[JAVA] So greifen Sie mit der TCP-Funktion von Spring Integration direkt auf Socket zu

Beim Erstellen eines TCP-Clients mit der TCP-Funktion von Spring Integration gab es (manchmal) Fälle, in denen ich direkten Kontakt mit Socket herstellen wollte. Notieren Sie sich daher, wie Sie direkten Kontakt mit Socket herstellen können.

Der Fall, in dem ich Socket direkt berühren wollte, ist ... FIN für normale Trennung und RST für abnormale Trennung (wenn ein Fehler auftritt)! Es war eine Zeit, in der es notwendig war, die Verbindungsanforderungen zu erfüllen. In der TCP-Funktion von Spring Integration kann angegeben werden, ob FIN oder RST als Trennmethode in der Einstellung von Connection Factory verwendet werden soll, es war jedoch nicht möglich, abhängig von den Bedingungen (in dem untersuchten Bereich ...) zu wechseln. ..

Verwendung von TcpSocketSupport

Spring Integration [TcpSocketSupport](https: // docs.) Zur Unterstützung der Anwendung einer beliebigen Verarbeitung auf Sockets, die auf der Framework-Seite generiert wurden (Sockets, die SocketChannels im Fall von NIO zugeordnet sind). spring.io/spring-integration/docs/5.1.2.RELEASE/reference/htmlsingle/#_the_literal_tcpsocketsupport_literal_strategy_interface) wird bereitgestellt. Standardmäßig wird die Klasse "DefaultTcpSocketSupport" angewendet, aber der Prozess, der den Status von Socket ändert, wird nicht ausgeführt.

Anwenden einer Implementierung, die RSTs, wenn eine Ausnahme auftritt

Die TCP-Funktion von Spring Integration unterstützt einen Mechanismus zur Behandlung von Ereignissen (Verbindung, Trennung, Fehlererkennung usw.), die bei der Verarbeitung in Spring Integration auftreten, und der diesmal eingeführte Code behandelt diese Ereignisse. Ich habe versucht, den Code zu trennen, nachdem eine Ausnahme mit RST festgestellt wurde. Es ist zu beachten, dass der hier eingeführte Code nicht der Code ist, der auf die tatsächliche Anwendung angewendet wird (oder geplant ist), sodass er nicht so verwendet werden kann, wie er ist. (Es ist nur eine Probe)

package com.example.demo;

import java.net.Socket;
import java.net.SocketException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.dsl.Transformers;
import org.springframework.integration.ip.dsl.Tcp;
import org.springframework.integration.ip.tcp.connection.*;
import org.springframework.integration.ip.tcp.serializer.SoftEndOfStreamException;
import org.springframework.integration.ip.tcp.serializer.TcpCodecs;

@SpringBootApplication
public class SprIntDemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(SprIntDemoApplication.class, args);
  }

  // TCP Server
  @Bean
  public IntegrationFlow integrationInboundFlow() {
    return IntegrationFlows.from(Tcp.inboundGateway(Tcp.nioServer(5555)
        .serializer(TcpCodecs.crlf())
        .deserializer(TcpCodecs.crlf())
        .get()))
        .transform(Transformers.objectToString()) // byte[] -> String
        .transform(m -> m) //Beantworten Sie die empfangene Nachricht so wie sie ist
        .get();
  }

  // TCP Client
  @Bean
  public IntegrationFlow integrationOutboundFlow(ApplicationEventPublisher publisher) {
    AbstractClientConnectionFactory factory = Tcp.nioClient("localhost", 5555)
        .serializer(TcpCodecs.crlf())
        .deserializer(TcpCodecs.crlf())
        .tcpSocketSupport(socketManager()) //Wenden Sie die Supportklasse an, um den generierten Socket zu verwalten
        .get();
    factory.setApplicationEventPublisher(publisher);
    return flow -> flow.handle(Tcp.outboundGateway(factory))
        .transform(Transformers.objectToString());  // byte[] -> String
  }

  @Bean
  public SocketManager socketManager() {
    return new SocketManager();
  }

  @Bean
  public MessagingTemplate messagingTemplate() {
    return new MessagingTemplate();
  }

  static class SocketManager extends DefaultTcpSocketSupport {
    private final Map<Integer, Socket> sockets = new ConcurrentHashMap<>();

    @Override
    public void postProcessSocket(Socket socket) {
      super.postProcessSocket(socket);
      sockets.put(socket.getLocalPort(), socket); //Speichern Sie es intern, damit Sie auf Socket zugreifen können, wenn ein Fehler erkannt wird.
    }

    @EventListener
    public void handleTcpConnectionExceptionEvent(TcpConnectionExceptionEvent event) {
      try {
        int localPort = ((TcpConnection) event.getSource()).getSocketInfo().getLocalPort();
        Socket socket = sockets.get(localPort);
        if (!socket.isClosed() && !(event.getCause() instanceof SoftEndOfStreamException)) {
          sockets.get(localPort).setSoLinger(true, 0); //Auf RST einstellen
        }
      } catch (SocketException e) {
        // ignore
      }
    }

    @EventListener
    public void handleTcpConnectionCloseEvent(TcpConnectionCloseEvent event) {
      sockets.remove(((TcpConnection) event.getSource()).getSocketInfo().getLocalPort()); //Reinigen Sie Steckdosen, die nach dem Trennen nicht mehr benötigt werden
    }

  }

}
package com.example.demo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpIntDemoApplicationTests {

  @Autowired
  MessagingTemplate template;

  @Test
  public void contextLoads() {
    Message<?> reply = template.sendAndReceive("integrationOutboundFlow.input",
        MessageBuilder.withPayload("hello!").build());
    System.out.println("reply: " + reply);
  }

}

