You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Integration TCP双连接轮询客户端无法接收服务器消息求助

问题排查:Spring Integration TCP客户端无法接收服务器响应

你需要向双IP/端口的TCP服务器轮询发送消息(长连接),已实现发送但无法接收响应,核心问题出在序列化器不匹配、入站适配器模式错误和连接工厂配置不合理三个方面,具体排查和修正如下:

1. 长度头序列化器不匹配服务器格式

当前使用的ByteArrayLengthHeaderSerializer默认采用二进制长度编码,但服务器要求的是4字节ASCII字符串格式的长度头(例如"0128"标识消息体长度为128字节),这种不匹配会导致客户端无法解析服务器返回的消息,表现为收不到数据。

修正代码:

private ByteArrayLengthHeaderSerializer codec() {
    ByteArrayLengthHeaderSerializer serializer = new ByteArrayLengthHeaderSerializer();
    serializer.setMaxMessageSize(8 * 1024);
    serializer.setInclusive(false);
    // 启用ASCII格式长度头,指定头部长度为4字节
    serializer.setAscii(true);
    serializer.setHeaderLength(4);
    return serializer;
}

2. 入站适配器未启用客户端模式

TcpReceivingChannelAdapter默认工作在服务器模式(监听本地端口等待连接),但你的场景是作为客户端复用已建立的长连接接收响应,必须启用客户端模式,否则适配器不会关联发送handler创建的客户端连接,无法接收服务器返回的数据。

修正代码:
在两个入站适配器配置中添加setClientMode(true):

@Bean
public MessageProducer tcpInboundChannelOne() {
    TcpReceivingChannelAdapter inboundChannelAdapter = new TcpReceivingChannelAdapter();
    inboundChannelAdapter.setConnectionFactory(failoverClientConnectionFactoryOne());
    inboundChannelAdapter.setOutputChannel(inboundChannel());
    // 启用客户端模式,复用客户端连接接收消息
    inboundChannelAdapter.setClientMode(true);
    return inboundChannelAdapter;
}

@Bean
public MessageProducer tcpInboundChannelTwo() {
    TcpReceivingChannelAdapter inboundChannelAdapter = new TcpReceivingChannelAdapter();
    inboundChannelAdapter.setConnectionFactory(failoverClientConnectionFactoryTwo());
    inboundChannelAdapter.setOutputChannel(inboundChannel());
    inboundChannelAdapter.setClientMode(true);
    return inboundChannelAdapter;
}

3. 连接工厂配置冗余不符合轮询需求

你当前配置的两个FailoverClientConnectionFactory核心是故障转移(连接失败时切换),而非轮询分发。重复的配置可能导致连接资源冲突,且难以保证发送/接收复用同一个长连接。

如果你的核心需求是轮询两个固定TCP连接,推荐使用RoundRobinClientConnectionFactory简化配置,同时确保发送和接收复用同一连接:

优化后的配置示例:

// 轮询连接工厂
@Bean
public RoundRobinClientConnectionFactory roundRobinCF() {
    List<AbstractClientConnectionFactory> factories = new ArrayList<>();
    factories.add(tcpNetClientConnectionFactoryOne());
    factories.add(tcpNetClientConnectionFactoryTwo());
    RoundRobinClientConnectionFactory cf = new RoundRobinClientConnectionFactory(factories);
    cf.setLeaveOpen(true);
    cf.setSingleUse(false);
    cf.setSoKeepAlive(true);
    return cf;
}

// 单个发送handler实现轮询
@Bean
@ServiceActivator(inputChannel = "outboundChannel")
public MessageHandler tcpOutboundHandler() {
    TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
    handler.setConnectionFactory(roundRobinCF());
    handler.setClientMode(true);
    return handler;
}

// 单个入站适配器复用轮询连接工厂
@Bean
public MessageProducer tcpInboundAdapter() {
    TcpReceivingChannelAdapter inboundChannelAdapter = new TcpReceivingChannelAdapter();
    inboundChannelAdapter.setConnectionFactory(roundRobinCF());
    inboundChannelAdapter.setOutputChannel(inboundChannel());
    inboundChannelAdapter.setClientMode(true);
    return inboundChannelAdapter;
}

内容的提问来源于stack exchange,提问作者ShadowStorm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 15:54:57