Spring Integration TCP。获取已连接客户端的连接ID

时间:2016-08-21 09:45:40

标签: tcp spring-integration

我在这里遇到动态TCP连接方法(Spring-IP Dynamic FTP Sample)的问题。收到消息后,我想获取收到的消息的TCP连接详细信息。通过这种方式,我可以跟踪发送该消息的发件人的应用程序。但在服务激活器中,我无法获得这个细节。

当我的TCP客户端连接到服务器时,还需要连接详细信息。这样,如果服务器想要启动通信,它将具有连接细节。

对于info,我的应用程序有多个TCP客户端和服务器。

1 个答案:

答案 0 :(得分:5)

在Gary Russell先生的另一篇文章中得到了答复。

<强>答案

对于正常的请求/回复处理,使用入站网关,框架将负责将服务激活器回复路由到正确的套接字。它通过使用连接ID头来完成此操作。

如果您需要提供任意回复(例如,对邮件进行多次回复,则必须使用入站和出站通道适配器,并且您的应用程序负责设置连接ID标头。

有两种方法可以访问服务激活器调用的POJO中所需的标头:

public void foo(byte[] payload, @Header(IpHeaders.CONNECTION_ID) String connectionId) {
    ...
}

public void foo(Message<byte[]> message) {
    String connectionId = message.getHeaders().get(...);
}

然后,当您发送回复时,您需要以某种方式设置该标题。

修改

以下是我的实施

要获取所有连接的客户端,只需从上下文中获取ServerConnectionFactory并访问方法.getConnectedClients()。它返回每个连接客户端的列表connectionIds。

AbstractServerConnectionFactory connFactory = (AbstractServerConnectionFactory) appContext.getBean("server");
List<String> openConns = connFactory.getOpenConnectionIds();

如上所述,在Gary的回复中,使用此connectionId并在将消息发送到客户端时将其设置在连接头中。示例代码如下。

MessageChannel serverOutAdapter = null;
try{
    serverOutAdapter = (MessageChannel) appContext.getBean("toObAdapter");
}catch(Exception ex){
    LOGGER.error(ex.getMessage());
    throw ex;
}

    if(null == serverOutAdapter){
        throw new Exception("output channel not available");
    }

    AbstractServerConnectionFactory connFactory = (AbstractServerConnectionFactory) appContext.getBean("serverConnFactoryBeanId");
    List<String> openConns = connFactory.getOpenConnectionIds();
    if(null == openConns || openConns.size() == 0){

        throw new Exception("No Client connection registered");
    }

    for (String connId: openConns) {
        MessageBuilder<String> mb = MessageBuilder.withPayload(message).setHeader(IpHeaders.CONNECTION_ID, connId);
        serverOutAdapter.send(mb.build());
    }

注1 :如果您想从服务器发送消息,请务必以不超时的方式配置服务器和客户端连接工厂。即在客户端连接工厂中放置so-keep-alive = true。

注意2 :如果服务器必须与客户端通信,请确保客户端在加载上下文后立即连接到服务器。因为Spring-IP客户端连接工厂仅在发送第一条消息时才连接。为了在上下文加载后连接客户端,请在tcp客户端上下文中为“tcp-outbound-channel-adapter”添加 client-mode =“true”