【问题标题】:How do I set up a Spring TCP client and server model?如何设置 Spring TCP 客户端和服务器模型?
【发布时间】:2014-11-14 18:39:44
【问题描述】:

所以按照这个问题(how to plug a TCP-IP client server in a spring MVC application), 我成功地将网关连接到我的 Spring REST 控制器。但是,我对下一步去哪里感到困惑。这是我想要完成的任务:

1) 当某个路由被 POST 请求命中时,打开一个从 POST 传递过来的到某个 IP 的连接(或使用已经使用该 IP 打开的连接)并发送一条消息。

@RequestMethod(value = '/sendTcpMessage', method=RequestMethod.POST)
public void sendTcpMessage(@RequestParam(value="ipAddress", required=true) String ipAddress,
                           @RequestParam(value="message", required=true) String message) {

//send the message contained in the 'message' variable to the IP address located 
//at 'ipAddress' - how do I do this?

}

2) 我还需要我的 Spring 后端来监听传递给它的 TCP“消息”,并将它们存储在缓冲区中。我的 Javascript 将每 5 秒左右调用一次路由,并从缓冲区中读取信息。

这是我的控制器代码:

@Controller
public class HomeController {

    @Resource(name = "userDaoImpl")
    private UserDAO userDao;
    @Resource(name = "receiveTcp")
    private ReceiveTcp tcpMessageReceiver;
    @Autowired
    SimpleGateway gw;

    String tcpBuffer[] = new String[100];

    @RequestMapping(value="/")
    public String home() {
        return "homepage";
    }

    @RequestMapping(value = "/checkTcpBuffer", method=RequestMethod.POST)
    public String[] passTcpBuffer() {
        return tcpMessageReceiver.transferBuffer();
    }

}

根上下文.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-ip="http://www.springframework.org/schema/integration/ip"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/integration/ip http://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd
                        http://www.springframework.org/schema/integration/ http://www.springframework.org/schema/integration/spring-integration.xsd">

    <!-- Root Context: defines shared resources visible to all other web components -->
<int:gateway id="gw"
   service-interface="net.codejava.spring.interfaces.SimpleGateway"
   default-request-channel="input"/>

<bean id="javaSerializer"
      class="org.springframework.core.serializer.DefaultSerializer"/>
<bean id="javaDeserializer"
      class="org.springframework.core.serializer.DefaultDeserializer"/>

<int-ip:tcp-connection-factory id="server"
    type="server"
    port="8081"
    deserializer="javaDeserializer"
    serializer="javaSerializer"
    using-nio="true"
    single-use="true"/>

<int-ip:tcp-connection-factory id="client"
    type="client"
    host="localhost"
    port="8081"
    single-use="true"
    so-timeout="10000"
    deserializer="javaDeserializer"
    serializer="javaSerializer"/>

    <int:channel id="input" />

    <int:channel id="replies">
        <int:queue/>
    </int:channel>

    <int-ip:tcp-outbound-channel-adapter id="outboundClient"
    channel="input"
    connection-factory="client"/>

    <int-ip:tcp-inbound-channel-adapter id="inboundClient"
    channel="replies"
    connection-factory="client"/>

    <int-ip:tcp-inbound-channel-adapter id="inboundServer"
    channel="loop"
    connection-factory="server"/>

    <int-ip:tcp-outbound-channel-adapter id="outboundServer"
    channel="loop"
    connection-factory="server"/>

    <int:service-activator input-channel="input" ref="receiveTcp" method = "saveValue"/>

</beans>

ReceiveTcp.java

@Component(value = "receiveTcp")
public class ReceiveTcp {

    String buf[] = new String[100];
    int currentPosition = 0;

    @ServiceActivator
    public void saveValue(String value){
        System.out.println(value);
        buf[currentPosition] = value;
        currentPosition++;
    }

    public String[] transferBuffer() {
        String tempBuf[] = new String[100];
        tempBuf = buf;
        buf = new String[100];

        return tempBuf;
    }
}

我该如何解决这些问题?

【问题讨论】:

    标签: java spring spring-mvc tcp spring-integration


    【解决方案1】:

    您需要使用ResponseEntity。请参阅此answer。 tcp 连接是双向连接,因此如果您的方法返回响应而不是 void,它会自动将其发送回向您发出请求的 ip。您不必手动执行此操作。

    【讨论】:

      【解决方案2】:

      请参阅tcp-client-server sample。它使用 TCP 网关(请求/回复)。根据您的情况,您可能希望改用单向通道适配器。

      gateway(with void return) -> tcp-outbound-channel-adapter
      

      tcp-inbound-channel-adapter -> service-activator
      

      (服务激活器调用一个 POJO,它将入站消息保存在您的“缓冲区”中,可能由 connectionId 键入 - 从消息头中获取)。

      将服务激活器引用的网关和 POJO 注入您的控制器,以便您可以 (a) 发送消息和 (b) 清空“缓冲区”。

      您还可以收听TcpConnectionEvents,以便检测连接是否丢失。

      【讨论】:

      • 嗨@GaryRussell,再次感谢您的回答。我对 Spring 和使用 TCP 都很陌生,所以请原谅新手的错误并尽量对我耐心:)。我已经修改了我的问题并尝试实施您的指示 - 这看起来正确吗?另外,发送消息会像调用gw.send("message"); 一样简单吗?我浏览了一些文档,看到有人发送这样的信息。
      • 嗨,Gary,我有一个问题,关于我们是否必须从简单网关发送自定义 java 对象而不是字符串,比如 send(obj) 那么我们必须做什么。我尝试了您的示例,使用字符串它可以工作,但不会自定义 hava 对象。你能告诉我我需要做些什么改变吗?
      • 最好提出一个新问题,而不是对现有问题发表评论。您不能通过 TCP 发送任意 Java 对象。如果您的对象是Serializable,您可以使用DefaultSerializer - see the documentation。如果没有,您需要将对象转换为可传输的对象,例如 JSON。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 2012-01-25
      • 1970-01-01
      相关资源
      最近更新 更多