Kotlin WebSocket 库:Ktor WebSocket
WebSocket 是一种协议,可在客户端和服务器之间提供持久的双向连接。在 Kotlin 生态系统中,用于处理 WebSocket 最强大且最流行的库之一是 Ktor——由 JetBrains 公司创建的异步框架。Ktor 在服务器端和客户端都提供了对 WebSocket 的全面支持,使您可以轻松创建实时应用程序:聊天、通知、在线游戏、数据追踪器等。
在本文中,我们将详细介绍如何使用 Ktor 在 Kotlin 中使用 WebSocket。您将学习如何配置依赖项、创建 WebSocket 服务器和客户端、发送和接收消息,以及处理错误和连接关闭。
安装与配置
首先,将必要的依赖项添加到 build.gradle.kts(或 build.gradle)文件中。如果您使用 Gradle,请添加以下模块:
// build.gradle.ktsdependencies { // 服务器端 implementation("io.ktor:ktor-server-core:2.3.0") implementation("io.ktor:ktor-server-netty:2.3.0") implementation("io.ktor:ktor-server-websockets:2.3.0")
// 客户端 implementation("io.ktor:ktor-client-core:2.3.0") implementation("io.ktor:ktor-client-cio:2.3.0") implementation("io.ktor:ktor-client-websockets:2.3.0")}对于 Maven,请使用类似的构件。所有 2.x.x 版本的 Ktor 模块都支持 Kotlin 协程,并可在 JVM、Android、iOS 和其他平台上运行。
在 Ktor 上创建 WebSocket 服务器
让我们编写一个简单的回显服务器,它接收来自客户端的消息并将其发送回去。服务器将监听 8080 端口。
import io.ktor.server.engine.*import io.ktor.server.netty.*import io.ktor.server.websocket.*import io.ktor.websocket.*import kotlinx.coroutines.*
fun main() { embeddedServer(Netty, port = 8080) { install(WebSockets) routing { webSocket("/chat") { send("欢迎加入聊天!") for (frame in incoming) { if (frame is Frame.Text) { val text = frame.readText() println("收到: $text") send("回显: $text") } } } } }.start(wait = true)}在此示例中:
install(WebSockets)— 将 WebSocket 插件连接到服务器。webSocket("/chat")— 定义用于连接的端点。send()— 向客户端发送消息。incoming— 接收来自客户端帧的通道。- 帧可以是文本 (
Frame.Text)、二进制 (Frame.Binary) 或控制帧。
在 Ktor 上创建 WebSocket 客户端
现在让我们编写一个客户端,它连接到我们的服务器,发送问候语并读取响应。
import io.ktor.client.*import io.ktor.client.engine.cio.*import io.ktor.client.plugins.websocket.*import io.ktor.websocket.*import kotlinx.coroutines.*
suspend fun main() { val client = HttpClient(CIO) { install(WebSockets) }
client.webSocket("ws://localhost:8080/chat") { // 读取问候语 val welcome = incoming.receive() as Frame.Text println("服务器: ${welcome.readText()}")
// 发送消息 send(Frame.Text("你好,服务器!"))
// 等待回显响应 val response = incoming.receive() as Frame.Text println("服务器: ${response.readText()}")
// 关闭连接 close() }
client.close()}客户端使用双