WebSocket библиотека Kotlin: ktor-client-websockets
В современной веб-разработке всё чаще требуется обмен данными в реальном времени: онлайн-чаты, уведомления, биржевые котировки, многопользовательские игры. Для Kotlin одной из самых мощных и нативных библиотек для работы с протоколом WebSocket является ktor-client-websockets — часть экосистемы Ktor (Kotlin HTTP-клиент).
В этой статье мы подробно разберём, как подключить и использовать WebSocket в Kotlin с помощью Ktor. Вы узнаете, как установить библиотеку, установить соединение, отправлять и получать сообщения, а также обрабатывать ошибки и закрытие соединения.
Что такое WebSocket и зачем он нужен?
WebSocket — это протокол, который обеспечивает постоянное двустороннее соединение между клиентом (например, Android-приложением или сервером) и сервером. В отличие от HTTP, где клиент каждый раз инициирует запрос, WebSocket позволяет серверу отправлять данные клиенту мгновенно, как только они появляются. Это идеально для:
- чатов и мессенджеров;
- уведомлений и ленты событий;
- игр и коллаборативных редакторов;
- финансовых тикеров и трейдинга.
Установка библиотеки ktor-client-websockets
Для начала добавьте зависимость в ваш build.gradle.kts (проект на Kotlin/JVM или Kotlin Multiplatform).
// build.gradle.kts
dependencies {
implementation("io.ktor:ktor-client-core:2.3.7")
implementation("io.ktor:ktor-client-cio:2.3.7") // или другой движок
implementation("io.ktor:ktor-client-websockets:2.3.7")
}
Если вы используете Kotlin Multiplatform, убедитесь, что добавили модуль для каждой платформы (например, ktor-client-okhttp для Android).
Создание WebSocket клиента
Основной класс для работы с WebSocket — HttpClient с плагином WebSockets. Рассмотрим простейший пример подключения к WebSocket-серверу.
import io.ktor.client.*
import io.ktor.client.plugins.websocket.*
import io.ktor.websocket.*
suspend fun main() {
val client = HttpClient {
install(WebSockets)
}
client.webSocket("ws://echo.websocket.org") {
// Отправляем сообщение
send(Frame.Text("Привет, WebSocket!"))
// Получаем ответ
for (frame in incoming) {
when (frame) {
is Frame.Text -> {
println("Получено: ${frame.readText()}")
}
else -> println("Другой тип фрейма: $frame")
}
}
}
client.close()
}
В этом коде мы:
- Создаём HTTP-клиент с поддержкой WebSocket.
- Устанавливаем соединение с тестовым сервером
ws://echo.websocket.org. - Отправляем текстовое сообщение.
- Читаем входящие фреймы и выводим их в консоль.
Обработка ошибок и закрытие соединения
В реальных приложениях важно корректно обрабатывать исключения и закрывать соединение. Используйте try-catch и finally.
import io.ktor.client.*
import io.ktor.client.plugins.websocket.*
import io.ktor.websocket.*
import kotlinx.coroutines.*
suspend fun main() = coroutineScope {
val client = HttpClient {
install(WebSockets)
}
try {
client.webSocket("ws://your-server.com/ws") {
// Отправка
send(Frame.Text("Пинг"))
// Приём с таймаутом
withTimeout(5000) {
for (frame in incoming) {
if (frame is Frame.Text) {
println("Ответ: ${frame.readText()}")
}
}
}
}
} catch (e: Exception) {
println("Ошибка WebSocket: ${e.message}")
} finally {
client.close()
}
}
Продвинутые возможности: фильтрация фреймов и пинг/понг
Библиотека поддерживает не только текстовые, но и бинарные фреймы (Frame.Binary), а также пинг-понг для поддержания соединения. Вы можете фильтровать типы фреймов:
client.webSocket("ws://example.com/ws") { for (frame in incoming) { when (frame) { is Frame.Text -> { println("Текст: ${frame.readText()}") } is Frame.Binary -> { println("Бинарные данные: ${frame.readBytes().size} байт") } is Frame.Ping -> { println("Пинг получен, отправляем понг") send(Frame.Pong(frame.data)) } else -> { println("Другой фрейм: $frame") } } } }Также в библиотеке
Рекомендаций