前言

在之前的文章中,咱们知道了 WebSocket 是一种全双工通讯协议。本文将介绍如安在 Android 端运用 WebSocket 进行双向通讯。其间包含创立 WebSocket 目标、发送和接纳数据等操作。

创立 WebSocket 目标

要运用 WebSocket 目标,咱们需要先创立一个 WebSocket 客户端目标。在 Android 中,咱们能够运用 OkHttp 库来创立 WebSocket 客户端目标。在开始之前,咱们先在 Gradle 文件中增加 OkHttp 库的依赖:

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

在代码中创立 WebSocket 客户端目标的示例如下:

import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.WebSocket
//创立一个 OkHttpClient 目标
val client = OkHttpClient()
//恳求体
val request = Request.Builder()
    .url("wss://example.com/websocket")
    .build()
//经过上面的 client 创立 webSocket
val webSocket = client.newWebSocket(request, object : WebSocketListener() {
    override fun onOpen(webSocket: WebSocket, response: Response) {
        // WebSocket 衔接树立成功
    }
    override fun onMessage(webSocket: WebSocket, text: String) {
        // 收到 WebSocket 服务器发送的文本音讯
    }
    override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
        // 收到 WebSocket 服务器发送的二进制音讯
    }
    override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
        // WebSocket 衔接失利
    }
    override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
        // WebSocket 衔接封闭
    }
})

在上面的示例中,咱们首要创立了一个 OkHttpClient 目标,然后运用 Request.Builder 类构建了一个 WebSocket 恳求目标,并指定了 WebSocket 服务器的地址。接着,咱们调用 OkHttpClient 目标的 newWebSocket() 办法,传入 WebSocket 恳求目标和一个 WebSocketListener 目标,来创立一个 WebSocket 客户端目标。在 WebSocketListener 目标中,咱们能够完成 WebSocket 衔接树立、收到音讯、衔接失利、衔接封闭等事情的回调函数。

发送和接纳数据

WebSocket 客户端目标创立成功后,咱们能够经过 send() 办法来向 WebSocket 服务器发送音讯。在 WebSocketListener 目标中的 onMessage() 办法中,咱们能够接纳到 WebSocket 服务器发送的音讯。下面是一个发送和接纳文本音讯的示例:

val message = "Hello, WebSocket!"
webSocket.send(message)
// 在 onMessage() 办法中接纳音讯
override fun onMessage(webSocket: WebSocket, text: String) {
    Log.d(TAG, "Received message: $text")
}

假如要发送二进制音讯,能够运用 send() 同名的另一个重载办法:

val message = ByteString.encodeUtf8("Hello, WebSocket!")
webSocket.send(message)
// 在 onMessage() 办法中接纳音讯
override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
    Log.d(TAG, "Received message: ${bytes.utf8()}")
}

封闭 WebSocket 衔接

当 WebSocket 衔接不再需要时,咱们能够调用 WebSocket 目标的 close() 办法来封闭衔接,及时释放资源,避免引起内存走漏。在 WebSocketListener 目标中的 onclose() 办法中,咱们能够接纳到 WebSocket 封闭事情,能够在该事情中履行一些清理操作。下面是一个封闭 WebSocket 衔接的示例:

webSocket.close(NORMAL_CLOSURE_STATUS, "WebSocket connection closed")
// 在 onClosed() 办法中接纳封闭事情
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
    Log.d(TAG, "WebSocket connection closed: $reason")
}

在上面的示例中,咱们调用 WebSocket 目标的 close() 办法来封闭衔接,传入一个封闭代码和封闭原因。在 WebSocketListener 目标中的 onClosed() 办法中,咱们能够接纳到 WebSocket 封闭事情,并处理封闭原因。

完好示例

下面是一个完好的 WebSocket 通讯示例,包含创立 WebSocket 目标、发送和接纳音讯、封闭衔接等操作:

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.*
import okio.ByteString
class MainActivity : AppCompatActivity() {
    private lateinit var webSocket: WebSocket
    companion object {
        private const val TAG = "WebSocketDemo"
        private const val NORMAL_CLOSURE_STATUS = 1000
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val client = OkHttpClient()
        val request = Request.Builder()
            .url("wss://echo.websocket.org")
            .build()
        webSocket = client.newWebSocket(request, object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket, response: Response) {
                webSocket.send("Hello, WebSocket!")
            }
            override fun onMessage(webSocket: WebSocket, text: String) {
                Log.d(TAG, "Received message: $text")
            }
            override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
                Log.d(TAG, "Received message: ${bytes.utf8()}")
            }
            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                Log.e(TAG, "WebSocket connection failed", t)
            }
            override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
                Log.d(TAG, "WebSocket connection closed: $reason")
            }
        })
        btn_send.setOnClickListener {
            val message = et_message.text.toString()
            webSocket.send(message)
        }
        btn_close.setOnClickListener {
            webSocket.close(NORMAL_CLOSURE_STATUS, "WebSocket connection closed")
        }
    }
}

在上面的示例中,咱们在 Activity 的 onCreate() 办法中创立了 WebSocket 客户端目标,并经过按钮的点击事情来发送音讯和封闭衔接。咱们运用了 Echo WebSocket 服务器来测试 WebSocket 通讯。在实践开发中,咱们能够运用自己的 WebSocket 服务器来进行通讯。

总结

WebSocket 是一种全双工通讯协议,能够在 Android 应用程序中运用 WebSocket 目标完成双向通讯。经过 OkHttp 库,咱们能够创立 WebSocket 客户端目标,运用 send() 办法发送音讯,运用 WebSocketListener 回调接口处理事情。在实践应用中,咱们能够运用 WebSocket 协议来完成实时交互、即时通讯等功能,提升 Android 应用程序的用户体验和竞争力。