Coco Liliace
Coco Liliace

Reputation: 364

Check client connectivity to a RESTful Spring server without modifying application response

I have a REST service in Spring and an api that blocks for some before starting a heavy task and then returning it to the client. I want to check that the client is still connected to the socket of the request before I start the heavy task, so I don't waste computation power on someone who has disconnected already. I can't use a WebSocket and I am aware that the only way to check that the TCP connection is still open is to write some data to it. However, my HTTP response follows a strict format and writing anything to it would mess up that format.

I found an old tomcat thread from 2009 saying that we can achieve this by flushing empty bytes (new byte[0]) to response.getOutputStream, but when I tried it, I did not receive any exception even when the client had closed the connection. I traced through the source code of tomcat and found that they skip flushes that don't have length > 0, so I don't think this solution works.

I'm thinking that I would need something on the TCP layer, like a PING or keep-alive, but I could not find resources on how to do it for my use case. Spring's integration for TCP looks like it establishes new connections with a configured server instead of using the socket of the incoming requests. Tomcat's keep-alive configurations seem to be for timing out requests, not for checking if the user has disconnected (I don't want to time out any connection from my server).

Ideally, I would like to check for the connectivity periodically so that I can unblock and release the resources sooner, or halt the heavy task if the client disconnects after the task starts. But if that is too difficult, then just checking the connectivity once right before starting the heavy task is fine too.

Edit:

@talex pointed out in the comment that it is impossible to achieve the type of TCP heartbeat I proposed without changing the protocol. So now I'm thinking of a less robust check where we check whether we have received a FIN packet from the client, and not handle cases where the client disconnects abrubtly. Would this be possible to implement in the spring architecture? I found a related SO question but their solution is for detecting the EOF, which is always true in my case because spring would have parsed the stream for me by the time I reach my controller.

Upvotes: 1

Views: 70

Answers (1)

talex
talex

Reputation: 20436

Unfortunately even in weak form you question have same answer: You can't.

While theoretically you can check state of socket it not accessible from request handler (without dirtiest of hacks).

EDIT: I found this question. It suggests alternative approach. It may work, but I'm not sure.

Upvotes: 1

Related Questions