Fix thread safety
syncExec synced on the Listener instance, but it modified properties of the WebSocketConnection without synchronizing on the WebSocketConnection.
This commit is contained in:
@@ -116,13 +116,18 @@ internal class WebSocketConnection(
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
fun close() {
|
fun close() {
|
||||||
if (webSocket != null) {
|
if (webSocket != null) {
|
||||||
|
webSocket?.close(1000, "")
|
||||||
|
closed()
|
||||||
Log.i("WebSocket(${ID.get()}): closing existing connection.")
|
Log.i("WebSocket(${ID.get()}): closing existing connection.")
|
||||||
state = State.Disconnected
|
|
||||||
webSocket!!.close(1000, "")
|
|
||||||
webSocket = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
private fun closed() {
|
||||||
|
webSocket = null
|
||||||
|
state = State.Disconnected
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun scheduleReconnect(seconds: Long) {
|
fun scheduleReconnect(seconds: Long) {
|
||||||
if (state == State.Connecting || state == State.Connected) {
|
if (state == State.Connecting || state == State.Connected) {
|
||||||
@@ -150,7 +155,7 @@ internal class WebSocketConnection(
|
|||||||
|
|
||||||
private inner class Listener(private val id: Long) : WebSocketListener() {
|
private inner class Listener(private val id: Long) : WebSocketListener() {
|
||||||
override fun onOpen(webSocket: WebSocket, response: Response) {
|
override fun onOpen(webSocket: WebSocket, response: Response) {
|
||||||
syncExec {
|
syncExec(id) {
|
||||||
state = State.Connected
|
state = State.Connected
|
||||||
Log.i("WebSocket($id): opened")
|
Log.i("WebSocket($id): opened")
|
||||||
onOpen.run()
|
onOpen.run()
|
||||||
@@ -164,7 +169,7 @@ internal class WebSocketConnection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessage(webSocket: WebSocket, text: String) {
|
override fun onMessage(webSocket: WebSocket, text: String) {
|
||||||
syncExec {
|
syncExec(id) {
|
||||||
Log.i("WebSocket($id): received message $text")
|
Log.i("WebSocket($id): received message $text")
|
||||||
val message = Utils.JSON.fromJson(text, Message::class.java)
|
val message = Utils.JSON.fromJson(text, Message::class.java)
|
||||||
onMessageCallback(message)
|
onMessageCallback(message)
|
||||||
@@ -173,12 +178,12 @@ internal class WebSocketConnection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
|
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
|
||||||
syncExec {
|
syncExec(id) {
|
||||||
if (state == State.Connected) {
|
if (state == State.Connected) {
|
||||||
Log.w("WebSocket($id): closed")
|
Log.w("WebSocket($id): closed")
|
||||||
onClose.run()
|
onClose.run()
|
||||||
}
|
}
|
||||||
state = State.Disconnected
|
closed()
|
||||||
}
|
}
|
||||||
super.onClosed(webSocket, code, reason)
|
super.onClosed(webSocket, code, reason)
|
||||||
}
|
}
|
||||||
@@ -187,11 +192,10 @@ internal class WebSocketConnection(
|
|||||||
val code = if (response != null) "StatusCode: ${response.code()}" else ""
|
val code = if (response != null) "StatusCode: ${response.code()}" else ""
|
||||||
val message = if (response != null) response.message() else ""
|
val message = if (response != null) response.message() else ""
|
||||||
Log.e("WebSocket($id): failure $code Message: $message", t)
|
Log.e("WebSocket($id): failure $code Message: $message", t)
|
||||||
syncExec {
|
syncExec(id) {
|
||||||
state = State.Disconnected
|
closed()
|
||||||
if (response != null && response.code() >= 400 && response.code() <= 499) {
|
if (response != null && response.code() >= 400 && response.code() <= 499) {
|
||||||
onBadRequest.execute(message)
|
onBadRequest.execute(message)
|
||||||
close()
|
|
||||||
return@syncExec
|
return@syncExec
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,13 +213,12 @@ internal class WebSocketConnection(
|
|||||||
}
|
}
|
||||||
super.onFailure(webSocket, t, response)
|
super.onFailure(webSocket, t, response)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun syncExec(runnable: Runnable) {
|
@Synchronized
|
||||||
synchronized(this) {
|
private fun syncExec(id: Long, runnable: () -> Unit) {
|
||||||
if (ID.get() == id) {
|
if (ID.get() == id) {
|
||||||
runnable.run()
|
runnable()
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user