3

I'm using the AndroidAsync koush low level network protocol library. I am connecting to a server with WebSocket. I am able to connect, send/receive messages, and disconnect. My disconnect time is very long. Server does not detect the disconnect for on average 59 seconds.

In order to reproduce the problem, I connect WebSocket, authorize, and start pinging every 10 seconds. Then I turn on Airplane Mode and my network connection drops. At this time the setClosedCallback method is called. Here is how I am logging this message:

private WebSocket mConnection;

private WebSocketConnectCallback mSocketCallback = new WebSocketConnectCallback() {
    @Override
    public void onCompleted(Exception ex, WebSocket webSocket) {
    ...
            webSocket.setClosedCallback(new CompletedCallback() {
            @Override
            public void onCompleted(Exception ex) {
                Log.d("websocket", "WebSocket closed");
                if (ex != null && ex.getMessage() != null) {
                    Log.e("websocket", "WebSocket closed exception: " + ex.getMessage());
                }
                disconnect();
            }
        });
    }
};

private void disconnect() {
    mPingHandler.removeCallbacks(pingRunnable);
    if (mConnection != null) {
        mConnection.close();
        mConnection = null;
    }
}

This is the log message letting me know that WebSocket has closed:

WebSocket closed exception: recvfrom failed: ETIMEDOUT (Connection timed out)

However our server does not receive the disconnect message for about 59 seconds. Our server is using these libraries:

  • gevent==1.0
  • gevent-websocket==0.9.2
  • greenlet==0.4.2

Is there a way to speed this up on my end? Is there a socket level timeout somewhere that I can set to a lower value so that my server guys get the disconnect message faster?

Lou Morda
  • 5,078
  • 2
  • 44
  • 49

1 Answers1

9

Because AndroidAsync does not implement the closing handshake which is required by RFC 6455 (see this for details), your WebSocket server cannot detect disconnection in the context of WebSocket. So, the server has to wait for ETIMEDOUT in the context of TCP/IP to detect disconnection.

Use a WebSocket library that complies with RFC 6455 and implements the closing handshake correctly.

Community
  • 1
  • 1
Takahiko Kawasaki
  • 18,118
  • 9
  • 62
  • 105
  • Just putting a link to @Takahiko's WebSocket library for reference https://github.com/TakahikoKawasaki/nv-websocket-client. I was using AndroidAsync and had this issue when closing the connection as Takahiko mentioned it doesn't properly close it and our server kept thinking the connections were still open after issuing a close in the client side. Takahiko's implementation works perfectly, it is much easier to implement and has way much cleaner ways to implement the callbacks. Don't know how I didn't find this library before. Took me 5min to migrate. hope the lib gets better google ranking. – velval Nov 07 '16 at 00:27