Introdução ao WebSocket em Kotlin: da teoria à prática em tempo real
As aplicações web modernas exigem cada vez mais troca instantânea de dados entre cliente e servidor. O protocolo HTTP tradicional, que funciona no princípio de "requisição-resposta", não é adequado para tarefas onde as informações devem chegar em tempo real: chats online, cotações de bolsa, jogos multiplayer ou notificações push. É aqui que o WebSocket entra em ação — um protocolo que fornece uma conexão bidirecional permanente.
Kotlin, sendo uma linguagem moderna para JVM, JavaScript e Native, oferece excelentes ferramentas para trabalhar com WebSocket. Neste artigo, vamos explorar como criar aplicações em tempo real em Kotlin usando a biblioteca Ktor — um framework popular para construir servidores e clientes assíncronos. Você aprenderá como configurar uma conexão WebSocket, enviar e receber mensagens, tratar erros e construir soluções escaláveis.
1. Fundamentos do WebSocket: por que Kotlin e Ktor?
WebSocket é um protocolo que, após estabelecer uma conexão através de um handshake HTTP, transforma o canal em um modo bidirecional permanente. Ao contrário do HTTP, o servidor pode iniciar o envio de dados sem uma requisição do cliente. Isso é ideal para cenários em tempo real.
Kotlin em conjunto com Ktor oferece:
- Assincronicidade — as corrotinas do Kotlin permitem processar milhares de conexões simultâneas sem bloquear threads.
- Multiplataforma — o mesmo código pode funcionar em JVM, JavaScript e Native.
- Concisão — mínimo de boilerplate, máximo de expressividade.
- Segurança — suporte embutido para SSL/TLS, autenticação e CORS.
Vamos passar à prática e criar um servidor e cliente WebSocket simples em Kotlin.
2. Criando um servidor WebSocket em Kotlin com Ktor
2.1. Configuração do projeto
Para começar, crie um novo projeto Gradle ou Maven. Adicione as dependências do Ktor no 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. Implementação do servidor
Vamos criar um servidor WebSocket que aceita conexões, lê mensagens e responde a elas. O exemplo abaixo usa a biblioteca Ktor com corrotinas:
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("Bem-vindo ao chat!")) for (frame in incoming) { if (frame is Frame.Text) { val text = frame.readText() println("Recebido: $text") send(Frame.Text("Eco: $text")) } } } }.start(wait = true)}Aqui nós:
- Instalamos o plugin
WebSockets. - Definimos o endpoint
/chat. - Na corrotina, processamos os frames recebidos e enviamos uma resposta de eco.
2.3. Tratamento de erros e fechamento da conexão
Em aplicações reais, é importante tratar corretamente as desconexões. Vamos adicionar tratamento de exceções e fechamento de sessão:
webSocket("/chat") { try { send(Frame.Text("Conexão estabelecida")) for (frame in incoming) { when (frame) { is Frame.Text -> { val text = frame.readText() if (text.equals("exit", ignoreCase = true)) { cl