为什么AndroidAsync的断开时间这么长?

3
我正在使用AndroidAsync库,这是一个由koush编写的低级网络协议库。我通过WebSocket连接到服务器后能够发送/接收消息并断开连接。但是,我的断开时间非常长,平均需要59秒才能被服务器检测到。
为了重现这个问题,我会先通过WebSocket连接并进行授权,然后每10秒钟开始ping操作。当我打开飞行模式或者我的网络连接中断时,setClosedCallback方法就会被调用。以下是我记录这条信息的方式:
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;
    }
}

这是 WebSocket 关闭的日志消息: WebSocket 关闭异常: recvfrom 失败: ETIMEDOUT (连接超时) 然而,我们的服务器大约需要 59 秒才能收到断开连接的信息。我们的服务器使用以下库:
  • gevent==1.0
  • gevent-websocket==0.9.2
  • greenlet==0.4.2
有没有方法可以在我的端上加速这个过程?是否有一个套接字级别的超时设置,我可以将其设置为较低的值,以便我的服务器团队更快地收到断开连接的消息?
1个回答

9
由于AndroidAsync没有实现关闭握手,而RFC 6455要求实现该握手(详情请参见this),因此您的WebSocket服务器无法在WebSocket上下文中检测到断开连接。因此,服务器必须等待ETIMEDOUT以在TCP/IP上下文中检测到断开连接。
请使用符合RFC 6455规范并正确实现关闭握手的WebSocket库。

只是为了参考,放一个@Takahiko的WebSocket库的链接 https://github.com/TakahikoKawasaki/nv-websocket-client。我之前使用的是AndroidAsync,在关闭连接时遇到了问题,正如Takahiko所提到的,它没有正确地关闭连接,我们的服务器一直认为连接仍然打开,即使在客户端发出关闭请求后。Takahiko的实现完美地解决了这个问题,它更容易实现,并且有更清晰的回调实现方式。不知道为什么我以前没找到这个库。只用了5分钟就完成了迁移。希望这个库能得到更好的谷歌排名。 - velval

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接