sgcWebSockets en cinco minutos

Ya has instalado la biblioteca y la paleta se muestra en el IDE. Esta página te lleva desde ahí hasta un servidor que acepta una conexión y un cliente que envía un mensaje y lee la respuesta. Todo lo que ves a continuación está extraído de una demo incluida en la descarga, así que puedes abrir el proyecto en lugar de teclear.

Delphi 7 a RAD Studio 13
Windows, Linux, macOS, iOS, Android
Cliente desde Standard, servidor desde Professional

Lo que necesita el primer ejemplo

Dos componentes no visuales, una unit en la cláusula uses y otra unit más para los tipos de parámetro de los manejadores de eventos.

Componente cliente

TsgcWebSocketClient, declarado en sgcWebSocket.pas y registrado en la página SGC WebSockets de la paleta. Define Host, Port y después Active.

Componente servidor

TsgcWebSocketServer, misma unit, misma página de la paleta. Define Port y después Active. Escucha, actualiza el handshake y lanza OnConnect.

La segunda unit

Cada evento te entrega un TsgcWSConnection, que vive en sgcWebSocket_Classes.pas. Las demos escriben uses sgcWebSocket, sgcWebSocket_Classes; y tú también deberías hacerlo.

Plataformas

Ninguna de las dos units lleva una guarda de plataforma y ambos componentes se registran con ComponentPlatforms(0), de modo que compilan en destinos VCL, FMX, consola y servicio. En la descarga se incluye una demo de cliente FireMonkey.

Requisitos y ediciones

La columna de edición es el define que realmente controla el código, con la línea en la que se encuentra en Source/sgcVer.inc.

Qué Valor
IDE Delphi 7 hasta RAD Studio 13, y C++Builder 2007 hasta 13. Un grupo de paquetes por versión de IDE en Packages\.
Cláusula uses sgcWebSocket para los componentes, sgcWebSocket_Classes para TsgcWSConnection.
Edición del cliente TsgcWebSocketClient está envuelto en {$IFDEF SGC_WS_CLIENT}. SGC_WS_CLIENT se define en la línea 697, dentro del bloque {$IFDEF SGC_EDT_STD} que va de la línea 675 a la 724. Es decir, Standard y superiores.
Edición del servidor TsgcWebSocketServer está envuelto directamente en {$IFDEF SGC_EDT_PRO}, y su registro en la paleta en sgcWebSocket_Reg.pas está dentro de la misma guarda. El bloque de características Professional va de la línea 727 a la 758. Es decir, Professional y superiores. Una licencia Standard te da el cliente, no el servidor.
Página de la paleta Registrada bajo {$IFDEF SGC_PACK_WEBSOCKETS}, definido en la línea 852.
Plataformas No hay guarda de plataforma a nivel de unit en sgcWebSocket.pas, sgcWebSocket_Client.pas ni sgcWebSocket_Server.pas. En Windows se incluye la unit Windows de forma condicional, nada más.

¿No estás seguro de qué edición tienes? Abre Source/sgcVer.inc y mira las cinco primeras líneas. Los defines SGC_EDT_* son acumulativos, así que All-Access los define todos y Standard solo los dos primeros.

Instala y confirma la paleta

Cinco pasos desde el zip hasta un componente que puedes soltar en el formulario. Compila el paquete de runtime antes de instalar el de tiempo de diseño, porque el segundo hace referencia al primero.

1. Descomprime

Descomprime la descarga en la carpeta que prefieras. El resto de esta página la llama {$DIR}. Las carpetas Source\, Packages\, Demos\ y lib*\ están todas dentro.

2. Ruta de biblioteca

Tools, Options, Library. Añade {$DIR}\source y la carpeta que corresponda a tu IDE, por ejemplo {$DIR}\libD13\$(Platform) en RAD Studio 13 o {$DIR}\libD12\$(Platform) en la 12.

3. Compila los paquetes

Abre {$DIR}\Packages\sgcWebSocketsD13.groupproj para tu versión de IDE. Compila primero sgcWebSocketsD13.dpk y después instala dclsgcWebSocketsD13.dpk. C++Builder usa los archivos .cbproj de la misma carpeta.

4. Comprueba la paleta

Aparece una página nueva llamada SGC WebSockets. En una compilación Standard contiene TsgcWebSocketClient. En Professional y superiores contiene además TsgcWebSocketServer, TsgcWebSocketHTTPServer, TsgcWebSocketProxyServer y TsgcWebSocketLoadBalancerServer.

5. Abre una demo

Antes de escribir nada, abre {$DIR}\Demos\01.WebSocket_Quick_Start\01.Server_and_Client_Chat. Es la pareja funcional más pequeña de la biblioteca y el código de más abajo procede de ella.

Un servidor y un cliente, en unas veinte líneas

