开发者
资源
Android使用Kotlin实现WebSocket通信
Android使用Kotlin实现WebSocket通信
发表于2025/07/30
1010

一、WebSocket简介

WebSocket是一种在单个TCP连接上进行全双工通信的协议,与传统的HTTP请求相比具有显著优势:

  • 持久连接:一次握手,持久连接,避免重复建立连接的开销
  • 双向通信:服务器可以主动推送消息,不再需要客户端轮询
  • 低延迟:相比HTTP轮询,大大降低通信延迟
  • 高效传输:头部信息小,通信效率高

二、准备工作

在build.gradle文件中添加依赖(使用OkHttp)

implementation("com.squareup.okhttp3:okhttp:4.12.0")

三、基础实现

接下来是在Android移动开发中实现WebSocket通信的简单例子

1.创建管理数据获取的Model层

import com.example.websocketinmvp.contract.WebSocketContract
 import okhttp3.OkHttpClient
 import okhttp3.WebSocket
 import okhttp3.WebSocketListener
 import java.util.concurrent.TimeUnit
 import kotlin.getValue
 ​
 class WebSocketModel : WebSocketContract.Model {
 ​
     private var webSocket : WebSocket?=null
     private val client by lazy {
         OkHttpClient.Builder()
             .pingInterval(30, TimeUnit.SECONDS)
             .build()
     }
 ​
     override fun connect(listener: WebSocketListener) {
         val request = okhttp3.Request.Builder()
             .url("wss://echo.websocket.events") // Replace with your WebSocket URL
             .build()
 ​
         webSocket = client.newWebSocket(request, listener)
     }
 ​
     override fun disconnect() {
         webSocket?.close(1000, "Normal closure")
         client.dispatcher.executorService.shutdown()
         webSocket = null
     }
 ​
     override fun sendMessage(message: String): Boolean {
         return webSocket?.send(message) ?: false
     }
 }

2.创建WebSocket管理器

import android.util.Log
 import com.example.websocketinmvp.contract.WebSocketContract
 import okhttp3.WebSocket
 import okhttp3.WebSocketListener
 ​
 class WebSocketPresenter(
     private val view : WebSocketContract.View,
     private val model : WebSocketContract.Model
 ) : WebSocketContract.Presenter {
 ​
     private val webSocketListener = object : WebSocketListener() {
         override fun onOpen(webSocket: WebSocket, response: okhttp3.Response) {
             view.showConnectionStatus(true)
             view.showMessage("Connected to WebSocket server")
         }
 ​
         override fun onMessage(webSocket: WebSocket, text: String) {
             view.showMessage("Sent $text")
             view.showMessage("Received $text")
             Log.d("WebSocket", text)
         }
 ​
         override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
             view.showMessage("Closing: $code / $reason")
         }
 ​
         override fun onFailure(webSocket: WebSocket, t: Throwable, response: okhttp3.Response?) {
             view.showError("Error: ${t.message}")
             view.showConnectionStatus(false)
         }
 ​
         override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
             view.showConnectionStatus(false)
             view.showMessage("Closing: $code / $reason")
         }
     }
 ​
     override fun connect() {
         model.connect(webSocketListener)
     }
 ​
     override fun disconnect() {
         model.disconnect()
     }
 ​
     override fun sendMessage(message: String) {
         if (message.isNotEmpty()) {
             val success = model.sendMessage(message)
             if (!success) {
                 view.showError("Failed to send message - not connected")
             }
         }
     }
 ​
     override fun onDestroy() {
         disconnect()
     }
 }

3.在Activity中绑定UI

import android.os.Bundle
 import androidx.appcompat.app.AppCompatActivity
 import com.example.websocketinmvp.contract.WebSocketContract
 import com.example.websocketinmvp.databinding.ActivityWebsocketBinding
 import com.example.websocketinmvp.model.WebSocketModel
 import com.example.websocketinmvp.presenter.WebSocketPresenter
 ​
 class WebSocketActivity : AppCompatActivity(), WebSocketContract.View {
 ​
     private lateinit var binding : ActivityWebsocketBinding
     private lateinit var presenter: WebSocketContract.Presenter
 ​
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         binding = ActivityWebsocketBinding.inflate(layoutInflater)
         setContentView(binding.root)
         presenter = WebSocketPresenter(this, WebSocketModel())
         setupUI()
     }
 ​
     private fun setupUI() {
         binding.connectButton.setOnClickListener {
             presenter.connect()
         }
 ​
         binding.disconnectButton.setOnClickListener {
             presenter.disconnect()
         }
 ​
         binding.sendButton.setOnClickListener {
             val message = binding.messageEditText.text.toString()
             presenter.sendMessage(message)
             binding.messageEditText.text.clear()
         }
     }
 ​
     override fun showConnectionStatus(connected: Boolean) {
         runOnUiThread {
             binding.connectionStatus.text = if(connected) "Connected" else "Disconnected"
             binding.connectButton.isEnabled = !connected
             binding.disconnectButton.isEnabled = connected
             binding.sendButton.isEnabled = connected
         }
     }
 ​
     override fun showMessage(message: String) {
         runOnUiThread {
             binding.messagesTextView.append("$message\n")
         }
     }
 ​
     override fun showError(error: String) {
         runOnUiThread {
             binding.messagesTextView.append("Error: $error\n")
         }
     }
 ​
     override fun onDestroy() {
         super.onDestroy()
         presenter.onDestroy()
     }
 }

最后附上一个管理M层、V层和P层的接口类

import okhttp3.WebSocketListener
 ​
 ​
 interface WebSocketContract {
 ​
     interface View {
         fun showConnectionStatus(connected: Boolean)
         fun showMessage(message: String)
         fun showError(error: String)
     }
 ​
     interface Presenter {
         fun connect()
         fun disconnect()
         fun sendMessage(message: String)
         fun onDestroy()
     }
 ​
     interface Model {
         fun connect(listener: WebSocketListener)
         fun disconnect()
         fun sendMessage(message: String): Boolean
     }
 }
收藏举报
Level 1
0
帖子
0
粉丝
0
获赞