Android WebSocket - 断开检测奇怪的行为

时间:2017-09-12 15:21:27

标签: javascript java android websocket chat

这是我在StackOverflow中的第一个问题,经过多年我使用它:D

我正在处理使用ToolTallNate API的应用程序。我只是在尝试检测由于线路问题导致的断线时发现了一个小问题(如低信号;在我的情况下,我模拟线路问题,停用我的本地网络)。

在深入研究文档后,我发现基本上有两种不同的情况:

1)手动关闭

当我自己关闭websocket(因此不是由于行问题)时,应用程序流程基本上是这样的

  1. 调用WebSocketClient.java
  2. 上定义的close()方法
  3. 此方法调用WebSocketImpl.java的close()方法

    @Override
    public void close( int code, String message ) {
        engine.close( code, message );
    }
    
  4. 在方法close( int code, String message, boolean remote ) {*code*}中,ABNORMALNORMAL关闭案例是分开的,但似乎重要部分或多或少相同

    readystate is setted to  **READYSTATE.CLOSING**
    
    readystate = READYSTATE.CLOSING;
    
  5. 在WebSocketClient类中有一个正在运行的线程(从websocket连接开始),其中有一个while循环检查 readystate

    try {
        while ( !isClosing() 
            && !isClosed() 
            && ( readBytes = istream.read( rawbuffer ) ) != -1 ) {
            engine.decode( ByteBuffer.wrap( rawbuffer, 0, readBytes ) );
    }
    engine.eot();
    
  6. 当readystate设置为CLOSING条件时,应用程序调用连接关闭的eot();方法,并通过 closeConnection()方法 onWebsocketClose()<调用/ strong>方法并且所有线程都被中断,最重要的是调用stopConnectionLostTimer();此计时器用于使用经典的ping / pong方法检查连接状态

  7. 所以这似乎完美无缺

    线网络问题断开连接

    要测试这种情况,我会停用我的本地网络(我正在测试我的应用程序)以在线模拟问题。

    程序流程基本相同但在这种情况下,在 startConnectionLostTimer()中调用close方法,如果服务器响应有延迟,则使用ABNORMAL_CLOSE调用close()方法条件

    同样在这个条件下,close方法设置 readystate = READYSTATE.CLOSING; 但是现在好像有一个while循环检查状态的线程正在等待和eot方法(关闭)永远不会调用连接和停止连接丢失计时器,并且计时器永不停止。

    我还试图覆盖onClosing()方法并调用stopConnectionLostTimer()方法但是没有任何事情发生,因为似乎有些东西被卡住......

    另一个奇怪的蜜蜂(或者可能只是形成我)是当我重新启动我的本地网络时,它最终通过eot方法关闭并停止一切......

    所以我期待在连接丢失超时之后,一切都必须像正常手动关闭()...

    我错了? (因为我知道我的论点有错误:D)

    修改 您好,我发现另一个重要的事情就是为什么while语句在关闭连接之前被阻止了很长时间; 在while语句中有一个条件

    ( readBytes = istream.read( rawbuffer ) )
    

    此功能在2分钟之后发现异常&#34;没有路由没有主机&#34; 。 我想,经过一段时间的超时(但我找不到它),它会调用异常,最后关闭连接

1 个答案:

答案 0 :(得分:0)

最后我发现了一种管理超时的方法; 在标准实现中,我无法设置输入流读取方法的超时,所以我只创建自己的WebSocketClient类,当创建套接字时,我还使用setSoTimeout设置timemout

socket = new Socket( proxy );
socket.setSoTimeout(20000);   //for 20 second of timeout ; it's in millisecond