问题描述
我需要实现一个 TCP 服务器,它基本上应该打开一个套接字作为与客户端握手的一部分.
socket打开后服务端需要保持socket打开状态,并能够通过打开的socket向客户端推送消息
我查看了一些 spring 集成示例,但不确定我看到的示例实际上是对我的 requiremnt 的引用.
1 .spring 集成 tcp 是否具有保持打开套接字并将消息从服务器发送到客户端的能力?
服务器也应该支持传入请求
客户端实现是一个模拟,写成一个简单的 Tcp java 客户端
谢谢!尼尔
这里是上下文配置
<int-ip:tcp-inbound-channel-adapter id="inboundServer"频道=内环"连接工厂=服务器"客户端模式=假"/><int-ip:tcp-outbound-channel-adapter id="outboundServer"频道=外环"连接工厂=服务器"客户端模式=假"/><channel id="inloop"/><channel id="outloop"/>
在我使用的服务器端
outputchanel.send(new GenericMessage("HI World from server16\n",header));
并在客户端使用
读取推送消息 BufferedReader stdIn = new BufferedReader(new InputStreamReader(socketClient.getInputStream()));while ((serverResponse = stdIn.readLine()) != null) {_logger.info("来自服务器的响应::"+serverResponse);}
客户端是一个java base tcp客户端,没有配置spring集成,这是一个未来集成的模拟客户端
为了支持不以 '\n' 终止的字节数组请求的回显服务器,我扩展 AbstractByteArraySerializer 并覆盖反序列化
public byte[] deserialize(InputStream inputStream) 抛出 IOException {_Logger.trace("开始反序列化");字节[] 结果;试试{字节 [] 缓冲区 = 新字节 [getMaxMessageSize()];int numOfBytes = inputStream.read(buffer, 0, buffer.length);结果 = copyToSizedArray(buffer, numOfBytes);} catch (IOException e) {_Logger.error("反序列化tcp入站流异常", e);//publishEvent(e, , n);扔e;}返回结果;}
您可以使用 协作通道适配器,用于在对等方之间进行完全任意的消息传递.
参见 TCP 事件.>
tcp 入站通道适配器(实际上是连接工厂)将在客户端连接时发布一个 TcpConnectionOpenEvent
.
您可以使用 ApplicationListener
来接收这些事件.
该事件包含一个 connectionId
.然后,您可以在名为 ip_connectionId
(IpHeaders.CONNECTION_ID
) 的标头中使用此 connectionId
开始向 tcp 出站通道适配器发送消息.
入站适配器从客户端接收的入站消息(如果有)将在标头中具有相同的值.
只需配置服务器连接工厂并配置两个适配器即可使用它.
如果服务器必须打开套接字,请使用 client-mode="true"
并注入客户端连接工厂.
I need to implement a TCP server which basicliy should open a socket as part of handshake with a client .
after socket is open server need to keep the socket open , and be able to push a message from the server to the client via the open socket
I look on some spring integration examples but not sure that examples I saw are actully a reference to my requiremnt .
1 .does spring integration tcp has a this ability to keep open socket and send a message from server to client ?
the server should support as well incoming requests
client side implemenatation is a mock written as a simple Tcp java client
Thanks!Nir
here context configuration
<int-ip:tcp-connection-factory id="server"
type="server"
port="5679"
host="localhost"
single-use="false"
deserializer="javaDeserializer"
serializer="javaSerializer" />
<int-ip:tcp-inbound-channel-adapter id="inboundServer"
channel="inloop"
connection-factory="server" client-mode="false"/>
<int-ip:tcp-outbound-channel-adapter id="outboundServer"
channel="outloop"
connection-factory="server" client-mode="false"/>
<channel id="inloop"/>
<channel id="outloop"/>
on the server side I use
outputchanel.send(new GenericMessage<String>("HI World from server16\n",header));
and on the client side read push message with
BufferedReader stdIn = new BufferedReader(new InputStreamReader(socketClient.getInputStream()));
while ((serverResponse = stdIn.readLine()) != null) {
_logger.info("RESPONSE FROM SERVER::"+serverResponse);
}
the client side is a java base tcp client not configure with spring integration , this is a mock client for future integration
for support echo server for a request with byte array not terminate with '\n' , I extend AbstractByteArraySerializer , and override deserialize
public byte[] deserialize(InputStream inputStream) throws IOException {
_Logger.trace("start deserialize");
byte[] result;
try {
byte[] buffer = new byte[getMaxMessageSize()];
int numOfBytes = inputStream.read(buffer, 0, buffer.length);
result = copyToSizedArray(buffer, numOfBytes);
} catch (IOException e) {
_Logger.error("Exception on deserialize tcp inbound stream ", e);
//publishEvent(e, , n);
throw e;
}
return result;
}
You can use collaborating channel adapters for completely arbitrary messaging between peers.
See TCP Events.
The tcp inbound channel adapter (actually the connection factory) will publish a TcpConnectionOpenEvent
when the client connects.
You can use an ApplicationListener
to receive these events.
The event contains a connectionId
. You can then start sending messages to a tcp outbound channel adapter with this connectionId
in the header named ip_connectionId
(IpHeaders.CONNECTION_ID
).
Inbound messages (if any) from the client received by the inbound adapter will have the same value in the header.
Simply configure a server connection factory and configure both adapters to use it.
If the server has to open the socket, use client-mode="true"
and inject a client connection factory.
这篇关于Spring 集成 TCP 服务器推送到客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!