2016-11-07 70 views
0

我知道Spring集成有TcpInboundGateway和ByteArrayStxEtxSerializer來處理通過TCP端口傳來的數據。在彈簧集成中預讀TCP服務器

如果TCP服務器需要讀取客戶端發送的所有數據並進行處理,則ByteArrayStxEtxSerializer的工作效果很好。 (請求和響應模型)我正在使用single-use = false,以便可以在同一個連接中處理多個請求。

例如,如果客戶端發送0x02AAPL0x03,則服務器可以發送AAPL價格。

如果客戶端發送0x02AAPL0x030x02GOOG0x03,我的TCP服務器正在工作。它發送AAPL和GOOG價格。

有時客戶端在ETX(0x03)後發送LRC(縱向冗餘檢查)。如果客戶端發送LRC,我想閱讀並檢查校驗和。

我的客戶端請求可以是0x02AAPL0x030x1E0x02GOOG0x03。注意在這種情況下LRC是0x1E。

我知道ByteArrayStxEtxSerializer解串器可以被定製來讀取客戶端發送的字節。有沒有什麼方法可以預先閱讀LRC? 如果沒有LRC,則應將讀標記放回0x02,以便數據可以通過解串器以正常方式進行處理。

請建議如何處理可選的LRC。

這裏是我的Spring配置:

<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

您將需要在PushbackInputStream莫名其妙地包裹輸入流。

目前在框架中沒有掛鉤來做到這一點;我會考慮如何在未來的版本中提供這種可擴展性。

在此同時,一個解決辦法是將寫有狀態解串器維持一個ConcurrentHashMap,由InputStream參數鍵控,與地圖值是一個PushbackInputStream包裝。您需要實現ApplicationListener<TcpConnectionCloseEvent>,以便在套接字關閉時清除映射條目。