【问题标题】:Spring Integration and TCP server socket - how can I send a message to a client?Spring 集成和 TCP 服务器套接字 - 我如何向客户端发送消息?
【发布时间】:2014-09-25 22:45:23
【问题描述】:

我正在尝试在 Spring 中创建一个服务器,该服务器正在侦听 TCP 端口并接受连接。 我知道如何将传入请求路由到我的服务,并且它可以响应这些请求。 但是,我想在没有收到任何请求的情况下向某些客户发送消息。例如,有时我必须通知客户它收到了一条消息。

为此,我认为我需要一种方法来识别客户,例如通过让他们登录。有没有办法让每个活动连接都有一个“会话”对象,我可以在其中存储登录数据?

如何向使用用户名 X 登录的客户端发送消息?

这可能在 Spring 中实现吗?

【问题讨论】:

    标签: java spring sockets tcp spring-integration


    【解决方案1】:

    从 3.0 版开始;现在的框架emits connection events when there are connection state changes。您可以使用ApplicationListener<event:inbound-channel-adapter/> 捕获这些事件。

    TcpConnectionOpenEvent 包含一个connectionId;一旦知道它的 ID,您就可以向任何连接发送任意消息,方法是在消息中填充 IpHeaders.connectionId 标头 (ip_connectionId) 并将其发送到 <tcp:outbound-channel-adapter/>

    如果您需要支持请求/回复以及发送任意消息,则需要使用一对协作的通道适配器进行所有通信,而不是网关。

    编辑

    这是一个简单的启动应用程序...

    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(String[] 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()));
            String 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<TcpConnectionOpenEvent> listener() {
            return new ApplicationListener<TcpConnectionOpenEvent>() {
    
                @Override
                public void onApplicationEvent(TcpConnectionOpenEvent event) {
                    outputChannel().send(MessageBuilder.withPayload("foo")
                            .setHeader(IpHeaders.CONNECTION_ID, event.getConnectionId())
                            .build());
                }
    
            };
        }
    
    }
    

    pom 部门:

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-ip</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    

    【讨论】:

      猜你喜欢
      • 2017-05-03
      • 1970-01-01
      • 2013-04-01
      • 2016-08-31
      • 1970-01-01
      • 2013-04-29
      • 2019-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多