MST

星途 面试题库

面试题:Kotlin WebSocket连接状态管理及异常处理

在Kotlin实现WebSocket实时通信时,如何优雅地管理WebSocket的连接状态(如连接、断开连接、重连)?请描述如何处理连接过程中可能出现的各种异常情况,比如网络中断、服务器拒绝连接等,并给出相关代码示例。
44.7万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试

1. 依赖引入

首先,在build.gradle中引入okhttp库,因为它内置了对WebSocket的支持。

implementation 'com.squareup.okhttp3:okhttp:4.9.1'

2. 管理WebSocket连接状态

创建一个WebSocketManager类来管理连接状态。

import okhttp3.*
import java.io.IOException

class WebSocketManager {
    private var webSocket: WebSocket? = null
    private var connectionListener: ConnectionListener? = null
    private var reconnectCount = 0
    private val MAX_RECONNECT_ATTEMPTS = 3
    private val client = OkHttpClient()
    private val request: Request = Request.Builder()
      .url("ws://your-server-url")
      .build()

    fun connect() {
        webSocket = client.newWebSocket(request, object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket, response: Response) {
                super.onOpen(webSocket, response)
                reconnectCount = 0
                connectionListener?.onConnected()
            }

            override fun onMessage(webSocket: WebSocket, text: String) {
                super.onMessage(webSocket, text)
                connectionListener?.onMessageReceived(text)
            }

            override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
                super.onClosing(webSocket, code, reason)
                connectionListener?.onClosing(code, reason)
            }

            override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
                super.onClosed(webSocket, code, reason)
                connectionListener?.onClosed(code, reason)
                if (reconnectCount < MAX_RECONNECT_ATTEMPTS) {
                    reconnect()
                } else {
                    connectionListener?.onReconnectFailed()
                }
            }

            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                super.onFailure(webSocket, t, response)
                connectionListener?.onFailure(t, response)
                if (reconnectCount < MAX_RECONNECT_ATTEMPTS) {
                    reconnect()
                } else {
                    connectionListener?.onReconnectFailed()
                }
            }
        })
    }

    private fun reconnect() {
        reconnectCount++
        connect()
    }

    fun sendMessage(message: String) {
        webSocket?.send(message)
    }

    fun disconnect() {
        webSocket?.close(1000, "Normal closure")
        webSocket = null
    }

    fun setConnectionListener(listener: ConnectionListener) {
        connectionListener = listener
    }

    interface ConnectionListener {
        fun onConnected()
        fun onMessageReceived(message: String)
        fun onClosing(code: Int, reason: String)
        fun onClosed(code: Int, reason: String)
        fun onFailure(t: Throwable, response: Response?)
        fun onReconnectFailed()
    }
}

3. 使用示例

fun main() {
    val webSocketManager = WebSocketManager()
    webSocketManager.setConnectionListener(object : WebSocketManager.ConnectionListener {
        override fun onConnected() {
            println("Connected to WebSocket server")
        }

        override fun onMessageReceived(message: String) {
            println("Received message: $message")
        }

        override fun onClosing(code: Int, reason: String) {
            println("Closing WebSocket. Code: $code, Reason: $reason")
        }

        override fun onClosed(code: Int, reason: String) {
            println("WebSocket closed. Code: $code, Reason: $reason")
        }

        override fun onFailure(t: Throwable, response: Response?) {
            println("WebSocket connection failed: ${t.message}")
        }

        override fun onReconnectFailed() {
            println("Reconnect attempts exhausted. Connection failed.")
        }
    })
    webSocketManager.connect()

    // 发送消息示例
    webSocketManager.sendMessage("Hello, WebSocket server!")

    // 模拟一段时间后断开连接
    Thread.sleep(5000)
    webSocketManager.disconnect()
}

4. 异常处理

  • 网络中断:当网络中断时,onFailure方法会被调用,在这个方法中我们可以进行重连操作。如上述代码,每次调用onFailure时会检查重连次数,如果未达到最大重连次数则进行重连。
  • 服务器拒绝连接:同样在onFailure方法中处理,服务器拒绝连接时会抛出异常,在该方法中我们同样通过重连机制来尝试再次连接。如果多次重连失败,则通知监听者重连失败。