I'm trying to disconnect from WebSocket connection, but it's listener is still alive, I can see that websockets are still recreating by "OPEN/FAIL" messages using System.out messages.
On the one hand I've tried to release connection in finally
block using client.dispatcher().executorService().shutdown()
method, but it rejects other future calls (so it doesn't fit), on the other using client.connectionPool().evictAll()
doesn't help either (even if I wait, because it may not exit immediately based on docs https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/)
There is WebSocketListener code:
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()
}
}
There is DataSource implementation code:
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()
}
}
}
}
Use WebSocket.close()
for a graceful shutdown or WebSocket.cancel()
for an immediate one.
https://square.github.io/okhttp/5.x/okhttp/okhttp3/-web-socket/