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

Spring Integration Java DSL动态TCP Server向客户端发消息问题

解决Spring Integration TCP Server模式错误及多端口动态集成流实现

首先,咱们先搞清楚你遇到的错误根源:你之前的代码里把Tcp.outboundAdapter和Tcp.netServer搭配使用了,这是完全错误的角色组合!

Tcp.netServer是TCP服务端连接工厂,它需要绑定一个入站端点来监听客户端的连接请求;而Tcp.outboundAdapter是为TCP客户端设计的,用来主动发起连接并发送数据。把服务端工厂塞给客户端适配器,自然会出现No listener bound to server connection factory的错误——服务端工厂根本没找到能处理连接的监听器,只能退出。

接下来给你一套正确的实现方案,满足你多端口、多队列对应独立集成流的需求:

核心思路

每个端口(比如1111对应queue1,2222对应queue2)需要一套独立的组件链:

  1. 一个TcpNetServerConnectionFactory:监听指定端口,管理客户端连接
  2. 一个TcpSendingMessageHandler:负责把JMS队列的消息发送到已连接的客户端
  3. 一条集成流:JMS入站适配器 → 通道 → TCP发送处理器

修正后的动态创建代码示例

假设你有一个包含端口、队列名、连接ID的HostConnection列表,循环创建每条集成流:

// 遍历所有需要创建的连接配置
for (HostConnection hostConnection : hostConnections) {
    int port = hostConnection.getPort();
    String queueName = hostConnection.getQueueName();
    String connectionId = hostConnection.getConnectionNumber();

    // 1. 创建TCP服务端连接工厂,监听指定端口
    TcpNetServerConnectionFactory serverFactory = Tcp.netServer(port)
            .serializer(customSerializer)
            .deserializer(customSerializer)
            .id(connectionId + "-tcp-server-factory")
            .soTimeout(10000)
            .get();

    // 2. 创建TCP消息发送处理器,绑定服务端工厂
    TcpSendingMessageHandler tcpSender = new TcpSendingMessageHandler();
    tcpSender.setConnectionFactory(serverFactory);
    tcpSender.setId(connectionId + "-tcp-sender");

    // 3. 构建集成流:从指定JMS队列取消息,发送到TCP客户端
    IntegrationFlow flow = IntegrationFlows
            .from(Jms.inboundAdapter(connectionFactory())
                    .destination(queueName)
                    .id(connectionId + "-jms-inbound-adapter"))
            .channel(MessageChannels.direct(connectionId + "-jms-to-tcp-channel"))
            .handle(tcpSender)
            .get();

    // 4. 注册并启动这条集成流
    FlowRegistration flowRegistration = this.flowContext.registration(flow)
            .id(connectionId + "-integration-flow")
            .register();

    // 确保服务端工厂启动(如果上下文未自动触发)
    serverFactory.start();
}

关键注意事项

  • 唯一ID标识:所有组件(连接工厂、适配器、通道、流)的ID都要带上connectionId前缀,避免多流之间的ID冲突
  • 连接管理:TcpSendingMessageHandler会自动管理服务端的客户端连接,当外部VB应用连接上来后,后续JMS队列的消息会自动发送到该连接
  • 单端口单客户端:如果你的场景是每个端口只对应一个外部应用,这个方案完全适用;如果需要支持多客户端连接同一端口,可以额外配置TcpConnectionRouter来实现消息路由

验证步骤

  1. 启动Spring Boot应用后,用netstat -ano(Windows)或ss -tulpn(Linux)检查1111、2222端口是否被监听
  2. 启动VB客户端连接对应端口,然后向queue1/queue2发送测试消息
  3. 查看日志,确认没有No listener bound错误,并且能看到类似New connection from /xxx.xxx.xxx.xxx:xxxx to port xxxx的连接成功日志

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:20:22