没有Transformer的Spring TCP客户端 [英] Spring TCP Client without Transformer

查看:157
本文介绍了没有Transformer的Spring TCP客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我跟着这个在Spring中设置TCP客户端的示例。下面是变换器所在的 tcpClientServerDemo-context.xml 文件。有人可以帮我拆除变压器并按原样发送数据而不做任何修改吗?如果我尝试删除行 reply-channel ='clientBytes2StringChannel'或甚至将其设为null,我在构建项目时会遇到异常。

I followed this example for setting up a TCP Client in Spring. Below is my tcpClientServerDemo-context.xml file where the transformer lies. Can someone help me remove the transformer and send the data as it is without any modifications? If I try to remove the line reply-channel='clientBytes2StringChannel' or even make it null, I get exceptions when building the project.

<?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>

编辑:

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

Now I am able to send the messages using a custom serializer/deserializer. But unfortunately, I am unable to receive the responses. Here is my serializer/deserializer:

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);
}

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

I have some logging done on the first line of the serializer/deserializer but the log is never printed. Which in turn means, we don't get any response. Any help will be appreciated.

推荐答案

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

Removing the reply-channel is correct. You don't give any indication of the error, but the gateway interface method return type must be changed to byte[].

编辑

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

Clearly you are doing something wrong if the mainframe is getting junk. You should do the EBCDIC conversion after you convert your "ABCD" to a byte[] (with getBytes()); if you have EBCDIC chars in a String, that won't work. Also, bear in mind the default serializer will add CRLF (ascii) to the output. If that mainframe can determine the end of message from the data itself, you can use a ByteArrayRawSerializer in the serializer attribute. However, you will need a custom deserializer because the framework won't know how to construct a message from the stream; unless the mainframe closes the socket after sending the reply, in which case a ByteArrayRawSerializer will work as the deserializer attribute.

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

A common technique used to communicate with mainframes (and others) is to use a 1, 2, or 4 byte length header (network byte order). The ByteArrayLengthHeaderSerializer does just that.

如果大型机期待EBCDIC分隔符,则需要自定义序列化程序/反序列化器 - 在那里进行EBCDIC转换可能更有意义,将它与应用程序逻辑分开。

If the mainframe is expecting EBCDIC delimiters, you'll need a custom serializer/deserializer - it might make more sense to do the EBCDIC conversion there, separating it from your application logic.

您可以阅读序列化器/反序列化器这里

You can read about serializers/deserializers here.

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

TCP is a streaming protocol; this means that some structure has to be provided to data transported over TCP, so the receiver can demarcate the data into discrete messages. Connection factories are configured to use (de)serializers to convert between the message payload and the bits that are sent over TCP. This is accomplished by providing a deserializer and serializer for inbound and outbound messages respectively. A number of standard (de)serializers are provided.

ByteArrayCrlfSerializer ,将字节数组转换为流bytes后跟回车符和换行符( \\\\ n )。这是默认(de)序列化程序,例如,可以与telnet一起用作客户端。

The ByteArrayCrlfSerializer, converts a byte array to a stream of bytes followed by carriage return and linefeed characters (\r\n). This is the default (de)serializer and can be used with telnet as a client, for example.

这篇关于没有Transformer的Spring TCP客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