我在这里遇到动态TCP连接方法(Spring-IP Dynamic FTP Sample)的问题。收到消息后,我想获取收到的消息的TCP连接详细信息。通过这种方式,我可以跟踪发送该消息的发件人的应用程序。但在服务激活器中,我无法获得这个细节。
当我的TCP客户端连接到服务器时,还需要连接详细信息。这样,如果服务器想要启动通信,它将具有连接细节。
对于info,我的应用程序有多个TCP客户端和服务器。
答案 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”。