WebSocket на Kotlin: real-time приложения от А до Я

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

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

Начать курс

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

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

Kotlin, благодаря своей лаконичности, безопасности и полной совместимости с Java-экосистемой, является отличным выбором для разработки серверной части. В качестве основного фреймворка мы будем использовать Ktor — современный асинхронный фреймворк для Kotlin, который имеет встроенную поддержку WebSocket.

Что такое WebSocket и зачем он нужен?

WebSocket — это протокол, обеспечивающий полнодуплексную (двустороннюю) связь между клиентом и сервером через одно постоянное TCP-соединение. В отличие от HTTP, где инициатором запроса всегда выступает клиент, WebSocket позволяет серверу самостоятельно отправлять данные клиенту в любой момент.

Основные преимущества WebSocket:

  • Низкая задержка: Нет накладных расходов на установку нового соединения для каждого сообщения.
  • Эффективность: Минимальный служебный трафик (всего 2 байта на сообщение после установки соединения).
  • Постоянное соединение: Сервер может отправлять данные в реальном времени без опроса со стороны клиента.

WebSocket идеально подходит для:

  • Онлайн-чатов и мессенджеров
  • Совместного редактирования документов
  • Биржевых и финансовых котировок
  • Многопользовательских игр
  • Push-уведомлений и мониторинга

Настройка проекта Ktor для WebSocket

Прежде чем писать код, необходимо настроить проект. Проще всего это сделать через IntelliJ IDEA с плагином Ktor, или вручную через Gradle.

Шаг 1: Создание проекта

Создайте новый Gradle-проект с Kotlin (JVM). В файл build.gradle.kts добавьте следующие зависимости:

plugins {
    kotlin("jvm") version "1.9.22"
    id("io.ktor.plugin") version "2.3.7"
}

application {
    mainClass.set("ApplicationKt")
}

dependencies {
    implementation("io.ktor:ktor-server-core:2.3.7")
    implementation("io.ktor:ktor-server-netty:2.3.7")
    implementation("io.ktor:ktor-server-websockets:2.3.7")
    implementation("ch.qos.logback:logback-classic:1.4.14")
}

Шаг 2: Базовая структура сервера

Создадим файл Application.kt и напишем минимальный WebSocket-сервер:

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("Добро пожаловать в чат!")
            
            for (frame in incoming) {
                if (frame is Frame.Text) {
                    val text = frame.readText()
                    send("Вы написали: $text")
                    println("Получено: $text")
                }
            }
        }
    }.start(wait = true)
}

Этот код запускает сервер на порту 8080, который принимает WebSocket-соединения по адресу /chat. При подключении клиент получает приветственное сообщение, а затем сервер отвечает на каждое текстовое сообщение эхом.

Создание продвинутого чата с комнатами

Теперь перейдём к более сложному примеру — многопользовательскому чату с поддержкой комнат. Мы реализуем функционал, где пользователи могут подключаться к разным комнатам и общаться внутри них.

Архитектура чата

Нам понадобится:

  • Коллекция комнат: Хранит список активных комнат и их участников.
  • Обработка подключений: Присоединение и выход из комнаты.
  • Расслылка сообщений: Отправка сообщений всем участникам комнаты.

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

import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.websocket.*
import io.ktor.websocket.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

data class Room(val name: String, val clients: MutableSet<WebSocketSession> = mutableSetOf())

class ChatServer {
    private val rooms = mutableMapOf<String, Room>()
    
    fun joinRoom(roomName: String, session: WebSocketSession) {
        val room = rooms.getOrPut(roomName) { Room(roomName) }
        room.clients.add(session)
        broadcast(roomName, "Пользователь присоединился к комнате $roomName")
    }
    
    fun leaveRoom(roomName: String, session: WebSocketSession) {
        val room = rooms[roomName] ?: return
        room.clients.remove(session)
        broadcast(roomName, "Пользователь покинул комнату $roomName")
        if (room.clients.isEmpty()) {
            rooms.remove(roomName)
        }
    }
    
    suspend fun broadcast(roomName: String, message: String) {
        val room = rooms[roomName] ?: return
        room.clients.forEach { client ->
            try {
                client.send(Frame.Text(message))
            } catch (e: Exception) {
                room.clients.remove(client)
            }
        }
    }
}

fun main() {
    val chatServer = ChatServer()
    
    embeddedServer(Netty, port = 8080) {
        install(WebSockets)
        
        webSocket("/chat/{roomName}") {
            val roomName = call.parameters["roomName"] ?: "general"
            chatServer.joinRoom(roomName, this)
            
            try {
                for (frame in incoming) {
                    if (frame is Frame.Text) {
                        val text = frame.readText()
                        chat                

Блоги

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