2017-07-16 2 views
1

私は春の統合を使用してTCPストリームメッセージを受信するサービスを作成していません。TCPストリームメッセージを読む

class TCPClient { 
    public static void main(String args[]) throws Exception { 
     Socket clientSocket = new Socket("localhost", 9999); 

     clientSocket.getOutputStream().write("XYZ".getBytes()); 
     clientSocket.close(); 
    } 
} 

Serverコード、メッセージを受信する必要があります:私は、テストメッセージを送信するには、このクラスを使用してい

@EnableIntegration 
@IntegrationComponentScan 
@Configuration 
public class TcpServer { 

    @Bean 
    public AbstractServerConnectionFactory serverCF() { 
     return new TcpNetServerConnectionFactory(9999); 
    } 

    @Bean 
    public TcpInboundGateway tcpInGate(AbstractServerConnectionFactory conFactory) { 
     TcpInboundGateway inGate = new TcpInboundGateway(); 
     inGate.setConnectionFactory(conFactory); 

     SubscribableChannel channel = new DirectChannel(); 

     //Planning to set custom message handler here, to process messages later 
     channel.subscribe(message -> System.out.println(convertMessage(message))); 

     inGate.setRequestChannel(channel); 
     return inGate; 
    } 

    private String convertMessage(Message<?> message) { 
     return message == null || message.getPayload() == null 
     ? null 
     : new String((byte[]) message.getPayload()); 
    } 
} 

問題:は、クライアントコードが実行されると - サーバーが次の例外をログに記録します。

TcpNetConnection : Read exception localhost:46924:9999:6d00ac25-b5c8-47ac-9bdd-edb6bc09fe55 IOException:Socket closed during message assembly 

Aは私がのtelnetを使用して、それを送信するメッセージを受信することができていますか私は、Siを使用する場合mple java-only tcp-serverの実装です。クライアントから送信されたメッセージを読み込めるようにSpring Integrationを構成するにはどうすればよいですか?

答えて

1

デフォルトのデシリアライザでは、メッセージがCRLF(Telnetが送信するものと、それが動作する理由)で終了することが必要です。

送信"XYZ\r\n".getBytes()

または、デシリアライザを変更して、ソケットクローズを使用してメッセージを終了するByteArrayRawDeserializerを使用します。

the documentation about (de)serializers hereを参照してください。

TCPはストリーミングプロトコルです。これは、TCPを介して転送されるデータにいくつかの構造を提供する必要があるため、受信者がデータを個別のメッセージに区切ることができることを意味します。接続ファクトリは、シリアライザを使用してメッセージペイロードとTCP経由で送信されるビットとの間で変換するように構成されています。これは、それぞれインバウンドおよびアウトバウンドメッセージ用のデシリアライザおよびシリアライザを提供することによって達成されます。いくつかの標準(デ)シリアライザが用意されています。

ByteArrayCrlfSerializer*は、バイト配列を、キャリッジリターンと改行文字(\r\n)に続くバイトストリームに変換します。これはデフォルトの(シリアライザ)シリアライザであり、たとえばクライアントとしてtelnetで使用できます。

...

ByteArrayRawSerializer*は、バイトのストリームにバイト配列を変換し、追加のメッセージ境界データを付加しません。この(シ)シリアライザでは、メッセージの終わりはクライアントが順番にソケットを閉じることで示されます。このシリアライザを使用すると、クライアントがソケットを閉じるかタイムアウトが発生するまで、メッセージの受信はハングします。タイムアウトではメッセージが表示されません。