Relay WebSocket
O middleware de relay WebSocket atualiza conexões HTTP para WebSocket e retransmite mensagens para um processo alvo.
Como Funciona
- Handler HTTP define header
X-WS-Relaycom PID do processo alvo - Middleware atualiza conexão para WebSocket
- Relay anexa ao processo alvo e o monitora
- Mensagens fluem bidirecionalmente entre cliente e processo
Semântica de Processo
Conexões WebSocket são processos completos com seu próprio PID. Elas se integram com o sistema de processos:
- Endereçável - Qualquer processo pode enviar mensagens para um PID WebSocket
- Monitorável - Processos podem monitorar conexões WebSocket para eventos de saída
- Linkável - Conexões WebSocket podem ser vinculadas a outros processos
- Eventos EXIT - Quando a conexão fecha, monitores recebem notificações de saída
-- Monitora uma conexão WebSocket de outro processo
process.monitor(websocket_pid)
-- Envia mensagem para cliente WebSocket de qualquer processo
process.send(websocket_pid, "ws.send", {type = "text", data = "hello"})
Transferência de Conexão
Conexões podem ser transferidas para um processo diferente enviando uma mensagem de controle:
process.send(websocket_pid, "ws.control", {
target_pid = new_process_pid,
message_topic = "ws.message"
})
Configuração
Adicione como middleware pós-match em um roteador:
- name: ws_router
kind: http.router
meta:
server: gateway
prefix: /ws
post_middleware:
- websocket_relay
post_options:
wsrelay.allowed.origins: "https://app.example.com"
| Opção | Descrição |
|---|---|
wsrelay.allowed.origins |
Origens permitidas separadas por vírgula |
Configuração do Handler
O handler HTTP cria um processo e configura o relay:
local http = require("http")
local json = require("json")
local function handler()
local req = http.request()
local res = http.response()
-- Cria processo handler
local pid = process.spawn("app.ws:handler", "app:processes")
-- Configura relay
res:header("X-WS-Relay", json.encode({
target_pid = tostring(pid),
message_topic = "ws.message",
heartbeat_interval = "30s",
metadata = {
user_id = req:query("user_id")
}
}))
end
Campos de Configuração do Relay
| Campo | Tipo | Padrão | Descrição |
|---|---|---|---|
target_pid |
string | obrigatório | PID do processo para receber mensagens |
message_topic |
string | ws.message |
Tópico para mensagens do cliente |
heartbeat_interval |
duration | - | Frequência de heartbeat (ex: 30s) |
metadata |
object | - | Anexado a todas as mensagens |
Tópicos de Mensagens
O relay envia estas mensagens para o processo alvo:
| Tópico | Quando | Payload |
|---|---|---|
ws.join |
Cliente conecta | client_pid, metadata |
ws.message |
Cliente envia mensagem | client_pid, type, data, metadata |
ws.heartbeat |
Periódico (se configurado) | client_pid, uptime, message_count |
ws.leave |
Cliente desconecta | client_pid, reason, metadata |
Recebendo Mensagens
local json = require("json")
local function handler()
local inbox = process.inbox()
while true do
local msg, ok = inbox:receive()
if not ok then break end
local topic = msg:topic()
local data = msg:payload():data()
if topic == "ws.join" then
-- Cliente conectou
local client_pid = data.client_pid
elseif topic == "ws.message" then
-- Trata mensagem do cliente
local content = json.decode(data.data)
handle_message(data.client_pid, content)
elseif topic == "ws.leave" then
-- Cliente desconectou
cleanup(data.client_pid)
end
end
end
Enviando para o Cliente
Envia mensagens de volta usando o PID do cliente:
-- Envia mensagem de texto
process.send(client_pid, "ws.send", {
type = "text",
data = json.encode({event = "update", value = 42})
})
-- Envia binário
process.send(client_pid, "ws.send", {
type = "binary",
data = binary_content
})
-- Fecha conexão
process.send(client_pid, "ws.close", {
code = 1000,
reason = "Sessão encerrada"
})
Broadcast
Rastreie PIDs de clientes para broadcast para múltiplos clientes:
local clients = {}
-- No join
clients[client_pid] = true
-- No leave
clients[client_pid] = nil
-- Broadcast
local function broadcast(message)
local data = json.encode(message)
for pid, _ in pairs(clients) do
process.send(pid, "ws.send", {type = "text", data = data})
end
end
Veja Também
- Middleware - Configuração de middleware
- Processo - Mensagens de processo
- Cliente WebSocket - Conexões WebSocket de saída