sgcWebSockets em cinco minutos

Você instalou a biblioteca e a paleta está aparecendo. Esta página leva você daí até um servidor que aceita uma conexão e um cliente que envia uma mensagem e lê a resposta. Tudo o que está abaixo foi extraído de um demo que acompanha o download, então você pode abrir o projeto em vez de digitar.

Do Delphi 7 ao RAD Studio 13
Windows, Linux, macOS, iOS, Android
Cliente a partir da Standard, servidor a partir da Professional

O que o primeiro exemplo precisa

Dois componentes não visuais, uma unit na cláusula uses e uma unit extra para os tipos de parâmetro dos manipuladores de eventos.

Componente cliente

TsgcWebSocketClient, declarado em sgcWebSocket.pas e registrado na página SGC WebSockets da paleta. Defina Host, Port e depois Active.

Componente servidor

TsgcWebSocketServer, na mesma unit e na mesma página da paleta. Defina Port e depois Active. Ele escuta, faz o upgrade do handshake e dispara OnConnect.

A segunda unit

Todo evento entrega a você um TsgcWSConnection, que fica em sgcWebSocket_Classes.pas. Os demos escrevem uses sgcWebSocket, sgcWebSocket_Classes; e você também deve fazer o mesmo.

Plataformas

Nenhuma das duas units tem restrição de plataforma, e ambos os componentes são registrados com ComponentPlatforms(0), então os destinos VCL, FMX, console e serviço compilam. Um demo de cliente FireMonkey acompanha o pacote.

Requisitos e edições

A coluna de edição é o define que de fato controla o código, com a linha em que ele aparece em Source/sgcVer.inc.

O quê Valor
IDE Do Delphi 7 ao RAD Studio 13, e do C++Builder 2007 ao 13. Um grupo de pacotes por versão da IDE em Packages\.
Cláusula uses sgcWebSocket para os componentes, sgcWebSocket_Classes para TsgcWSConnection.
Edição do cliente TsgcWebSocketClient está envolvido em {$IFDEF SGC_WS_CLIENT}. SGC_WS_CLIENT é definido na linha 697, dentro do bloco {$IFDEF SGC_EDT_STD} que vai da linha 675 à linha 724. Ou seja, Standard e superiores.
Edição do servidor TsgcWebSocketServer está envolvido diretamente em {$IFDEF SGC_EDT_PRO}, e seu registro na paleta em sgcWebSocket_Reg.pas fica dentro da mesma proteção. O bloco de recursos da Professional vai da linha 727 à linha 758. Ou seja, Professional e superiores. Uma licença Standard dá a você o cliente, não o servidor.
Página da paleta Registrada em {$IFDEF SGC_PACK_WEBSOCKETS}, definido na linha 852.
Plataformas Nenhuma restrição de plataforma no escopo da unit em sgcWebSocket.pas, sgcWebSocket_Client.pas ou sgcWebSocket_Server.pas. No Windows, a unit Windows é incluída condicionalmente, nada além disso.

Não tem certeza de qual edição você está usando? Abra Source/sgcVer.inc e olhe as cinco primeiras linhas. Os defines SGC_EDT_* ali são cumulativos, então a All-Access define todos eles e a Standard define apenas os dois primeiros.

Instale e confirme a paleta

Cinco passos do zip até um componente que você pode soltar no formulário. Compile o pacote de runtime antes de instalar o de design-time, porque o segundo referencia o primeiro.

1. Descompacte

Descompacte o download em uma pasta de sua escolha. O restante desta página a chama de {$DIR}. As pastas Source\, Packages\, Demos\ e lib*\ ficam todas dentro dela.

2. Caminho da biblioteca

Tools, Options, Library. Adicione {$DIR}\source e a pasta que corresponde à sua IDE, por exemplo {$DIR}\libD13\$(Platform) no RAD Studio 13 ou {$DIR}\libD12\$(Platform) no 12.

3. Compile os pacotes

Abra {$DIR}\Packages\sgcWebSocketsD13.groupproj para a versão da sua IDE. Compile primeiro sgcWebSocketsD13.dpk e depois instale dclsgcWebSocketsD13.dpk. O C++Builder usa os arquivos .cbproj da mesma pasta.

4. Confira a paleta

Aparece uma nova página chamada SGC WebSockets. Em uma compilação Standard, ela contém TsgcWebSocketClient. Na Professional e superiores, ela também contém TsgcWebSocketServer, TsgcWebSocketHTTPServer, TsgcWebSocketProxyServer e TsgcWebSocketLoadBalancerServer.

