Spring集成TCP客户端 - 客户端未收到多条消息。需要处理onMessage事件

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)

+0

是啊!这是如此明显。无法指出它。谢谢加里。问题的另一个部分是,如果我的客户端可以收到有关写入套接字的数据的通知,以便我可以将我的功能放在那里,以处理我的消息。 –

+0

请参阅我的编辑示例。 –

+0

好的,我从您的编辑中了解到,我将这条消息写入'foo()'。但我期待的是,当数据写入套接字时,应该通知客户端。换句话说,我不希望我的客户端轮询传入的数据,但会在数据写入套接字时收到通知。 –