如何使用 OkHttpClient 真正断开与 WebSocket 的连接?
How to really disconnect from WebSocket using OkHttpClient?
我正在尝试断开 WebSocket 连接,但它的侦听器仍然存在,我可以看到 Websocket 仍在使用 System.out 消息通过“OPEN/FAIL”消息重新创建。
一方面,我尝试使用 client.dispatcher().executorService().shutdown()
方法释放 finally
块中的连接,但它拒绝了以后的其他调用(因此不适合),另一方面使用client.connectionPool().evictAll()
也无济于事(即使我等待,因为它可能不会根据文档立即退出 https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/)
有WebSocketListener代码:
class WebSocketConnectionListener(
private val updateConnectionValue: (internetConnection: Boolean) -> Unit,
private val okHttpClient: OkHttpClient,
private val urlAddress: String
) : WebSocketListener() {
companion object {
private const val NORMAL_CLOSURE_STATUS = 1000
}
private var isConnected = true
private var webSocketN: WebSocket? = null
init {
createWebSocket()
}
override fun onOpen(webSocket: WebSocket, response: Response) {
println("OPEN: ${response.code}")
isConnected = true
updateConnectionValue(true)
reconnect(webSocket)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
println("FAIL: $t")
if (!isConnected) {
updateConnectionValue(false)
}
isConnected = false
reconnect(webSocket)
}
private fun createWebSocket() {
val request = Request.Builder().url(urlAddress).build()
webSocketN = okHttpClient.newWebSocket(request, this)
}
private fun reconnect(webSocket: WebSocket) {
webSocket.close(NORMAL_CLOSURE_STATUS, null)
webSocketN?.close(NORMAL_CLOSURE_STATUS, "Connection closed")
webSocketN = null
Thread.sleep(3_000)
createWebSocket()
}
}
有DataSource实现代码:
class InternetConnectionDataSourceImpl(
private val okHttpClient: OkHttpClient,
private val urlAddress: String
) : InternetConnectionDataSource {
private fun createWebSocketListener(
internetConnectionFlow: MutableStateFlow<Boolean>,
) = WebSocketConnectionListener(
updateConnectionValue = { internetConnectionFlow.value = it },
okHttpClient = okHttpClient,
urlAddress = urlAddress
)
override suspend fun checkConnection(): Flow<Boolean> =
withContext(Dispatchers.IO) {
val internetConnectionFlow = MutableStateFlow(true)
createWebSocketListener(internetConnectionFlow)
flow {
try {
internetConnectionFlow.collect {
emit(it)
}
} finally {
println("finally")
okHttpClient.connectionPool.evictAll()
}
}
}
}
结果我在 logcat 中收到了这条消息
使用 WebSocket.close() 进行正常关机或使用 cancel() 进行立即关机。
https://square.github.io/okhttp/4.x/okhttp/okhttp3/-web-socket/
我正在尝试断开 WebSocket 连接,但它的侦听器仍然存在,我可以看到 Websocket 仍在使用 System.out 消息通过“OPEN/FAIL”消息重新创建。
一方面,我尝试使用 client.dispatcher().executorService().shutdown()
方法释放 finally
块中的连接,但它拒绝了以后的其他调用(因此不适合),另一方面使用client.connectionPool().evictAll()
也无济于事(即使我等待,因为它可能不会根据文档立即退出 https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/)
有WebSocketListener代码:
class WebSocketConnectionListener(
private val updateConnectionValue: (internetConnection: Boolean) -> Unit,
private val okHttpClient: OkHttpClient,
private val urlAddress: String
) : WebSocketListener() {
companion object {
private const val NORMAL_CLOSURE_STATUS = 1000
}
private var isConnected = true
private var webSocketN: WebSocket? = null
init {
createWebSocket()
}
override fun onOpen(webSocket: WebSocket, response: Response) {
println("OPEN: ${response.code}")
isConnected = true
updateConnectionValue(true)
reconnect(webSocket)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
println("FAIL: $t")
if (!isConnected) {
updateConnectionValue(false)
}
isConnected = false
reconnect(webSocket)
}
private fun createWebSocket() {
val request = Request.Builder().url(urlAddress).build()
webSocketN = okHttpClient.newWebSocket(request, this)
}
private fun reconnect(webSocket: WebSocket) {
webSocket.close(NORMAL_CLOSURE_STATUS, null)
webSocketN?.close(NORMAL_CLOSURE_STATUS, "Connection closed")
webSocketN = null
Thread.sleep(3_000)
createWebSocket()
}
}
有DataSource实现代码:
class InternetConnectionDataSourceImpl(
private val okHttpClient: OkHttpClient,
private val urlAddress: String
) : InternetConnectionDataSource {
private fun createWebSocketListener(
internetConnectionFlow: MutableStateFlow<Boolean>,
) = WebSocketConnectionListener(
updateConnectionValue = { internetConnectionFlow.value = it },
okHttpClient = okHttpClient,
urlAddress = urlAddress
)
override suspend fun checkConnection(): Flow<Boolean> =
withContext(Dispatchers.IO) {
val internetConnectionFlow = MutableStateFlow(true)
createWebSocketListener(internetConnectionFlow)
flow {
try {
internetConnectionFlow.collect {
emit(it)
}
} finally {
println("finally")
okHttpClient.connectionPool.evictAll()
}
}
}
}
结果我在 logcat 中收到了这条消息
使用 WebSocket.close() 进行正常关机或使用 cancel() 进行立即关机。
https://square.github.io/okhttp/4.x/okhttp/okhttp3/-web-socket/