5. Abra um demo

Antes de escrever qualquer coisa, abra {$DIR}\Demos\01.WebSocket_Quick_Start\01.Server_and_Client_Chat. É o menor par funcional da biblioteca e o código abaixo vem dele.

Um servidor e um cliente, em cerca de vinte linhas

Inicie o servidor, inicie o cliente, envie uma string. A aba do servidor escuta em uma porta; a aba do cliente se conecta a ela e grava uma mensagem.

uServerChat.pas
uses
  Classes, SysUtils,
  // sgc
  sgcWebSocket, sgcWebSocket_Classes;

procedure TfrmServerChat.btnStartClick(Sender: TObject);
begin
  WSServer.Port := 5418;
  WSServer.Active := True;
  memoLog.Lines.Add('#started');
end;

procedure TfrmServerChat.WSServerConnect(Connection: TsgcWSConnection);
begin
  memoLog.Lines.Add('Connected: ' + Connection.IP);
end;

procedure TfrmServerChat.WSServerDisconnect(Connection: TsgcWSConnection;
  Code: Integer);
begin
  memoLog.Lines.Add('Disconnected (' + IntToStr(Code) + '): ' + Connection.IP);
end;

procedure TfrmServerChat.WSServerMessage(Connection: TsgcWSConnection;
  const Text: string);
begin
  memoLog.Lines.Add(Text);
  // send it straight back, so the client has something to read
  Connection.WriteData('echo: ' + Text);
end;

Solte TsgcWebSocketServer no formulário, dê a ele o nome WSServer e deixe a IDE gerar os quatro manipuladores pelo Object Inspector. Connection.IP e Connection.WriteData vêm ambos de TsgcWSConnection, e é por isso que sgcWebSocket_Classes está na cláusula uses.

uClientChat.pas
uses
  Classes, SysUtils,
  // sgc
  sgcWebSocket, sgcWebSocket_Classes;

procedure TfrmClientChat.btnStartClick(Sender: TObject);
begin
  WSClient.Host := 'localhost';
  WSClient.Port := 5418;
  WSClient.TLS := False;
  WSClient.Active := True;
end;

procedure TfrmClientChat.btnSendClick(Sender: TObject);
begin
  if WSClient.Active then
    WSClient.WriteData('Hello from Delphi')
  else
    raise Exception.Create('Not connected');
end;

procedure TfrmClientChat.WSClientConnect(Connection: TsgcWSConnection);
begin
  memoLog.Lines.Add('#connected');
end;

procedure TfrmClientChat.WSClientMessage(Connection: TsgcWSConnection;
  const Text: string);
begin
  memoLog.Lines.Add(Text);
end;

Execute primeiro o projeto do servidor e depois este. #connected aparece no log do cliente e echo: Hello from Delphi volta em OnMessage. Essa viagem de ida e volta é o início rápido inteiro.

uConsole.pas
program WSConsoleClient;

{$APPTYPE CONSOLE}

uses
  Classes, SysUtils,
  // sgc
  sgcWebSocket, sgcWebSocket_Classes;

type
  TChatHandler = class
    procedure DoConnect(Connection: TsgcWSConnection);
    procedure DoMessage(Connection: TsgcWSConnection; const Text: string);
  end;

procedure TChatHandler.DoConnect(Connection: TsgcWSConnection);
begin
  Writeln('#connected');
end;

procedure TChatHandler.DoMessage(Connection: TsgcWSConnection;
  const Text: string);
begin
  Writeln('Server says: ', Text);
end;

var
  oClient: TsgcWebSocketClient;
  oHandler: TChatHandler;
begin
  oHandler := TChatHandler.Create;
  oClient := TsgcWebSocketClient.Create(nil);
  try
    oClient.Host := 'localhost';
    oClient.Port := 5418;
    oClient.WatchDog.Enabled := True;   // reconnect on its own

    // assign the handlers BEFORE Active, or the first
    // OnConnect can fire with nothing attached
    oClient.OnConnect := oHandler.DoConnect;
    oClient.OnMessage := oHandler.DoMessage;

    oClient.Active := True;
    oClient.WriteData('Hello from Delphi');
    Readln;
  finally
    oClient.Free;
    oHandler.Free;
  end;
end.

O cliente executa sua própria thread, então um programa de console precisa manter a thread principal ativa. É para isso que serve o Readln.

