WebSocket на Kotlin: создаём real-time приложения

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в WebSocket на Kotlin: от теории к real-time практике

Современные веб-приложения всё чаще требуют мгновенного обмена данными между клиентом и сервером. Традиционный HTTP-протокол, работающий по принципу «запрос-ответ», не подходит для задач, где информация должна приходить в реальном времени: онлайн-чаты, биржевые котировки, многопользовательские игры или push-уведомления. Именно здесь на помощь приходит WebSocket — протокол, обеспечивающий постоянное двустороннее соединение.

Kotlin, будучи современным языком для JVM, JavaScript и Native, предоставляет отличные инструменты для работы с WebSocket. В этой статье мы разберём, как создавать real-time приложения на Kotlin с использованием библиотеки Ktor — популярного фреймворка для построения асинхронных серверов и клиентов. Вы узнаете, как настроить WebSocket-соединение, отправлять и получать сообщения, обрабатывать ошибки и строить масштабируемые решения.

1. Основы WebSocket: почему Kotlin и Ktor?

WebSocket — это протокол, который после установки соединения через HTTP-рукопожатие переводит канал в постоянный двусторонний режим. В отличие от HTTP, сервер может инициировать отправку данных без запроса клиента. Это идеально для real-time сценариев.

Kotlin в паре с Ktor предлагает:

  • Асинхронность — корутины Kotlin позволяют обрабатывать тысячи одновременных соединений без блокировки потоков.
  • Кроссплатформенность — один и тот же код может работать на JVM, JavaScript и Native.
  • Лаконичность — минимум бойлерплейта, максимум выразительности.
  • Безопасность — встроенная поддержка SSL/TLS, аутентификации и CORS.

Давайте перейдём к практике и создадим простой WebSocket-сервер и клиент на Kotlin.

2. Создание WebSocket-сервера на Kotlin с Ktor

2.1. Настройка проекта

Для начала создайте новый проект Gradle или Maven. Добавьте зависимости Ktor в build.gradle.kts:

dependencies {
    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("ch.qos.logback:logback-classic:1.4.11")
}

2.2. Реализация сервера

Создадим WebSocket-сервер, который принимает соединения, читает сообщения и отвечает на них. Пример ниже использует библиотеку Ktor с корутинами:

import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.websocket.*
import io.ktor.websocket.*
import kotlinx.coroutines.delay

fun main() {
    embeddedServer(Netty, port = 8080) {
        install(WebSockets)
        webSocket("/chat") {
            send(Frame.Text("Добро пожаловать в чат!"))
            for (frame in incoming) {
                if (frame is Frame.Text) {
                    val text = frame.readText()
                    println("Получено: $text")
                    send(Frame.Text("Эхо: $text"))
                }
            }
        }
    }.start(wait = true)
}

Здесь мы:

  • Устанавливаем плагин WebSockets.
  • Определяем endpoint /chat.
  • В корутине обрабатываем входящие фреймы и отправляем эхо-ответ.

2.3. Обработка ошибок и закрытие соединения

В реальных приложениях важно корректно обрабатывать разрывы связи. Добавим обработку исключений и закрытие сессии:

webSocket("/chat") {
    try {
        send(Frame.Text("Соединение установлено"))
        for (frame in incoming) {
            when (frame) {
                is Frame.Text -> {
                    val text = frame.readText()
                    if (text.equals("exit", ignoreCase = true)) {
                        close(CloseReason(CloseReason.Codes.NORMAL, "Пользователь вышел"))
                        break
                    }
                    send(Frame.Text("Вы сказали: $text"))
                }
                is Frame.Close -> {
                    println("Клиент закрыл соединение")
                }
                else -> {}
            }
        }
    } catch (e: Exception) {
        println("Ошибка: ${e.message}")
    } finally {
        println("Соединение завершено")
    }
}

3. WebSocket-клиент на Kotlin: подключаемся к серверу

Теперь создадим клиент, который будет подключаться к нашему серверу. Ktor предоставляет удобный клиентский API для WebSocket.

3.1. Настройка клиента

Добавьте зависимости в build.gradle.kts:

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")

3.2. Реализация клиента

import io.ktor.client.*
import io.ktor.client.plugins.websocket.*
import io.ktor.websocket.*
import kotlinx.coroutines.*

suspend fun main() {
    val client = HttpClient {
        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()}")

        // Закрываем соединение
        send(Frame.Text("exit"))
    }

    client.close()
}

Этот клиент подключается к серверу, получает приветствие, отправляет сообщение и корректно завершает сессию.

4. Real-time приложение: онлайн-чат

Давайте создадим полноценный многопользовательский чат, где все подключенные клиенты видят сообщения друг друга.

4.1. Серверная часть чата

Для этого нам потребуется хранить список активных сессий и рассылать сообщения всем участникам:

import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.websocket.*
import io.ktor.websocket.*
import kotlinx.coroutines.channels.                

Блоги

Рекомендаций по книгам