Arranca el servidor, arranca el cliente, envía una cadena. La pestaña del servidor escucha en un puerto; la pestaña del cliente se conecta a él y escribe un mensaje.

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;

Suelta TsgcWebSocketServer en el formulario, llámalo WSServer y deja que el IDE genere los cuatro manejadores desde el Object Inspector. Connection.IP y Connection.WriteData proceden ambos de TsgcWSConnection, y por eso sgcWebSocket_Classes está en la 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;

Ejecuta primero el proyecto del servidor y después este. En el log del cliente aparece #connected y echo: Hello from Delphi vuelve por OnMessage. Ese viaje de ida y vuelta es todo el inicio rápido.

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.

El cliente ejecuta su propio hilo, así que un programa de consola tiene que mantener vivo el hilo principal. Para eso sirve el Readln.

Las pestañas de servidor y cliente son la demo incluida Demos\01.WebSocket_Quick_Start\01.Server_and_Client_Chat, sin el código auxiliar de casillas y cuadros de edición de la demo. La tercera pestaña contiene las mismas llamadas escritas sobre componentes creados en tiempo de ejecución en lugar de soltados en un formulario.

Demuestra el viaje de ida y vuelta

Cuatro eventos te dicen todo sobre la primera ejecución, y conviene tener los cuatro conectados antes de seguir adelante.

Active

En el servidor, Active := True o bien funciona o bien lanza una excepción. Si el puerto está ocupado te enteras aquí y no tres pasos más tarde.

OnConnect

procedure(Connection: TsgcWSConnection). Se dispara en ambos lados. En el servidor, Connection.IP te dice quién ha llegado; en el cliente es la prueba de que el handshake se ha actualizado.

OnMessage

procedure(Connection: TsgcWSConnection; const Text: string). El eco que vuelve al cliente demuestra el viaje de ida y vuelta de extremo a extremo.

OnError y OnException

procedure(Connection: TsgcWSConnection; const Error: string) y procedure(Connection: TsgcWSConnection; E: Exception). Conecta ambos. Sin ellos un fallo es silencioso y parece que no ha pasado nada.

Lo que suele fallar la primera vez

Casi todos los problemas de la primera ejecución son uno de estos seis.

TsgcWebSocketServer no está en la paleta

La clase del servidor se compila solo cuando SGC_EDT_PRO está definido, en la línea 130 de sgcWebSocket.pas, y se registra solo dentro de la misma guarda. En una compilación Standard está el cliente y no el servidor. Eso es licenciamiento, no una instalación rota.

Identificador no declarado TsgcWSConnection

Los componentes viven en sgcWebSocket, el objeto de conexión vive en sgcWebSocket_Classes. Añade la segunda unit a la cláusula uses. Todas las demos incluidas llevan ambas.

El cliente se conecta y luego se cae

Define WatchDog.Enabled := True para que una conexión caída se reconecte sola, y gestiona OnError y OnException. Una desconexión silenciosa sin manejador parece que no ha pasado nada.

No llega nada al servidor

Comprueba que el cliente está realmente activo antes de escribir. WriteData sobre un cliente inactivo no hace nada útil, y por eso la demo comprueba if WSClient.Active then antes de enviar.

Puerto ya en uso

Otra instancia del servidor, u otro programa, sigue ocupando el puerto. Páralo o mueve el servidor a un puerto libre. Los valores por defecto de la demo son 5416 y 5418.

TLS falla en Linux o en móvil

Una conexión wss:// necesita un back end TLS operativo. Elige uno mediante TLSOptions.IOHandler: OpenSSL en todas partes, SChannel en Windows sin DLL que desplegar, o los manejadores nativos de Apple y Android en la edición Enterprise.

Adónde van los usuarios tras el primer mensaje

La pareja de chat es el punto de partida. Estas son las cuatro direcciones que suele tomar el trabajo, y las cuatro están en la misma biblioteca.

Habla un protocolo real

El mismo cliente transporta los componentes de subprotocolo MQTT, AMQP, STOMP, Kafka y WAMP. Suelta uno, apunta su propiedad Client a tu TsgcWebSocketClient y ya estás en un broker.

Inicio rápido de sgcMQ y la visión general de protocolos

Sirve HTTP además de WebSockets

TsgcWebSocketHTTPServer responde a peticiones HTTP normales y a actualizaciones WebSocket en el mismo puerto, que es lo que necesitas cuando el navegador tiene que descargar una página antes de abrir un socket.

Componentes HTTP

Escala más allá de un proceso

La edición Enterprise añade clustering, un servidor balanceador de carga y un servidor proxy, de modo que un único endpoint lógico puede situarse delante de varios procesos servidor.

Referencia del cluster y referencia del balanceador de carga

Endurécelo antes de publicarlo

