Reputation: 436
My colleague and I were working on a client application that communicates with the web service in order to process some transaction data. These are steps in our communication:
timestamp = T1
)timestamp ≈ T1
)timestamp = T1 + few_seconds
)timestamp = T1 + 3_minutes
)timestamp = T1 + 3_minutes
)Our problem lies in the timestamp references: The web service process the request and retrieves the response almost immediately but the client application does not get the response message until the server closes the connection. Here are log files:
Client application log snippet:
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.
Server application log:
10:46:25:153 <INFO> Client connection accepted.
...
10:46:26:602 <INFO> Response message sent.
...
10:49:25:069 <INFO> Closing connection...
As you can see, client gets the response only when the server closes the connection.
Here is the client app code of the method where the communication is done:
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) ...
}
Suppose that we can't change the web service implementation, is there a way to get the response message on the client side immediately when the service initiates the response (and then to close the connection by client) ? Thanks in advance.
Upvotes: 1
Views: 3705
Reputation: 182753
Most likely, the client is not properly implementing the message protocol. For example, the client calls readLine
. Does the message protocol specify that the message is a line? If not, readLine
will keep waiting until the connection closes, still trying to get that line that was never going to be sent.
The client will be unable to find the end of a message unless it understands how a message is delimited. How is a message delimited in your protocol? Where is the client code to detect the end of a message? If you didn't write it, it won't happen.
Upvotes: 3
Reputation: 12347
As @Yeroc suggested, it seems likely that the web server is buffering its response and not flushing the buffer until some timeout occurs. (This strikes me as a poor design choice on the server side but if you have no control over the server, presumably you're stuck with it.)
I would try doing a shutdown(SHUT_WR)
on the client side. This should produce an "end of file" indication in the server which would presumably lead it to flush its buffer and close the connection. Since that's exactly what you want to happen, that may get you your response more quickly. The shutdown
with SHUT_WR
only shuts down the connection in one direction -- the client-to-server direction -- so you should still be able to receive the response.
(It's possible the server could choose to close
without flushing, but it seems likely that flushing the buffer is being done as a side-effect of a high-level close
call on the server side so it's definitely worth a try.)
Upvotes: 1
Reputation: 1111
It sounds unlikely there's anything you can do about this from the client-side. What's probably happening is the web server is buffering the response from the webservice (so it can set content length headers etc.) so until the webservice closes the connection no data is sent. You can indirectly test this hypothesis by using the br.read()
method to read a single character of data instead of a whole line at a time as you are now.
Upvotes: 1