2016-05-17 84 views
0

那麼,我有一個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(); 

} 

請讓我知道如果您有更多問題。

回答

1

您的服務器只發送一條消息,然後接受新的連接。

編輯

我觸發某些功能的那一刻我收到消息?

我真的不明白問題的一部分 - 您目前有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()'。但我期待的是,當數據寫入套接字時,應該通知客戶端。換句話說,我不希望我的客戶端輪詢傳入的數據,但會在數據寫入套接字時收到通知。 –