Закрытие WebSocket в Kotlin
Соединение закрывают явно: у клиента вызывают
close, у сервера останавливают приём
через stop. Протокол передаёт код и
краткую причину; библиотека сообщает о закрытии
в onClose.
После обмена клиент закрывает сокет. В
onClose печатают причину и сигнализируют
main через CountDownLatch:
import java.net.InetSocketAddress
import java.net.URI
import java.util.concurrent.CountDownLatch
import org.java_websocket.WebSocket
import org.java_websocket.client.WebSocketClient
import org.java_websocket.handshake.ClientHandshake
import org.java_websocket.handshake.ServerHandshake
import org.java_websocket.server.WebSocketServer
fun main() {
val ready = CountDownLatch(1)
val closed = CountDownLatch(1)
val server = object : WebSocketServer(
InetSocketAddress(0),
) {
override fun onStart() {
ready.countDown()
}
override fun onOpen(
conn: WebSocket,
handshake: ClientHandshake,
) {}
override fun onClose(
conn: WebSocket,
code: Int,
reason: String,
remote: Boolean,
) {}
override fun onMessage(
conn: WebSocket,
message: String,
) {}
override fun onError(
conn: WebSocket,
ex: Exception,
) {}
}
server.start()
ready.await()
val port = server.port
val uri = URI("ws://127.0.0.1:$port")
val client = object : WebSocketClient(uri) {
override fun onOpen(
handshakedata: ServerHandshake,
) {}
override fun onMessage(message: String) {}
override fun onClose(
code: Int,
reason: String,
remote: Boolean,
) {
println(reason)
closed.countDown()
}
override fun onError(ex: Exception) {}
}
client.connectBlocking()
client.send("bye")
client.close()
closed.await()
server.stop()
}
Сервер тоже может закрыть конкретное соединение
из onMessage, тогда onClose
сработает на клиенте. Порядок завершения - сначала
закрыть клиентов, затем stop у сервера:
import java.net.InetSocketAddress
import java.net.URI
import java.util.concurrent.CountDownLatch
import org.java_websocket.WebSocket
import org.java_websocket.client.WebSocketClient
import org.java_websocket.handshake.ClientHandshake
import org.java_websocket.handshake.ServerHandshake
import org.java_websocket.server.WebSocketServer
fun main() {
val ready = CountDownLatch(1)
val closed = CountDownLatch(1)
val server = object : WebSocketServer(
InetSocketAddress(0),
) {
override fun onStart() {
ready.countDown()
}
override fun onOpen(
conn: WebSocket,
handshake: ClientHandshake,
) {}
override fun onClose(
conn: WebSocket,
code: Int,
reason: String,
remote: Boolean,
) {}
override fun onMessage(
conn: WebSocket,
message: String,
) {
conn.close(1000, "done")
}
override fun onError(
conn: WebSocket,
ex: Exception,
) {}
}
server.start()
ready.await()
val port = server.port
val uri = URI("ws://127.0.0.1:$port")
val client = object : WebSocketClient(uri) {
override fun onOpen(
handshakedata: ServerHandshake,
) {}
override fun onMessage(message: String) {}
override fun onClose(
code: Int,
reason: String,
remote: Boolean,
) {
println(reason)
closed.countDown()
}
override fun onError(ex: Exception) {}
}
client.connectBlocking()
client.send("finish")
closed.await()
server.stop()
}
После одного сообщения завершите соединение со
стороны клиента. В onClose выведите
причину закрытия.
Сервер закрывает клиента с причиной "ok"
после кадра "done". На клиенте
напечатайте эту причину.