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

Posted

技术标签:

【中文标题】Android WebSocket - 断开连接检测奇怪的行为【英文标题】:Android WebSocket - disconnection detection strange behaviour 【发布时间】:2017-09-12 15:21:26 【问题描述】:

这是我使用 *** 多年后的第一个问题:D

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

在查阅文档后,我发现基本上是两种不同的情况:

1) 手动关闭

当我自己关闭 websocket(所以不是因为线路问题)时,应用程序流程基本上是这样的

    调用WebSocketClient.java上定义的close()方法

    该方法调用WebSocketImpl.java的close()方法

    @Override
    public void close( int code, String message ) 
        engine.close( code, message );
    
    

    close( int code, String message, boolean remote ) *code* 方法中,ABNORMALNORMAL 关闭案例是分开的,但似乎重要的部分或多或少是相同的

    readystate is setted to  **READYSTATE.CLOSING**
    
    readystate = READYSTATE.CLOSING;
    

    在 WebSocketClient 类中有一个正在运行的线程(从 websocket 连接开始),其中有一个检查 readystate 值的 while 循环

    try 
        while ( !isClosing() 
            && !isClosed() 
            && ( readBytes = istream.read( rawbuffer ) ) != -1 ) 
            engine.decode( ByteBuffer.wrap( rawbuffer, 0, readBytes ) );
    
    engine.eot();
    

    当 readystate 设置为 CLOSING 条件时,应用程序调用 eot(); 方法,其中连接已关闭,并通过 closeConnection() 方法调用 onWebsocketClose() 方法被调用,所有线程都被中断,最重要的是,stopConnectionLostTimer() 被调用;此计时器用于使用经典的 ping/pong 方法检查连接状态

所以这似乎工作得很好

线路网络问题断开

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

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

同样在这种情况下,close 方法设置 readystate = READYSTATE.CLOSING; 但现在似乎有 while 循环检查状态的线程正在等待,而 eot 方法(即 close连接和停止连接丢失计时器)永远不会被调用并且计时器永远不会停止。

我也尝试过重写 onClosing() 方法并调用 stopConnectionLostTimer() 方法,但又没有任何反应,因为似乎卡住了...

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

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

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

编辑: 你好,我发现了另一个重要的事情,就是为什么while语句在他可以关闭连接之前被阻塞了很长时间; 在while语句中有一个条件

( readBytes = istream.read( rawbuffer ) )

这个函数在大约 2 分钟后捕获一个异常 "no route no host" 。 我想在某种超时之后(但我找不到它)它会调用异常,所以最后连接关闭

【问题讨论】:

除了引用文档之外,您能否公开您的代码并突出显示您的代码的哪一部分造成了问题?我唯一理解的是“如何处理断开连接问题”...... 你好,问题是我现在学习的代码99%不是我写的;我基本上是在测试库的断开连接。 【参考方案1】:

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

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

【讨论】:

以上是关于Android WebSocket - 断开连接检测奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

WebSocket 在几个时间间隔之间不断断开连接

2018-03-26(websocket自动断开连接)

socket 用disconnect 断开,再重新连接怎么搞

websocket不断断开连接

C# socket 如何断开连接

连接后立即断开Websocket