读取TCP流消息

时间:2017-07-16 09:19:06

标签: spring-integration

我很难写一个只使用spring-integration接收TCP流消息的服务。我正在使用这个类发送测试消息:

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

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

服务器代码,应收到消息:

@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

当我使用 telnet 发送消息或使用简单的仅使用java的tcp-server实现时,我能够收到消息。如何配置spring-integration以便能够读取客户端发送的消息?

1 个答案:

答案 0 :(得分:1)

默认的反序列化器期望消息以CRLF终止(这是Telnet发送的,以及为什么会这样做。)

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

或者,更改反序列化器以使用ByteArrayRawDeserializer使用套接字关闭来终止消息。

请参阅the documentation about (de)serializers here

  

TCP是一种流媒体协议;这意味着必须为通过TCP传输的数据提供一些结构,因此接收器可以将数据划分为离散消息。连接工厂配置为使用(反)序列化器在消息有效负载和通过TCP发送的位之间进行转换。这是通过分别为入站和出站消息提供解串器和串行器来实现的。提供了许多标准(de)序列化器。

     

ByteArrayCrlfSerializer*,将字节数组转换为字节流,然后是回车符和换行符(\r\n)。这是默认(de)序列化程序,可以与telnet一起用作客户端,例如。

     

...

     

ByteArrayRawSerializer*,将字节数组转换为字节流,不添加额外的消息分界数据;使用此(de)序列化程序,客户端以有序的方式关闭套接字来指示消息的结尾。使用此序列化程序时,消息接收将挂起,直到客户端关闭套接字或发生超时;超时不会导致消息。