Problem closing WebSocket connection with 3.9.3

429 views
Skip to first unread message

Eric Champigny

unread,
Dec 17, 2020, 12:48:59 PM12/17/20
to vert.x
Hi,

I'm using Vert.x to power a chat server that's used for the chat functionality of a mobile app. It uses WebSockets and is behind an NGINX proxy.

I was using Vertx 3.8.4 and I'm in the process of upgrading to the latest version. Version 3.9.3 is causing problems with my detection of lost connection and the closing of them.

Basically, my WebSocket has a close handler in which I do some cleanup stuff (mark the user as not connection in the DB, etc...). I have a ping-pong process for detecting stale connections: a ping is written to the WebSocket on a timer and if the pong is not received on the next timer invocation, I close the WebSocket.

Before 3.9.3, the close handler was called pretty much directly after the WebSocket close. With 3.9.3, it can take up to 15 minutes. I guess it's because of WebSocket closing handshake improvements #3531. Since the server now seem to wait for some acknowledgment frame to close the TCP connection after sending the close frame, this will never come if the connection to the client is broken. Maybe if the client was connection directly to Vert.x it could detect the broken connection, but in my case I guess Vert.x connection to NGINX is still good even if the connection from NGINX to the client is broken.

I know this could be considered a problem with my setup (NGINX), but let's say a client is buggy or malicious, it could simply not respond to the close frame and keep the connection open for a long time and on the server I would have no way to close it. Would it be possible for the TCP connection to be really closed after a ws.close(), whether by passing a max amount of time to wait or some other method?

Thanks

Eric

Julien Viet

unread,
Dec 17, 2020, 4:56:53 PM12/17/20
to vert.x
Hi,

this change was done to "respect" the specification.

I think we should introduce a timeout to close the server WebSocket.

In the meantime you could set a TCP idle timeout to mitigate this.

Julien



--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/4426d104-6faf-49bb-8339-33f6c67b01c7n%40googlegroups.com.

Julien Viet

unread,
Dec 18, 2020, 6:07:11 AM12/18/20
to vert.x
the feature was implemented in master https://github.com/eclipse-vertx/vert.x/issues/3714

the default timeout is 10 seconds on the server.

you can set 0 to close the connection immediately.

if the connection is closed before the WebSocket close frame is received this will result in a connection reset on the client (because it will send a close frame to a closed socket) and an exception on the server (reported on the exception handler) because the connection was closed before the close frame was received, the end handler on the server will not be called too for the same reason.

in the meantime 3.9.6 is released you can set an idle timeout on the server (which is actually a recommended practice) that will close the socket after a while when no activity was received from the client.

Julien


Eric Champigny

unread,
Dec 18, 2020, 5:00:04 PM12/18/20
to vert.x
Thanks Julien.

As you suggested I quickly tried the idle timeout by setting it a bit higher than my ping-pong delay so shouldn't modify the current behavior I have for detecting broken connections. I'll just call my cleanup code as soon as I close the connection in that case instead of waiting for the close handler.

Thanks a lot to you and all the development team for making Vert.x such a great tool to use.

Eric

Reply all
Reply to author
Forward
0 new messages