我的同事和我正在开发一个与web服务通信的客户端应用程序,以便处理一些事务数据。以下是我们沟通的步骤:
timestamp = T1)timestamp ≈ T1)timestamp = T1 + few_seconds)timestamp = T1 + 3_minutes)timestamp = T1 + 3_minutes)我们的问题在于时间戳引用: web服务处理请求并几乎立即检索响应,但客户端应用程序在服务器关闭连接之前不会收到响应消息。以下是日志文件:
客户端应用程序日志片段:
10:46:25,031 INFO MessageHandler.java:115 Message sent.
10:49:25,071 INFO MessageHandler.java:125 Message received.
10:49:25,103 DEBUG MessageParser.java:67 Message parsed.服务器应用程序日志:
10:46:25:153 <INFO> Client connection accepted.
...
10:46:26:602 <INFO> Response message sent.
...
10:49:25:069 <INFO> Closing connection...如您所见,只有当服务器关闭连接时,客户端才会获得响应。
下面是进行通信的方法的客户端应用程序代码:
public static String sendMsg(byte[] msg, String serverIp, int port) {
try {
InetAddress address = InetAddress.getByName(serverIp);
Socket socket = new Socket(address, port);
OutputStream os = socket.getOutputStream();
logger.info("Message sent.");
os.write(msg, 0, msg.length);
os.flush();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String msgReceived = br.readLine();
logger.info("Message received.");
os.close();
return msgReceived;
} ...(catch blocks) ...
}假设我们无法更改web服务实现,在服务启动响应时(然后由客户端关闭连接),是否有一种方法可以立即在客户端获取响应消息?提前谢谢。
发布于 2016-08-29 18:31:02
很可能,客户端没有正确地实现消息协议。例如,客户机调用readLine。消息协议是否指定消息为一行?如果没有,readLine将继续等待,直到连接关闭,仍然试图获得永远不会发送的线路。
除非客户端理解如何分隔消息,否则将无法找到消息的结尾。在您的协议中如何分隔消息?检测消息结束的客户端代码在哪里?如果不是你写的,就不会发生。
发布于 2016-08-29 16:41:31
听起来你不太可能从客户端做些什么。可能发生的情况是,web服务器正在缓冲来自webservice的响应(因此它可以设置内容长度、标题等)。因此,在webservice关闭连接之前,不会发送任何数据。通过使用br.read()方法读取数据的单个字符,而不是像现在这样一次读取整行数据,您可以间接地检验这一假设。
发布于 2016-08-29 18:26:10
正如@Yeroc所建议的那样,似乎web服务器正在缓冲其响应,并且在出现超时之前不会刷新缓冲区。(在服务器端,我认为这是一个糟糕的设计选择,但如果您无法控制服务器,那么您可能会被困在服务器上。)
我会尝试在客户端做一个shutdown(SHUT_WR)。这应该会在服务器中产生一个“文件结束”指示,这可能会导致它刷新其缓冲区并关闭连接。因为这正是你想要的,这可能会让你反应得更快。带有shutdown的SHUT_WR只在一个方向关闭连接--客户机到服务器方向--所以您仍然能够接收响应。
(服务器可能不需要刷新就可以选择close,但刷新缓冲区很可能是服务器端高级close调用的副作用,因此绝对值得一试。)
https://stackoverflow.com/questions/39211079
复制相似问题