Spring 集成 tcp-connection-factory 在回复前关闭客户端连接
Spring integration tcp-connection-factory closes client connection before reply
我在 spring 集成方面遇到了一些问题。
比方说,有我的传出通信配置:
<int:channel id="outputChannel">
<int:queue />
</int:channel>
<int:channel id="outputChannel-in"> <!-- for response from server -->
<int:queue />
</int:channel>
<int-ip:tcp-connection-factory
id="outputSocket"
type="client"
single-use="true"
host="localhost"
port="666" />
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="outputChannel"
reply-channel="outputChannel-in"
connection-factory="outputSocket"
reply-timeout="20000" />
<int:gateway id="myGateway"
service-interface="some.package.SocketGateway"
default-request-channel="outputChannel"
default-reply-channel="outputChannel-in" />
<int:service-activator
id="myServiceActivator"
input-channel="outputChannel-in"
ref="myService"
method="incomingDataHandlingMethod" />
不管我对界面做什么some.package.SocketGateway:
选项#1:
public interface SocketGateway{
byte[] send(String text);
}
选项#2:
public interface SocketGateway{
Future<byte[]> send(String text);
}
它没有收到任何消息。
我经常玩配置。这只是我的解决方案的一个版本,但 none 个版本有效。
这是一个服务器模拟:
ServerSocket someSocket = new ServerSocket(666);
Socket socket = someSocket.accept();
PrintWriter out =
new PrintWriter (socket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
System.out.println("socket accepted");
String data = in.readLine();
while (data != null) {
System.out.println(data);
data = in.readLine();
}
System.out.println("data received");
out.println("ACK");
out.flush();
System.out.println("data sent");
socket.close();
someSocket.close();
当out.println("ACK");
while 后,连接关闭且不发送ACK。当out.println("ACK");
在while之前或里面时,发送消息。
我应该怎么做才能收到这条消息?
编辑:
我也尝试过:
<int-ip:tcp-outbound-channel-adapter
id="outboundClient"
channel="outputChannel"
connection-factory="outputSocket" />
<int-ip:tcp-inbound-channel-adapter
id="outboundClient-in"
channel="outputChannel-in"
connection-factory="outputSocket" />
没有好的结果。
编辑:
我有这个客户端代码:
Socket echoSocket = new Socket("10.20.30.40", 11111);
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
String encodedMessage = "someMessage";
String result = String.format("%c%s%c%c", (char) 11, encodedMessage, (char) 28, (char) 13);
out.println(result);
out.flush();
System.out.println("data sent");
File file = new File("result.txt");
BufferedWriter output = new BufferedWriter(new FileWriter(file));
String data;
while ((data = in.readLine()) != null) {
output.write(data);
}
output.flush();
output.close();
System.out.println("after while");
out.close();
in.close();
echoSocket.close();
这在外部服务器上运行良好(服务器正在同步发送 ACK 消息,该消息在 字符串数据 中接收。如何通过 Spring 集成实现此结果?我什么都收不到...
TCP是一个流;它需要结构来分隔消息。默认的反序列化器在最后期望 CRLF。
发送out.println("ACK\r\n");
.
您可以阅读 Serializer
s 和 Deserializer
s here。
编辑:
你的逻辑有几个方面的缺陷。
- 使用
PrintWriter.println()
仅附加LF;除非您更改解串器,否则您需要 CRLF。
- 您的 "server" 挂在
readLine()
上,直到套接字关闭。
这很好用:
ServerSocket someSocket = new ServerSocket(1666);
Socket socket = someSocket.accept();
OutputStream out = socket.getOutputStream();
BufferedReader in =
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
System.out.println(Thread.currentThread().getName() + " socket accepted");
String data = in.readLine();
System.out.println(data);
System.out.println("data received");
out.write("ACK\r\n".getBytes());
out.flush();
System.out.println("data sent");
socket.close();
someSocket.close();
我在 spring 集成方面遇到了一些问题。 比方说,有我的传出通信配置:
<int:channel id="outputChannel">
<int:queue />
</int:channel>
<int:channel id="outputChannel-in"> <!-- for response from server -->
<int:queue />
</int:channel>
<int-ip:tcp-connection-factory
id="outputSocket"
type="client"
single-use="true"
host="localhost"
port="666" />
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="outputChannel"
reply-channel="outputChannel-in"
connection-factory="outputSocket"
reply-timeout="20000" />
<int:gateway id="myGateway"
service-interface="some.package.SocketGateway"
default-request-channel="outputChannel"
default-reply-channel="outputChannel-in" />
<int:service-activator
id="myServiceActivator"
input-channel="outputChannel-in"
ref="myService"
method="incomingDataHandlingMethod" />
不管我对界面做什么some.package.SocketGateway:
选项#1:
public interface SocketGateway{
byte[] send(String text);
}
选项#2:
public interface SocketGateway{
Future<byte[]> send(String text);
}
它没有收到任何消息。 我经常玩配置。这只是我的解决方案的一个版本,但 none 个版本有效。
这是一个服务器模拟:
ServerSocket someSocket = new ServerSocket(666);
Socket socket = someSocket.accept();
PrintWriter out =
new PrintWriter (socket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
System.out.println("socket accepted");
String data = in.readLine();
while (data != null) {
System.out.println(data);
data = in.readLine();
}
System.out.println("data received");
out.println("ACK");
out.flush();
System.out.println("data sent");
socket.close();
someSocket.close();
当out.println("ACK");
while 后,连接关闭且不发送ACK。当out.println("ACK");
在while之前或里面时,发送消息。
我应该怎么做才能收到这条消息?
编辑: 我也尝试过:
<int-ip:tcp-outbound-channel-adapter
id="outboundClient"
channel="outputChannel"
connection-factory="outputSocket" />
<int-ip:tcp-inbound-channel-adapter
id="outboundClient-in"
channel="outputChannel-in"
connection-factory="outputSocket" />
没有好的结果。
编辑: 我有这个客户端代码:
Socket echoSocket = new Socket("10.20.30.40", 11111);
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
String encodedMessage = "someMessage";
String result = String.format("%c%s%c%c", (char) 11, encodedMessage, (char) 28, (char) 13);
out.println(result);
out.flush();
System.out.println("data sent");
File file = new File("result.txt");
BufferedWriter output = new BufferedWriter(new FileWriter(file));
String data;
while ((data = in.readLine()) != null) {
output.write(data);
}
output.flush();
output.close();
System.out.println("after while");
out.close();
in.close();
echoSocket.close();
这在外部服务器上运行良好(服务器正在同步发送 ACK 消息,该消息在 字符串数据 中接收。如何通过 Spring 集成实现此结果?我什么都收不到...
TCP是一个流;它需要结构来分隔消息。默认的反序列化器在最后期望 CRLF。
发送out.println("ACK\r\n");
.
您可以阅读 Serializer
s 和 Deserializer
s here。
编辑:
你的逻辑有几个方面的缺陷。
- 使用
PrintWriter.println()
仅附加LF;除非您更改解串器,否则您需要 CRLF。 - 您的 "server" 挂在
readLine()
上,直到套接字关闭。
这很好用:
ServerSocket someSocket = new ServerSocket(1666);
Socket socket = someSocket.accept();
OutputStream out = socket.getOutputStream();
BufferedReader in =
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
System.out.println(Thread.currentThread().getName() + " socket accepted");
String data = in.readLine();
System.out.println(data);
System.out.println("data received");
out.write("ACK\r\n".getBytes());
out.flush();
System.out.println("data sent");
socket.close();
someSocket.close();