OkHttp WebSocket重启时出现RejectedExecutionException异常

4

我有这个客户:

OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .pingInterval(Duration.ofMinutes(3))
            .readTimeout(Duration.ofMillis(0))
            .build();

此为启动和停止的方法:

private WebSocket webSocket = null;
private MyListener wsListener = null;

private void start(){

    if(webSocket != null){ return; }

    wsListener = new MyListener();

    Request request = new Request.Builder()
        .url("wss://stream.binance.com:9443/ws")
        .build();

    webSocketBinance = okHttpClient.newWebSocket(request, wsListener); //here triggers error

}

private void stop(){

    if(webSocket == null){ return; }

    webSocket.close(1000, "{\"reason\": \"With love\"}");
    webSocket= null;

    okHttpClient.dispatcher().executorService().shutdown();
    okHttpClient.connectionPool().evictAll();

    wsListener = null;

}

有时我想像这样重新启动连接:
start();

Thread.sleep(10_000);

//restart connection
stop();
start(); //here triggers the error

但是在start()时,我收到了这个错误:

java.io.InterruptedIOException: executor rejected
    at okhttp3.internal.connection.RealCall$AsyncCall.executeOn(RealCall.kt:501)
    at okhttp3.Dispatcher.promoteAndExecute(Dispatcher.kt:184)
    at okhttp3.Dispatcher.enqueue$okhttp(Dispatcher.kt:125)
    at okhttp3.internal.connection.RealCall.enqueue(RealCall.kt:164)
    at okhttp3.internal.ws.RealWebSocket.connect(RealWebSocket.kt:165)
    at okhttp3.OkHttpClient.newWebSocket(OkHttpClient.kt:281)
    at foo.Foo.start(...)

Caused by: 
java.util.concurrent.RejectedExecutionException: 
    Task okhttp3.internal.connection.RealCall$AsyncCall@2aceadd4 rejected from 
    java.util.concurrent.ThreadPoolExecutor@24aed80c
    [Shutting down, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
    
at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2080)
    
at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:832)
    
at java.base/java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1365)
    
at okhttp3.internal.connection.RealCall$AsyncCall.executeOn(RealCall.kt:498)
    
... 8 more


我对OKHttp并不是很了解,但在我看来问题可能出在.readTimeout(Duration.ofMillis(0))上。尝试将0增加到10,000。现在它是否需要十秒钟才会崩溃? - Lajos Arpad
@LajosArpad,文档中说如果我将其设置为0,则表示没有超时。 - KunLun
你测试过了吗? - Lajos Arpad
@LajosArpad,是的,我尝试过了,但仍然出现相同的错误。 - KunLun
4
@KunLun 是的,我现在明白了。谢谢你。问题出在这一行代码上,okHttpClient.dispatcher().executorService().shutdown();。当它被关闭后,它会关闭 TaskExecutor 并拒绝任何进一步的连接。我关闭了 WebSocket 却没有关闭 OkHttpClient,然后尝试重新连接,这样就可以正常工作了。在 OkHttpClient 的文档中提到,关闭并不是必要的。OkHttp API - section117
显示剩余3条评论
1个回答

2
在我的情况下,解决方案是每次想要重新启动时创建一个新的OkHttpClientWebSocket

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