Skip to content
mobius1qwe edited this page Nov 11, 2026 · 1 revision

Home > Hubs 🚧

Hubs (chamadas e eventos sobre WebSocket)

Important

Em desenvolvimento (2.0). Ainda não está numa versão lançada e pode mudar.

Vale para a 2.0 · Delphi XE em diante e Lazarus/FPC 3.2 em diante · Nível: intermediário

Em uma frase: um hub é uma rota WebSocket com um protocolo pronto: o cliente chama métodos do servidor e recebe a resposta, e o servidor emite eventos para todos, para uma conexão, para um usuário ou para um grupo, inclusive em vários servidores ao mesmo tempo.

Você vai precisar: o pacote RALModuleWebSocketPackage (TRALHubModule na paleta RAL - Modules, TRALHubClient na RAL - Client); para vários servidores, também o RALModuleWebSocketMQTTPackage e um broker MQTT (o TRALMQTTBroker do próprio RAL serve).

Servidor

Hub := TRALHubModule.Create(Self);
Hub.Server := RALIndyServer1;
Hub.Path := '/chat';                 // a rota WebSocket
Hub.ClientGroups := True;            // o cliente pode entrar e sair de grupos
Hub.Methods.AddMethod('Chat.Send', OnChatSend);

procedure TForm1.OnChatSend(ACall: TRALHubCall);
begin
  // args: [sala, texto]
  ACall.Hub.EmitToGroup(ACall.ArgAsString(0), 'Chat.Message',
    '[' + RALHubQuote(ACall.ArgAsString(1)) + ',' + RALHubQuote(ACall.Connection.User) + ']');
  ACall.ReturnJSON('true');
end;
  • Methods é uma coleção do Object Inspector (nome + OnInvoke); OnInvoke do módulo atende o que não está nela.
  • No método: ACall.Arg(i) (JSON), ArgAsString(i), ArgCount, Connection; responde com ReturnJSON, ReturnText ou Fail(mensagem). Uma exceção vira erro para o cliente.
  • Emit(evento, args, escopo, chave), EmitToGroup, EmitToUser, EmitExcept; os argumentos são um array JSON em texto ('[1,"a"]').
  • OnConnect/OnDisconnect; Deflate, KeepAliveInterval, MaxMessageSize, AllowedOrigins como na rota WebSocket.

Navegador: ralhub.js

O módulo serve o cliente JavaScript em <Domain>/ralhub.js; nada para copiar.

<script src="/ralhub.js"></script>
<script>
  const hub = new RalHub("/chat");
  hub.on("Chat.Message", (texto, autor) => console.log(autor + ": " + texto));
  hub.on("$close", code => console.log("caiu", code));   // reconecta sozinho
  hub.start()
    .then(() => hub.join("geral"))
    .then(() => hub.invoke("Chat.Send", "geral", "olá"));
</script>

invoke devolve uma Promise (resultado ou erro); send chama sem esperar resposta; stop() encerra sem reconectar. Opções: new RalHub(url, {reconnect, reconnectDelay, reconnectMaxDelay, timeout, protocols}).

Delphi e Lazarus: TRALHubClient

HubClient := TRALHubClient.Create(nil);
HubClient.URL := 'ws://localhost:8090/chat';
HubClient.OnHubEvent := OnEvento;     // (ASender, ATarget, AArgs)
HubClient.Connect;
HubClient.JoinGroup('geral');
Resultado := HubClient.Invoke('Chat.Send', '["geral","olá"]');   // espera InvokeTimeout

É um TRALWebSocketClient: herda TLS, proxy, autenticação e reconexão. Invoke pode ser chamado da thread principal mesmo com SyncEvents (ele deixa os eventos rodarem enquanto espera).

Vários servidores: o backplane

Atrás de um balanceador, cada usuário fica num servidor. Com um TRALHubMQTTBackplane ligado ao hub, todo Emit vai também para os outros servidores pelo broker, e cada um entrega às suas conexões:

Mqtt := TRALMQTTClient.Create(Self);
Mqtt.Host := 'broker.interno';
Mqtt.Port := 1883;
Backplane := TRALHubMQTTBackplane.Create(Self);
Backplane.Client := Mqtt;
Backplane.Hub := Hub;                 // o tópico é ralhub/<nome do hub>

Ao ativar o servidor o cliente conecta (se não estava) e assina o tópico; ao parar, sai. Channel muda o nome do tópico (os servidores do mesmo cluster usam o mesmo). O EmitExcept e as respostas de Invoke ficam só no servidor local.

O protocolo (para outros clientes)

Uma mensagem de texto, um objeto JSON:

sentido mensagem
cliente → servidor {"t":"invoke","id":1,"target":"Chat.Send","args":["geral","olá"]} (sem id: ninguém espera a resposta)
servidor → cliente {"t":"result","id":1,"result":true} ou {"t":"error","id":1,"error":"mensagem"}
servidor → cliente {"t":"event","target":"Chat.Message","args":["olá","ana"]}

Com ClientGroups, os alvos hub.join e hub.leave (args: [grupo]) põem e tiram o próprio cliente de um grupo.

Veja também

Começar

Servidor

MQTT 🚧

E-mail 🚧

Chatbot 🚧

Cliente

Motores

Avançado

Ajuda

🚧 = em desenvolvimento, pode mudar

Clone this wiki locally