Übrigens ... Wenn Sie den obigen Code so ausführen, wie er ist, tritt während der Verarbeitung kein Fehler (Ausnahme) auf. Um einen Fehler zu generieren, müssen Sie den Socket während der Verarbeitung auf der Serverseite trennen, aber dieses Buch Ich werde diesen Teil im Eintrag weglassen.

Zusammenfassung

Wenn ich das Dokument lese, habe ich das Gefühl, dass ich es über die Rolle von "TcpSocketSupport" hinaus verwende, aber es war hilfreich, dass der Mechanismus, mit dem ich "Socket" berühren kann, unterstützt wurde.

Referenzdokument

Recommended Posts

So greifen Sie mit der TCP-Funktion von Spring Integration direkt auf Socket zu
So überprüfen Sie, bevor Sie mit Spring Integration eine Nachricht an den Server senden
Ich habe den Ablauf der TCP-Kommunikation mit Spring Integration (Client Edition) untersucht.
Ich habe den Ablauf der TCP-Kommunikation mit Spring Integration (Server Edition) untersucht.
So wenden Sie HandlerInterceptor auf das http-Inbound-Gateway von Spring Integration an
Greifen Sie mit jdbcTemplate auf das integrierte h2db des Spring Boot zu
Booten nach Umgebung mit Spring Boot of Maven
Implementieren wir eine Funktion, um die Anzahl der Zugriffe auf die API mit SpringBoot + Redis zu begrenzen
So fügen Sie die Löschfunktion hinzu
Verwendung von MinIO mit derselben Funktion wie S3 Verwenden Sie Docker-Compose
So erzielen Sie mit Rest Template of Spring einen großen Datei-Upload
So bestimmen Sie die Anzahl der Parallelen
So sortieren Sie eine Liste von SelectItems
So implementieren Sie TextInputLayout mit Validierungsfunktion
[Verarbeitung × Java] Verwendung der Funktion
So wenden Sie Thymeleaf-Änderungen sofort mit #Spring Boot + maven auf den Browser an
So dekorieren Sie CSS auf Rails6 form_with (Hilfs-) Optionsfeldern
[Spring Boot] Ich habe untersucht, wie die Nachbearbeitung der empfangenen Anforderung implementiert werden kann.
So lesen Sie Request Body mit Spring Boot + Spring Security mehrmals
So konvertieren Sie ein Array von Strings mit der Stream-API in ein Array von Objekten
Ich habe versucht, den Zugriff von Lambda → Athena mit AWS X-Ray zu visualisieren
[swift5] So ändern Sie die Farbe der TabBar oder die Farbe des TabBar-Elements mit Code
So implementieren Sie die E-Mail-Authentifizierungsfunktion zum Zeitpunkt der Benutzerregistrierung
So finden Sie die Ursache des Ruby-Fehlers
Drucken Sie Formulare mit Jasper Reports direkt auf dem Drucker
Passen Sie an, wie der Inhalt von Recyclerview aufgeteilt wird
Verwendung von MyBatis2 (iBatis) mit Spring Boot 1.4 (Spring 4)
[Rails6] So verbinden Sie die von Scaffold generierte Buchungsfunktion mit der von devise generierten Benutzerfunktion
Verwendung des eingebauten h2db mit Federstiefel
So überprüfen Sie die neueste Version von io.spring.platform für das Schreiben in pom.xml von Spring (STS)
Die Geschichte der Erhöhung der Spring Boot 1.5-Serie auf die 2.1-Serie
So implementieren Sie die Brotkrumenfunktion mit gretel
Versuchen Sie, die Anmeldefunktion mit Spring Boot zu implementieren
Wie komme ich zum heutigen Tag?
[Für Anfänger] So implementieren Sie die Löschfunktion
Ausgabe der Verwendung der Slice-Methode
Ressourcenhandler-Einstellungen bei der Bereitstellung von SPA mit der statischen Ressourcenfunktion von Spring Boot
So zeigen Sie das Ergebnis des Ausfüllens des Formulars an
So legen Sie Umgebungsvariablen in der Eigenschaftendatei der Spring-Boot-Anwendung fest
[Spring Boot] So verweisen Sie auf die Eigenschaftendatei
[Einführung in Spring Boot] Authentifizierungsfunktion mit Spring Security
So erstellen Sie einen Jenkins-Server mit einem Docker-Container unter CentOS 7 von VirtualBox und greifen von einem lokalen PC auf den Jenkins-Server zu
Wenn Sie SQLite mit VSCode verwenden, verwenden Sie die Erweiterung (wie die Binärdatei von sqlite3 angezeigt wird)
Verwendung von git mit der Leistung von jgit in einer Umgebung ohne git-Befehle
Anfordern durch Übergeben eines Arrays an eine Abfrage mit dem HTTP-Client von Ruby
[Docker] So sehen Sie den Inhalt von Volumes. Starten Sie einen Container mit Root-Rechten.
So legen Sie ein Wiederholungslimit für Sidekiq fest und benachrichtigen tote Warteschlangen mit Slack
[Grobe Erklärung] So trennen Sie den Betrieb der Produktionsumgebung und der Entwicklungsumgebung mit Rails
Zusammenfassung der Verwendung des im IE festgelegten Proxy-Sets bei der Verbindung mit Java
[Java] So erhalten Sie die URL der Übergangsquelle
So ändern Sie die Aktion mit mehreren Senden-Schaltflächen
So löschen / aktualisieren Sie das Listenfeld von OneToMany
Wie schreibe ich Scala aus der Perspektive von Java
[Java] So lassen Sie die Federkonstruktorinjektion mit Lombok weg
So erstellen Sie eine mit Ruby erstellte LINE-Messaging-Funktion