As abas de servidor e cliente são o demo que acompanha o pacote, Demos\01.WebSocket_Quick_Start\01.Server_and_Client_Chat, sem o código auxiliar de checkboxes e caixas de edição. A terceira aba traz as mesmas chamadas escritas para componentes criados em tempo de execução em vez de soltos em um formulário.

Comprove a viagem de ida e volta

Quatro eventos dizem tudo sobre a primeira execução, e você quer os quatro conectados antes de avançar.

Active

No servidor, Active := True ou funciona ou gera uma exceção. Se a porta estiver ocupada, você descobre aqui e não três passos depois.

OnConnect

procedure(Connection: TsgcWSConnection). Dispara nos dois lados. No servidor, Connection.IP diz quem chegou; no cliente, é a prova de que o handshake foi atualizado.

OnMessage

procedure(Connection: TsgcWSConnection; const Text: string). O eco voltando no cliente é a prova da viagem de ida e volta de ponta a ponta.

OnError e OnException

procedure(Connection: TsgcWSConnection; const Error: string) e procedure(Connection: TsgcWSConnection; E: Exception). Conecte os dois. Sem eles, uma falha é silenciosa e parece que nada aconteceu.

O que costuma dar errado na primeira vez

Quase todo problema da primeira execução é um destes seis.

TsgcWebSocketServer não está na paleta

A classe do servidor só é compilada quando SGC_EDT_PRO está definido, na linha 130 de sgcWebSocket.pas, e só é registrada dentro da mesma proteção. Em uma compilação Standard, o cliente está lá e o servidor não. Isso é licenciamento, não uma instalação quebrada.

Identificador não declarado TsgcWSConnection

Os componentes ficam em sgcWebSocket, o objeto de conexão fica em sgcWebSocket_Classes. Adicione a segunda unit à cláusula uses. Todos os demos que acompanham o pacote têm as duas.

O cliente conecta e depois cai

Defina WatchDog.Enabled := True para que uma conexão perdida se reconecte sozinha, e trate OnError e OnException. Uma desconexão silenciosa sem manipulador parece que nada aconteceu.

Nada chega ao servidor

Confirme que o cliente está realmente ativo antes de gravar. WriteData em um cliente inativo não faz nada de útil, e é por isso que o demo testa if WSClient.Active then antes de enviar.

Porta já em uso

Outra instância do servidor, ou outro programa, ainda é dono da porta. Pare-o ou mude o servidor para uma porta livre. Os padrões dos demos são 5416 e 5418.

O TLS falha no Linux ou no celular

Uma conexão wss:// precisa de um back end TLS funcional. Escolha um por meio de TLSOptions.IOHandler: OpenSSL em todo lugar, SChannel no Windows sem DLLs para distribuir, ou os handlers nativos de Apple e Android na edição Enterprise.

Para onde as pessoas vão depois da primeira mensagem

O par de chat é o ponto de partida. Estas são as quatro direções que o trabalho costuma tomar, e as quatro estão na mesma biblioteca.

Fale um protocolo de verdade

O mesmo cliente transporta os componentes de subprotocolo MQTT, AMQP, STOMP, Kafka e WAMP. Solte um, aponte sua propriedade Client para o seu TsgcWebSocketClient e você está em um broker.

Início rápido do sgcMQ e a visão geral dos protocolos

Sirva HTTP além de WebSockets

TsgcWebSocketHTTPServer responde a requisições HTTP comuns e a upgrades de WebSocket na mesma porta, que é o que você quer quando o navegador precisa buscar uma página antes de abrir um socket.

Componentes HTTP

Escale além de um processo

A edição Enterprise adiciona clustering, um servidor balanceador de carga e um servidor proxy, de modo que um único endpoint lógico pode ficar na frente de vários processos de servidor.

Referência de cluster e referência do balanceador de carga

Proteja antes de publicar

Limitação de taxa, circuit breaker, gerenciador de chaves de API e um componente de firewall se acoplam ao servidor que você já tem.

Limitador de taxa, circuit breaker e firewall

Referência, demos e documentação

As páginas de referência documentam cada propriedade e evento. Os projetos de demo estão dentro do seu download, em Demos\01.WebSocket_Quick_Start.

