我知道spring集成了TcpInboundGateway和ByteArrayStxEtxSerializer来处理通过TCP端口传输的数据。
如果TCP服务器需要读取客户端发送的所有数据然后对其进行处理,那么ByteArrayStxEtxSerializer工作得很好。 (请求和响应模型)我使用single-use = false,以便可以在同一连接中处理多个请求。
例如,如果客户端发送0x02AAPL0x03,那么Server可以发送AAPL价格。
如果客户端发送0x02AAPL0x030x02GOOG0x03,我的TCP服务器正在运行。它发送AAPL和GOOG价格的价格。
有时客户端在ETX(0x03)之后发送LRC(纵向冗余校验)。如果客户端发送LRC,我想阅读并检查校验和。
我的客户端请求可以是0x02AAPL0x030x1E0x02GOOG0x03。注意在这种情况下LRC是0x1E。
我知道可以自定义ByteArrayStxEtxSerializer反序列化器来读取客户端发送的字节。有什么方法可以提前阅读以寻找LRC吗? 如果没有LRC,则应将读取标记放回0x02,以便解串器以正常方式处理数据。
请建议如何处理可选的LRC。
这是我的弹簧配置:
<int-ip:tcp-connection-factory id="crLfServer"
type="server"
port="${availableServerSocket}"
single-use="false"
so-timeout="10000"
using-nio="false"
serializer="connectionSerializeDeserialize"
deserializer="connectionSerializeDeserialize"
so-linger="2000"/>
<bean id="connectionSerializeDeserialize" class="org.springframework.integration.ip.tcp.serializer.ByteArrayStxEtxSerializer"/>
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
connection-factory="crLfServer"
request-channel="serverBytes2StringChannel"
error-channel="errorChannel"
reply-timeout="10000"/> <!-- reply-timeout works on inbound-gateway -->
<int:channel id="toSA" />
<int:service-activator input-channel="toSA"
ref="myService"
method="prepare"/>
<int:object-to-string-transformer id="serverBytes2String"
input-channel="serverBytes2StringChannel"
output-channel="toSA"/>
<int:transformer id="errorHandler"
input-channel="errorChannel"
expression="payload.failedMessage.payload + ':' + payload.cause.message"/>
由于
答案 0 :(得分:0)
您需要以某种方式将输入流包装在PushbackInputStream。
中目前框架中没有钩子可以做到这一点;我将考虑如何在将来的版本中提供这样的可扩展性。
与此同时,一种解决方案是编写一个有状态的反序列化器,它维护ConcurrentHashMap
,由InputStream
参数键入,映射值为PushbackInputStream
包装器。您需要实现ApplicationListener<TcpConnectionCloseEvent>
,以便在套接字关闭时清除映射条目。