【问题标题】:Spring TCP Socket Integration Implementation not passing gateway.send methodSpring TCP Socket集成实现不通过gateway.send方法
【发布时间】:2017-09-12 18:22:55
【问题描述】:

所以我包装了 Spring Integration TCP 客户端来为我的应用程序提供 API。可以在herehere 找到有关此问题的先前问题。这样做的问题是 gateway.send() 根本没有结束,API 响应永远不会回来。

这是我的ServerConnection.java 文件:

package com.abc.xyz.serverconnection;
import org.springframework.context.support.GenericXmlApplicationContext;   
public class ServerConnections {    
    private SimpleGateway gateway;    
    public ServerConnections() {
        final GenericXmlApplicationContext context = setupContext();
        this.setGateway(context.getBean(SimpleGateway.class));
    }    
    public static GenericXmlApplicationContext setupContext() {
        final GenericXmlApplicationContext context = new GenericXmlApplicationContext();
        context.load("classpath:META-INF/spring/integration/tcpClientServerDemo-context.xml");
        context.registerShutdownHook();
        context.refresh();
        return context;
    }    
    public SimpleGateway getGateway() {
        return gateway;
    }    
    public void setGateway(SimpleGateway gateway) {
        this.gateway = gateway;
    }    
    public boolean sendData(String input) {
        this.gateway.send(input);
        return true;
    }    
    public void recieveData(String output) {
        System.out.println("Data from server:" + output);
    }    
}

在我的控制器中,我做了这样的事情:

@RequestMapping(value = "/logon", method = RequestMethod.GET)
@ResponseBody
public String logon() {
    // logics go here and the result is stored like below and sent
    String message = "0000005401F40000C1E3E304010000000020000000000000000000000000000000000000000000004040404040404040C1E3E300C1C2C3C4C5C6C7C8E8C5E2C8E6C1D540F1F7F24BF0F1F64BF0F0F34BF0F5F200";
    if (serverConnections.sendData(message)) {
        return "Data sent successfully!";
    } else {
        return "Data not sent!";
    }
}

这是我的配置的样子:

    <context:property-placeholder />
    <int:channel id="input" />
    <int:channel id="toSA" />
    <int:service-activator input-channel="toSA"
                           ref="echoService"
                           method="recieveData"/>
    <bean id="echoService" class="com.abc.xyz.serverconnection.ServerConnection" />
    <bean id="CustomSerializerDeserializer" class="com.abc.xyz.serverconnection.CustomSerializerDeserializer" />
    <int:object-to-string-transformer id="serverBytes2String"
                                      input-channel="serverBytes2StringChannel"
                                      output-channel="toSA"/>
    <int:gateway id="gw"
                 service-interface="com.abc.xyz.serverconnection.SimpleGateway"
                 default-request-channel="input"/>
    <int-ip:tcp-connection-factory id="client"
                                   type="client"
                                   host="<ip>"
                                   serializer="CustomSerializerDeserializer"
                                   deserializer="CustomSerializerDeserializer"
                                   port="6100"
                                   single-use="false" />
    <int-ip:tcp-outbound-gateway id="outGateway"
                                 request-channel="input"
                                 reply-channel="serverBytes2StringChannel"
                                 connection-factory="client" />

编辑:无法获取应用程序的调试日志,因为我将 TCP 客户端实现用作 Maven 项目中的 Maven 模块。另一个模块将其用作依赖项,这就是 REST API 端点所在的位置。

【问题讨论】:

    标签: sockets tcp spring-integration


    【解决方案1】:

    我觉得你的

     <int:service-activator input-channel="toSA"
                           ref="echoService"
                           method="recieveData"/>
    

    不返回任何要发送到replyChannel 标头的结果,同时您的gateway.send() 不是void 方法。这就是它等待永远不会回来的回复的方式。

    【讨论】:

    • TCP 出站网关将在 5 秒后超时,线程将坐在网关中等待永远不会到来的回复。将gw 上的default-reply-timeout 设置为5000 以匹配。如果您不想等待回复,请将方法更改为返回void 或将default-reply-timeout 设置为0。正如@artem 所说,您应该真正使用通道适配器进行仅发送操作。
    • @artem @gary 感谢您的意见。我已将网关更改为返回void。这行得通,但我想了解@artem 的观点。我的 EchoService 返回一个 voidgateway.send() 返回一个字符串。那么这是否意味着我需要在某些地方捕捉到gateway.send() 的回复?我不明白这一点。
    • EchoService 返回void 对我来说似乎是矛盾的:)(我知道你从样本中得到了这个名字)。返回非 void 的网关方法告诉框架需要回复;当线程返回到网关时,它会等待该回复。有一个超时,但默认情况下它是无限的。由于您从服务中返回 void,因此流程在该点结束,并且回复永远不会到达。返回void 的网关方法告诉框架永远不会有回复。对于请求/回复消息,通常最好在回复到达之前阻塞调用线程。
    • 网关的方法契约规定了下游流的行为。如果你有非void 返回类型,它会转向request/reply 场景;并在发送请求后等待回复。默认reply-timeout 是不确定的。这就是为什么您的通话被永久阻止的原因。在参考手册中查看更多信息:docs.spring.io/spring-integration/docs/4.3.11.RELEASE/reference/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多