Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import org.w3c.dom.MessageEvent
- import org.w3c.dom.WebSocket
- import kotlin.browser.window
- class KWebSocketImpl(val url : String, val reconnectDelayMillis: Int, val listener : (dynamic) -> Unit) {
- private var currentSocket : WebSocket? = null
- private val queue = arrayListOf<String>()
- private var closed = false
- init {
- connect()
- }
- fun stop() {
- closed = true
- try {
- currentSocket?.close()
- } catch (ignore : Throwable) {
- currentSocket = null
- }
- }
- fun send(o: Any) {
- if (closed) {
- throw IllegalStateException("Socket already stopped")
- }
- val text = JSON.stringify(o)
- queue.add(text)
- flush()
- }
- private fun flush() {
- val s = currentSocket ?: return
- try {
- val iterator = queue.iterator()
- while (iterator.hasNext()) {
- val text = iterator.next()
- s.send(text)
- iterator.remove()
- }
- } catch (ignore : Throwable) {
- }
- }
- private fun onMessage(message : dynamic) {
- listener(message)
- }
- private fun reconnectWithDelay() {
- window.setTimeout({
- connect()
- }, reconnectDelayMillis)
- }
- private fun connect() {
- try {
- tryConnect()
- } catch (any : Throwable) {
- reconnectWithMessageAndDelay()
- }
- }
- private fun reconnectWithMessageAndDelay() {
- console.error("WebSocket ($url) connection failure, will reconnect in ${reconnectDelayMillis / 1000.0}s")
- reconnectWithDelay()
- }
- private fun tryConnect() {
- val socket = WebSocket(url)
- fun closeSocket() {
- try {
- currentSocket?.close()
- socket.close()
- } finally {
- currentSocket = null
- }
- }
- socket.onopen = {
- if (currentSocket !== socket) {
- currentSocket?.close()
- currentSocket = socket
- }
- window.setTimeout({
- flush()
- }, 0)
- }
- socket.onerror = {
- closeSocket()
- reconnectWithMessageAndDelay()
- }
- socket.onmessage = {
- if (it is MessageEvent) {
- val data = it.data
- console.log("Received from websocket", data)
- if (data is String) {
- onMessage(JSON.parse(data))
- }
- flush()
- }
- }
- socket.onclose = {
- if (socket === currentSocket) {
- currentSocket = null
- }
- if (!closed) {
- tryConnect()
- }
- }
- }
- }
Add Comment
Please, Sign In to add comment