我正在尝试创建一个可以使用 SSE (服务器发送事件)从服务器接收事件的客户端,并且我使用 OkHttp3 结合 OkHttp3-sse 库(com.squareup.okhttp3:okhttp:4.1 .0 和 com.squareup.okhttp3:okhttp-sse:4.1.0)。我能够很好地连接到服务器并接收事件,但在某个时间点,我想断开客户端连接并关闭我的应用程序。这就是问题所在。连接关闭,但应用程序未关闭,可能是由于ConnectionPool未关闭。
由于几乎没有任何有关使用 OkHttp3-sse 库的文档,因此我尝试从代码中进行逆向工程。我尝试过:
RealEventSource.cancel()在线程上的调用OkHttpClient.dispatcher().cancelAll()也正在断开连接,但仍挂在线程上Response.close()传递给的调用EventSourceListener.onOpen()作为替代方案,我查看了https://github.com/heremaps/oksse,其中包含RealServerSentEvent.close()正在执行我期望的操作的调用。它关闭连接并停止所有线程,从而允许应用程序完全关闭。我查看了该类的实现,RealServerSentEvent以了解该实现与RealEventSource. 我认为区别在于读取循环的条件:
RealEventSource行https://github.com/square/okhttp/blob/master/okhttp-sse/src/main/java/okhttp3/internal/sse/RealEventSource.kt#L75:
try {
listener.onOpen(this, response)
while (reader.processNextEvent()) {
}
} catch (e: Exception) {
listener.onFailure(this, e, response)
return
}
Run Code Online (Sandbox Code Playgroud)
RealServerSentEvent与行https://github.com/heremaps/oksse/blob/master/src/main/java/com/here/oksse/RealServerSentEvent.java#L94相比
:
listener.onOpen(this, response);
//noinspection StatementWithEmptyBody
while (call != null && !call.isCanceled() && sseReader.read()) {
}
Run Code Online (Sandbox Code Playgroud)
该OkSSE实现包括条件 if thecall.isCanceled()在循环中,where as theOkHttp3-sse不在循环中。我怀疑这是导致OkHttp3-sse无法退出的原因,但我可能是错的。
或者,我是否正在监督断开连接的预期方式?
最终我发现可以通过调用以下命令来正常关闭连接:
eventSource.cancel();
client.dispatcher().executorService().shutdown();
Run Code Online (Sandbox Code Playgroud)
由于这不需要对库进行任何更改,因此我关闭了错误报告。
| 归档时间: |
|
| 查看次数: |
3089 次 |
| 最近记录: |