Intégration de spring et socket serveur TCP – comment puis-je envoyer un message à un client?

J’essaie de créer un serveur Spring qui écoute sur un port TCP et accepte les connexions. Je sais comment router les demandes entrantes vers mon service, et il peut y répondre. Cependant, j’aimerais envoyer des messages à certains clients sans qu’aucune demande ne soit reçue. Par exemple, je dois parfois informer un client qu’il a reçu un message.

Pour ce faire, je pense avoir besoin d’un moyen d’identifier les clients, par exemple en les laissant se connecter. Existe-t-il un moyen d’avoir un object “session” pour chaque connexion active dans laquelle je puisse stocker les données de connexion?

Comment puis-je envoyer un message à un client qui s’est connecté avec le nom d’utilisateur X?

Est-ce possible au spring?

À partir de la version 3.0; les frameworks émettent maintenant des événements de connexion lorsqu’il y a des changements d’état de connexion . Vous pouvez capturer ces événements à l’aide d’un ApplicationListener ou d’un .

TcpConnectionOpenEvent contient un TcpConnectionOpenEvent connectionId ; vous pouvez envoyer des messages arbitraires à toute connexion une fois que vous connaissez son identifiant, en IpHeaders.connectionId tête IpHeaders.connectionId ( ip_connectionId ) dans un message et en l’envoyant à un .

Si vous devez prendre en charge demande / réponse et envoyer des messages arbitraires, vous devez utiliser une paire d’adaptateurs de canal qui collaborent pour toutes les communications, pas une passerelle.

MODIFIER

Voici une application de démarrage simple …

 package com.example; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.Socket; import javax.net.SocketFactory; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.dsl.IntegrationFlows; import org.springframework.integration.ip.IpHeaders; import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter; import org.springframework.integration.ip.tcp.TcpSendingMessageHandler; import org.springframework.integration.ip.tcp.connection.TcpConnectionOpenEvent; import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory; import org.springframework.integration.ip.tcp.connection.TcpServerConnectionFactory; import org.springframework.integration.support.MessageBuilder; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHandler; @SpringBootApplication public class So25102101Application { public static void main(Ssortingng[] args) throws Exception { ConfigurableApplicationContext context = new SpringApplicationBuilder(So25102101Application.class) .web(false) .run(args); int port = context.getBean(TcpServerConnectionFactory.class).getPort(); Socket socket = SocketFactory.getDefault().createSocket("localhost", port); BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); Ssortingng line = reader.readLine(); System.out.println(line); context.close(); } @Bean public TcpReceivingChannelAdapter server(TcpNetServerConnectionFactory cf) { TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter(); adapter.setConnectionFactory(cf); adapter.setOutputChannel(inputChannel()); return adapter; } @Bean public MessageChannel inputChannel() { return new QueueChannel(); } @Bean public MessageChannel outputChannel() { return new DirectChannel(); } @Bean public TcpNetServerConnectionFactory cf() { return new TcpNetServerConnectionFactory(0); } @Bean public IntegrationFlow outbound() { return IntegrationFlows.from(outputChannel()) .handle(sender()) .get(); } @Bean public MessageHandler sender() { TcpSendingMessageHandler tcpSendingMessageHandler = new TcpSendingMessageHandler(); tcpSendingMessageHandler.setConnectionFactory(cf()); return tcpSendingMessageHandler; } @Bean public ApplicationListener listener() { return new ApplicationListener() { @Override public void onApplicationEvent(TcpConnectionOpenEvent event) { outputChannel().send(MessageBuilder.withPayload("foo") .setHeader(IpHeaders.CONNECTION_ID, event.getConnectionId()) .build()); } }; } } 

pom deps:

   org.springframework.boot spring-boot-starter-integration   org.springframework.integration spring-integration-ip   org.springframework.boot spring-boot-starter-test test