没有 Transformer 的 Spring TCP 客户端

2023-12-19

我跟着this https://github.com/spring-projects/spring-integration-samples/tree/master/basic/tcp-client-server在 Spring 中设置 TCP 客户端的示例。下面是我的tcpClientServerDemo-context.xml变压器所在的文件。有人可以帮我移除变压器并按原样发送数据而不进行任何修改吗?如果我尝试删除该行reply-channel='clientBytes2StringChannel'或者甚至将其设为空,我在构建项目时会遇到异常。

<?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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
        http://www.springframework.org/schema/integration/ip http://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd">

    <context:property-placeholder />

    <!-- Client side -->

    <int:gateway id="gw"
                 service-interface="hello.SimpleGateway"
                 default-request-channel="input"/>

    <int-ip:tcp-connection-factory id="client"
                                   type="client"
                                   host="192.86.33.61"
                                   serializer="CustomSerializerDeserializer"
                                   deserializer="CustomSerializerDeserializer"
                                   port="${availableServerSocket}"
                                   single-use="true"
                                   so-timeout="10000"/>

    <bean id="CustomSerializerDeserializer" class="hello.CustomSerializerDeserializer" />

    <int:channel id="input" />

    <int-ip:tcp-outbound-gateway id="outGateway"
                                 request-channel="input"
                                 connection-factory="client"
                                 request-timeout="10000"
                                 reply-timeout="10000"/>

    <!-- Server side -->
    <!-- When creating the socket factory on the server side, we specify both the serializer and deserializer
    which deals with both accepting a stream formatted with the Stx-Etx bytes as well as sending a stream
    formatted with the Stx-Etx bytes. -->
    <int-ip:tcp-connection-factory id="serverConnectionFactory"
                                   type="server"
                                   port="${availableServerSocket}"
                                   single-use="true"
                                   so-linger="10000"
                                   serializer="Custom1SerializerDeserializer"
                                   deserializer="Custom1SerializerDeserializer"/>


    <bean id="Custom1SerializerDeserializer" class="hello.CustomSerializerDeserializer1" />

    <int-ip:tcp-inbound-gateway id="gatewayCrLf"
                                connection-factory="serverConnectionFactory"
                                request-channel="incomingServerChannel"
                                error-channel="errorChannel"/>

    <!-- We leave a message listener off of this channel on purpose because we hook
    one up before the test actually runs (see the unit test associated with this
    context file) -->
    <int:channel id="incomingServerChannel" />

</beans>

EDIT:

现在我可以使用自定义序列化器/反序列化器发送消息。但不幸的是,我无法收到回复。这是我的序列化器/反序列化器:

public class CustomSerializerDeserializer implements Serializer<String>, Deserializer<String> {
protected final Log logger = LogFactory.getLog(this.getClass());

public void serialize(String input, OutputStream outputStream) throws IOException {
    logger.info("inside serialize");
    outputStream.write(buildSampleMsg(input));
    outputStream.flush();
}

public String deserialize(InputStream inputStream) throws IOException {
    logger.info("inside deserialize");
    final int bufferSize = 1024;
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    Reader in = new InputStreamReader(inputStream, "UTF-8");
    for (;;) {
        int rsz = in.read(buffer, 0, buffer.length);
        if (rsz < 0) {
            break;
        }
        out.append(buffer, 0, rsz);
    }
    logger.info(out.toString());
    return out.toString();
}

public byte[] buildSampleMsg(String body){
    logger.info("inside buildsamplemsg");
    ......
    return hexStringToByteArray(data);
}

我在序列化器/反序列化器的第一行完成了一些日志记录,但从未打印日志。这反过来意味着我们没有得到任何回应。任何帮助将不胜感激。


删除回复通道是正确的。您没有给出任何错误指示,但网关接口方法返回类型必须更改为 byte[]。

EDIT

如果主机出现垃圾,显然你做错了什么。您应该在将“ABCD”转换为byte[] (with getBytes());如果字符串中有 EBCDIC 字符,那将不起作用。另外,请记住默认序列化器会将 CRLF (ascii) 添加到输出中。如果该主机可以从数据本身确定消息的结尾,则可以使用ByteArrayRawSerializer in the serializer属性。但是,您将需要定制deserializer因为框架不知道如何从流中构造消息;除非主机在发送回复后关闭套接字,在这种情况下ByteArrayRawSerializer将作为deserializer属性。

用于与大型机(和其他)通信的常用技术是使用 1、2 或 4 字节长度标头(网络字节顺序)。这ByteArrayLengthHeaderSerializer就是这么做的。

如果大型机需要 EBCDIC 分隔符,您将需要一个自定义序列化器/解串器 - 在那里进行 EBCDIC 转换,将其与应用程序逻辑分开可能更有意义。

您可以阅读有关序列化器/反序列化器的信息here http://docs.spring.io/spring-integration/reference/html/ip.html#connection-factories.

TCP是一种流式传输协议;这意味着必须为通过 TCP 传输的数据提供某种结构,以便接收者可以将数据划分为离散的消息。连接工厂配置为使用(反)序列化器在消息有效负载和通过 TCP 发送的位之间进行转换。这是通过分别为入站和出站消息提供解串器和序列化器来实现的。提供了许多标准(反)序列化器。

The ByteArrayCrlfSerializer,将字节数组转换为字节流,后跟回车符和换行符(\r\n)。这是默认的(反)序列化器,可以作为客户端与 telnet 一起使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

没有 Transformer 的 Spring TCP 客户端 的相关文章

随机推荐