Referência, cliente WebSocket Cada propriedade, método e evento de TsgcWebSocketClient.
Referência, servidor WebSocket Bindings, autenticação, broadcast e gerenciamento de conexões em TsgcWebSocketServer.
Ajuda online, TsgcWebSocketClient A referência de componentes gerada, sempre alinhada com a versão atual.
Qual edição eu preciso Recurso por recurso, o que Standard, Professional, Enterprise e All-Access ativam.
Baixe a versão de avaliação O mesmo instalador da versão de produção, com tempo limitado, um por versão da IDE.
Manual do usuário (PDF) O manual completo que cobre todos os componentes da biblioteca.

Leitura relacionada: o que os WebSockets realmente são, os eventos de conexão e watchdog do cliente e como proteger um servidor WebSocket. Cada produto tem seu próprio início rápido, listado na página de primeiros passos.

Perguntas sobre o início rápido do sgcWebSockets

sgcWebSocket fornece TsgcWebSocketClient e TsgcWebSocketServer. Adicione também sgcWebSocket_Classes, porque todo evento entrega a você um TsgcWSConnection e esse tipo é declarado ali. Os demos que acompanham o pacote escrevem uses sgcWebSocket, sgcWebSocket_Classes; e o demo do servidor adiciona sgcWebSocket_Server.
A classe do servidor é compilada dentro de {$IFDEF SGC_EDT_PRO}, e seu registro na paleta em sgcWebSocket_Reg.pas fica dentro da mesma proteção. SGC_EDT_PRO ativa o bloco de recursos da Professional, linhas 727 a 758 de sgcVer.inc. Uma compilação Standard compila apenas o cliente. O define do cliente, SGC_WS_CLIENT, está na linha 697 dentro do bloco Standard, linhas 675 a 724.
Elas vêm de sgcWebSocket_Classes.pas. OnConnect é procedure(Connection: TsgcWSConnection). OnDisconnect é procedure(Connection: TsgcWSConnection; Code: Integer). OnMessage é procedure(Connection: TsgcWSConnection; const Text: string). OnError é procedure(Connection: TsgcWSConnection; const Error: string). OnException é procedure(Connection: TsgcWSConnection; E: Exception). Deixe a IDE gerá-las em vez de digitá-las, porque um parâmetro a mais ou a menos é o erro de compilação mais comum em um primeiro projeto.
Sim. sgcWebSocket.pas, sgcWebSocket_Client.pas e sgcWebSocket_Server.pas não têm restrição de plataforma no escopo da unit, e ambos os componentes são registrados com ComponentPlatforms(0), então a IDE não os restringe a um destino. Um demo de cliente e servidor FireMonkey acompanha o pacote em Demos\01.WebSocket_Quick_Start\07.Firemonkey_Server_and_Client. O único componente WebSocket da biblioteca restrito a uma plataforma é TsgcWebSocketClient_WinHTTP, que é Win32 e Win64.
Defina TLS := True no cliente e aponte Port para a porta TLS. Depois escolha um back end TLS com TLSOptions.IOHandler. O OpenSSL funciona em todo lugar e precisa de libcrypto-3.dll e libssl-3.dll ao lado do executável no Windows. O SChannel é apenas para Windows e não distribui nada extra. Os handlers nativos de Apple e Android são recursos da Enterprise.
Sim, e a terceira aba acima faz exatamente isso. Atribua os manipuladores de eventos antes de definir Active := True, caso contrário o primeiro OnConnect pode disparar antes de o seu manipulador estar conectado. Em um aplicativo de console, lembre-se de que o cliente executa sua própria thread, então a thread principal precisa permanecer ativa, e é por isso que o exemplo termina com Readln.
Ele reconecta um cliente que caiu, em um intervalo que você escolhe. Ative-o em qualquer aplicativo de longa execução, porque uma oscilação de rede que feche o socket deixaria seu aplicativo desconectado em silêncio. Defina WatchDog.Enabled := True e, se o padrão for agressivo demais, WatchDog.Interval e WatchDog.Attempts.
Dentro do seu download, em Demos\. O par usado nesta página é 01.WebSocket_Quick_Start\01.Server_and_Client_Chat. Também vale abrir logo no início: 06.Authentication para um servidor que verifica credenciais, 07.Firemonkey_Server_and_Client para um cliente multiplataforma e 12.Groups para broadcast a um subconjunto de conexões.
Melhor custo-benefício: All-AccessTodos os produtos da eSeGeCe, com Suporte Premium incluído, a partir de €1,059/ano.
Ver preços do All-Access

Pronto para construir com ele?

Baixe a versão de avaliação e execute o demo de chat antes de escrever uma linha sua.