Spring集成TCP客户端 - 客户端未收到多条消息。需要处理onMessage事件
问题描述:
那么,我有一个Spring集成的TCP客户端。我正尝试连接到远程TCP服务器,并从由服务器异步写入的套接字接收数据。Spring集成TCP客户端 - 客户端未收到多条消息。需要处理onMessage事件
但是,恰巧我的客户端正在接收第一条消息,并且不再接收来自服务器套接字的更多消息(实际上查看服务器日志可以使客户端已经失去连接,但是为什么?)
而且,还有一件事是我收到消息的那一刻如何触发某些功能? - 可能是TcpConnectionHandler-handleMessage()或TcpLisetner - onMessage()。最终,我希望有一个Spring TCP客户端,它连接到远程服务器并接收数据,因为它来到套接字上。下面是我的配置和代码:
我的配置:
<bean id="javaSerializer" class="com.my.client.CustomSerializerDeserializer" />
<bean id="javaDeserializer" class="com.my.client.CustomSerializerDeserializer" />
<context:property-placeholder />
<!-- Client side -->
<int:gateway id="gw" service-interface="com.zebra.client.SimpleGateway" default-request-channel="input" default-reply-channel="replies" />
<int-ip:tcp-connection-factory id="client"
type="client" host="localhost" port="5678" single-use="false"
so-timeout="100000" serializer="javaSerializer" deserializer="javaDeserializer"
so-keep-alive="true" />
<int:channel id="input" />
<int:channel id="replies">
<int:queue />
</int:channel>
<int-ip:tcp-outbound-channel-adapter
id="outboundClient" channel="input" connection-factory="client" />
<int-ip:tcp-inbound-channel-adapter
id="inboundClient" channel="replies" connection-factory="client"
client-mode="true" auto-startup="true" />
我TCP服务器:
while(true)
{
try
{
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to "
+ server.getRemoteSocketAddress());
DataOutputStream out =
new DataOutputStream(server.getOutputStream());
out.write("ACK\r\n".getBytes());
out.flush();
//server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
服务器日志:
等待客户端上的端口5678 ... 刚连接到/127.0.0.1:56108 在端口5678上等待客户端...
我的TcpClient:
final GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.load("classpath:config.xml");
context.registerShutdownHook();
context.refresh();
final SimpleGateway gateway = context.getBean(SimpleGateway.class);
int i=0;
while(i++<10){
String h = gateway.receive();
System.out.println("Received message "+h);
}try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我的客户端日志:
收到的报文ACK
收到的报文 收到的报文 收到的报文 收到的报文 收到的报文 收到的报文 收到的报文 收到的报文 收到消息
我的自定义解串器:
@Override
public String deserialize(InputStream inputStream) throws IOException {
// TODO Auto-generated method stub
StringBuilder builder = new StringBuilder();
int size = inputStream.available();
int c;
for (int i = 0; i < size; ++i) {
c = inputStream.read();
if(c!=-1){
builder.append((char)c);
}
else{
break;
}
}
return builder.toString();
}
我的网关:
public interface SimpleGateway {
public String receive();
}
请让我知道如果您有更多问题。
答
您的服务器只发送一条消息,然后接受新的连接。
编辑
我触发某些功能的那一刻我收到消息?
我真的不明白问题的一部分 - 您目前有input
通道连接到出站通道适配器,它只是将其重新写回。
你可以做这样的事情......
<int:object-to-string-transformer input-channel="input" output-channel="next" />
<int:service-activator input-channel="next" method="foo">
<bean class='foo.Foo" />
</int:service-activator>
public class Foo {
public void foo(String payload) {
...
}
}
如果你想处理byte[]
可以省略变压器和使用foo(byte[] bytes)
。
是啊!这是如此明显。无法指出它。谢谢加里。问题的另一个部分是,如果我的客户端可以收到有关写入套接字的数据的通知,以便我可以将我的功能放在那里,以处理我的消息。 –
请参阅我的编辑示例。 –
好的,我从您的编辑中了解到,我将这条消息写入'foo()'。但我期待的是,当数据写入套接字时,应该通知客户端。换句话说,我不希望我的客户端轮询传入的数据,但会在数据写入套接字时收到通知。 –