是否有任何spring集成tcp-inbound-channel-adapter示例?

时间:2014-10-28 21:50:35

标签: spring sockets tcp client integration

有没有人知道使用Spring的tcp-inbound-channel-adapter CLIENT示例的简单示例?我想创建一个简单的TCP客户端,它将一个短字符串发送到服务器,并只收到一个字节作为答案,然后关闭套接字。这是我的bean定义:

<int-ip:tcp-connection-factory id="client2" type="client"
    host="localhost" port="${availableServerSocket}" single-use="true"
    so-timeout="10000" deserializer="climaxDeserializer"
    so-keep-alive="false" />

<int:service-activator input-channel="clientBytes2StringChannel"
    method="valaszjott" ref="echoService">
</int:service-activator>

<int:gateway
    service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
    id="gw2" default-request-channel="gwchannel">
</int:gateway>
<int:channel id="gwchannel"></int:channel>
<int:object-to-string-transformer input-channel="gwchannel"
    id="clientbyte2string" output-channel="outputchannel">
</int:object-to-string-transformer>
<int:channel id="outputchannel"></int:channel>
<int-ip:tcp-outbound-channel-adapter channel="outputchannel"
    id="clientoutboundadapter" connection-factory="client2">
</int-ip:tcp-outbound-channel-adapter>
<int-ip:tcp-inbound-channel-adapter id="clientinboundadapter"
    channel="inputchannel" connection-factory="client2" />
<int:channel id="inputchannel"></int:channel>
<int:service-activator ref="echoService" method="valaszjott"
    input-channel="inputchannel" id="sa2">
</int:service-activator>

所以,我从主方法这样使用它:

....
SimpleGateway gateway = (SimpleGateway) context.getBean("gw2");
String result = gateway.send("foo");
....

然后客户端将"foo" + /r/n发送到服务器。在服务器端,我收到此消息,服务器只向客户端回复一个字节,( 06H )没有/r/n。客户端收到它,deserialiser找到它。这是我的deserialiser类:

@Component("climaxDeserializer")public class ClimaxDeserializer implements
Deserializer<Integer>{
    public Integer deserialize(InputStream arg0) throws IOException {
        int ertek;
        do{
            ertek = arg0.read();
            if ( ertek == 6){
                System.out.println("We have the ack byte !");
                return 1;
            }
        } while( ertek >= 0);
        return null;
    }
}

deserialiser找到ack字节,该方法返回一个整数,该值为1。 服务激活器指向此方法:

public String valaszjott ( int success){
        System.out.println("Answer: " + success);
        if ( success == 1){
            return "OK";
        } else {
            return "NOK";
        }
    }

此时一切正常,valaszjott方法打印出Answer: 1。但是结果参数(在main方法中)永远不会得到OKNOK字符串值,套接字将保持打开状态。

我在哪里弄错了?如果我将tcp-inbound-channel-adaptertcp-outbound-channel-adapter对更改为tcp-outbound-gateway,则可以正常使用...

1 个答案:

答案 0 :(得分:1)

你的错误存在于multi-threading

<int:gateway>调用存在于一个Thread中,但<int-ip:tcp-inbound-channel-adapter>是一个message-driven组件,它是自己的Thread内的套接字的监听器。对于最后一个,无论如何调用你的网关并不重要:服务器端总是可以将数据包发送到该套接字,你的适配器将接收它们。

对于ack用例,<tcp-outbound-gateway>是最佳解决方案,因为您在请求和回复之间确实有correlation。并且通过多个并发请求获得收益。

只需使用<tcp-outbound-channel-adapter><tcp-inbound-channel-adapter>,就无法保证将以与发送请求相同的顺序从服务器返回回复。

无论如何,在您当前的解决方案中,gateway只是不知道回复,而最后一个无法从请求邮件标题中传递到replyChannel

从其他方面插座不会被关闭,因为它们在cached中为<int-ip:tcp-connection-factory>

HTH