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

私の側でこれをスピードアップする方法はありますか?サーバーの担当者が切断メッセージをより速く取得できるように、低い値に設定できるソケット レベルのタイムアウトはどこかにありますか?

4

1 に答える 1

9

AndroidAsyncはRFC 6455で必要とされるクロージング ハンドシェイクを実装していないため(詳細はこちらを参照)、WebSocket サーバーはWebSocket のコンテキストで切断を検出できません。そのため、サーバーは切断を検出するために TCP/IP のコンテキストで待機する必要があります。ETIMEDOUT

RFC 6455 に準拠し、クロージング ハンドシェイクを正しく実装する WebSocket ライブラリを使用します。

于 2015-12-19T08:21:48.120 に答える