Un rate limiter, un circuit breaker, un gestor de claves API y un componente firewall se acoplan al servidor que ya tienes.

Rate limiter, circuit breaker y firewall

Referencia, demos y documentación

Las páginas de referencia documentan cada propiedad y evento. Los proyectos de demo están dentro de tu descarga, en Demos\01.WebSocket_Quick_Start.

Referencia, cliente WebSocket Todas las propiedades, métodos y eventos de TsgcWebSocketClient.
Referencia, servidor WebSocket Bindings, autenticación, difusión y gestión de conexiones en TsgcWebSocketServer.
Ayuda en línea, TsgcWebSocketClient La referencia generada del componente, siempre al día con la versión actual.
Qué edición necesito Característica por característica, qué activa cada una de las ediciones Standard, Professional, Enterprise y All-Access.
Descarga la versión de prueba El mismo instalador que en producción, con límite de tiempo, uno por versión de IDE.
Manual de usuario (PDF) El manual completo que cubre todos los componentes de la biblioteca.

Lecturas relacionadas: qué son realmente los WebSockets, los eventos de conexión y watchdog del cliente y cómo proteger un servidor WebSocket. Cada producto tiene su propio inicio rápido, listado en la página de primeros pasos.

Preguntas sobre el inicio rápido de sgcWebSockets

sgcWebSocket te da TsgcWebSocketClient y TsgcWebSocketServer. Añade también sgcWebSocket_Classes, porque cada evento te entrega un TsgcWSConnection y ese tipo se declara ahí. Las demos incluidas escriben uses sgcWebSocket, sgcWebSocket_Classes; y la demo del servidor añade sgcWebSocket_Server.
La clase del servidor se compila dentro de {$IFDEF SGC_EDT_PRO}, y su registro en la paleta en sgcWebSocket_Reg.pas está dentro de la misma guarda. SGC_EDT_PRO activa el bloque de características Professional, líneas 727 a 758 de sgcVer.inc. Una compilación Standard compila solo el cliente. El define del cliente, SGC_WS_CLIENT, está en la línea 697 dentro del bloque Standard, líneas 675 a 724.
Proceden de sgcWebSocket_Classes.pas. OnConnect es procedure(Connection: TsgcWSConnection). OnDisconnect es procedure(Connection: TsgcWSConnection; Code: Integer). OnMessage es procedure(Connection: TsgcWSConnection; const Text: string). OnError es procedure(Connection: TsgcWSConnection; const Error: string). OnException es procedure(Connection: TsgcWSConnection; E: Exception). Deja que el IDE los genere en lugar de teclearlos, porque un parámetro de más o de menos es el error de compilación más común en un primer proyecto.
Sí. sgcWebSocket.pas, sgcWebSocket_Client.pas y sgcWebSocket_Server.pas no llevan guarda de plataforma a nivel de unit, y ambos componentes se registran con ComponentPlatforms(0), así que el IDE no los restringe a un destino. Bajo Demos\01.WebSocket_Quick_Start\07.Firemonkey_Server_and_Client se incluye una demo de cliente y servidor FireMonkey. El único componente WebSocket de la biblioteca restringido a una plataforma es TsgcWebSocketClient_WinHTTP, que es Win32 y Win64.
Define TLS := True en el cliente y apunta Port al puerto TLS. Después elige un back end TLS con TLSOptions.IOHandler. OpenSSL funciona en todas partes y necesita libcrypto-3.dll y libssl-3.dll junto al ejecutable en Windows. SChannel es solo para Windows y no incluye nada adicional. Los manejadores nativos de Apple y Android son características Enterprise.
Sí, y la tercera pestaña de arriba hace exactamente eso. Asigna los manejadores de eventos antes de definir Active := True, de lo contrario el primer OnConnect puede dispararse antes de que tu manejador esté asociado. En una aplicación de consola recuerda que el cliente ejecuta su propio hilo, así que el hilo principal tiene que seguir vivo, y por eso el ejemplo termina con Readln.
Reconecta un cliente que se ha caído, con el intervalo que elijas. Actívalo para cualquier cosa que se ejecute durante mucho tiempo, porque un fallo de red que cierre el socket dejará tu aplicación desconectada en silencio. Define WatchDog.Enabled := True y, si el valor por defecto es demasiado insistente, WatchDog.Interval y WatchDog.Attempts.
Dentro de tu descarga, en Demos\. La pareja usada en esta página es 01.WebSocket_Quick_Start\01.Server_and_Client_Chat. También conviene abrir pronto: 06.Authentication para un servidor que comprueba credenciales, 07.Firemonkey_Server_and_Client para un cliente multiplataforma y 12.Groups para difundir a un subconjunto de conexiones.
La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

¿Listo para construir sobre ello?

Descarga la versión de prueba y ejecuta la demo de chat antes de escribir una línea propia.