API Pusher

Pusher

Pusher es una plataforma fácil y fiable con interesantes funcionalidades basadas en el protocolo WebSocket: mensajería pub/sub flexible, listas de usuarios en tiempo real (presencia), autenticación...

La versión de la API WebSocket de Pusher es 7.

Los datos se envían bidireccionalmente sobre un WebSocket como datos de texto que contienen JSON codificado en UTF8 (no se admiten tramas WebSocket binarias).

Puede llamar al método Ping para probar la conexión con el servidor. Esencialmente, cualquier mensaje recibido de la otra parte se considera una señal de que la conexión está activa. En ausencia de mensajes, cualquiera de las partes puede comprobar que la otra responde enviando un mensaje ping, al que la otra parte debe responder con un pong.

Antes de conectarse, debe completar los siguientes campos:


Pusher.Cluster := 'eu'; // cluster where your pusher account is located
Pusher.Key := '9c3b7ef25qe97a00116c'; // your pusher api key
Pusher.Name := 'js'; // optional, name of your application
Pusher.Version := '4.1';  // optional, version of your application
Pusher.TLS := True; // if encrypted, set to True
Pusher.Secret := '2dc792e1916ac49e6b3f'; // pusher secret string (needed for private and presence channels)

Importante

Pusher requiere que el cliente websocket se conecte a una URL usando los campos anteriores (clave, clúster...), estos campos se usan para construir la URL y esto se hace cuando asigna el cliente en el componente Pusher. Por lo tanto, para asegurarse de que la URL se construya correctamente, configure el cliente después de haber completado los campos de configuración de Pusher. A continuación se muestra el pseudocódigo:

// configure pusher fields

pusher.cluster = ...

pusher.key = ...

// set client

pusher.client = websocket client

// start connection

websocket client.Active = true;

Tras una conexión exitosa, se activa el evento OnPusherConnect y se obtienen los siguientes campos:

En caso de error, se generará el evento OnPusherError y se proporcionará información sobre el error. Pusher puede enviar un error como respuesta a una autenticación no válida, un comando incorrecto, etc.

4000-4099

Indica un error que provoca el cierre de la conexión por parte de Pusher, y que intentar reconectarse con los mismos parámetros no tendrá éxito.

4000: La aplicación solo acepta conexiones SSL, reconéctese usando wss://

4001: La aplicación no existe

4003: Aplicación deshabilitada

4004: La aplicación ha superado la cuota de conexiones

4005: Ruta no encontrada

4006: Formato de cadena de versión no válido

4007: Versión de protocolo no admitida

4008: No se ha suministrado ninguna versión de protocolo

4100-4199

Indica un error que provoca el cierre de la conexión por parte de Pusher, y que el cliente puede reconectarse después de 1 segundo o más.

4100: Capacidad excedida

4200-4299

Indica un error que provoca que Pusher cierre la conexión, y que el cliente puede reconectarse inmediatamente.

4200: Reconexión inmediata genérica

4201: Respuesta Pong no recibida: se envió un ping al cliente pero no se recibió respuesta; consulte los mensajes de ping y pong

4202: Cerrado por inactividad: el cliente ha estado inactivo durante mucho tiempo (actualmente 24 horas) y no es compatible con ping. Por favor, actualice a una versión más reciente del borrador de WebSocket o implemente la versión 5 o superior de este protocolo.

4300-4399

Cualquier otro tipo de error.

4301: Evento de cliente rechazado por límite de velocidad

Canales

Los canales son un concepto fundamental en Pusher. Cada aplicación tiene un número de canales, y cada cliente puede elegir a qué canales se suscribe.

Los canales proporcionan:

Se recomienda encarecidamente utilizar canales para filtrar los datos y no lograrlo mediante eventos. Esto se debe a que todos los eventos publicados en un canal se envían a todos los suscriptores, independientemente de su vinculación de eventos.

Los canales no necesitan crearse explícitamente y se instancian a demanda del cliente. Esto significa que crear un canal es sencillo: basta con indicar a un cliente que se suscriba a él.

Se admiten los siguientes tipos de canales:

Canales Públicos

Los canales públicos deben utilizarse para datos de acceso público, ya que no requieren ningún tipo de autorización para suscribirse a ellos.

Puede suscribirse y cancelar la suscripción de canales en cualquier momento. No es necesario esperar a que Pusher termine de conectarse primero.

Ejemplo: suscribirse al canal "my-channel".


Delphi
APIPusher.Subscribe('my-channel');

Si la suscripción se realiza correctamente, se activará el evento OnPusherSubscribe; si se produce un error, recibirá un mensaje en el evento OnPusherError.

Todos los mensajes del canal suscrito se recibirán en el evento OnPusherEvent.

Cuando se llama al método Publish y el canal es Public, el componente, en lugar de utilizar el protocolo WebSocket, utiliza el protocolo HTTP y llama al método TriggerEvent (no se permite publicar mediante el protocolo WebSocket).

Canales Privados

Requiere Indy 10.5.7 o posterior

Los canales privados deben utilizarse cuando el acceso al canal necesita restringirse de alguna manera. Para que un usuario pueda suscribirse a un canal privado, el permiso debe estar autorizado.

Ejemplo: suscribirse al canal "my-private-channel".


Delphi
APIPusher.Subscribe('my-private-channel', pscPrivateChannel);

Si la suscripción se realiza correctamente, se activará el evento OnPusherSubscribe; si se produce un error, recibirá un mensaje en el evento OnPusherError.

Todos los mensajes del canal suscrito se recibirán en el evento OnPusherEvent.

Canales Presence

Requiere Indy 10.5.7 o posterior

Los canales de presencia se basan en la seguridad de los canales privados y ofrecen la funcionalidad adicional de conocer quién está suscrito a ese canal. Esto facilita enormemente la implementación de salas de chat y funcionalidades del tipo "quién está en línea" en su aplicación. Piense en salas de chat, colaboradores en un documento, personas que ven la misma página web, competidores en un juego y cosas similares.

Los canales Presence se suscriben desde la API del cliente de la misma forma que los canales privados, pero el nombre del canal debe llevar el prefijo presence-. Al igual que con los canales privados, se realiza una solicitud HTTP a una URL de autenticación configurable para determinar si el usuario actual tiene permisos para acceder al canal.

La información sobre los usuarios que se suscriben y se dan de baja de un canal puede accederse enlazando eventos en el canal de presencia, y el estado actual de los usuarios suscritos al canal está disponible a través de la propiedad channel.members.

Ejemplo: suscribirse al canal "my-presence-channel".


APIPusher.Subscribe('my-presence-channel', pscPresenceChannel,
  '{"user_id":"John_Smith","user_info":{"name":"John Smith"}}')

Si la suscripción se realiza correctamente, se activará el evento OnPusherSubscribe; si se produce un error, recibirá un mensaje en el evento OnPusherError.

Todos los mensajes del canal suscrito se recibirán en el evento OnPusherEvent.

Canales de caché

Un canal de caché recuerda el último evento activado y lo envía como primer evento a los nuevos suscriptores.

Cuando se activa un evento en un canal de caché, Pusher Channels almacena en caché este evento, y cuando un cliente se suscribe a un canal de caché, si existe un valor en caché, este se envía al cliente como el primer evento en ese canal. Este comportamiento ayuda a los desarrolladores a proporcionar el estado inicial sin añadir lógica adicional para obtenerlo desde otro lugar.

Se admiten los siguientes canales de caché:

Ejemplo: suscribirse al canal de caché público "my-cache-channel".


APIPusher.Subscribe('my-cache-channel', pscCacheChannel);

Si la suscripción se realiza correctamente, se activará el evento OnPusherSubscribe; si se produce un error, recibirá un mensaje en el evento OnPusherError.

Todos los mensajes del canal suscrito se recibirán en el evento OnPusherEvent.

Si no hay ningún evento en caché al suscribirse a un canal de caché, se generará el evento OnPusherCacheMiss, que proporcionará el nombre del canal. Esto permite que su aplicación gestione el caso en que no haya datos en caché disponibles.

Canales privados cifrados

Los canales Privados-Cifrados proporcionan cifrado de extremo a extremo para los mensajes. Al igual que los canales privados, requieren autenticación, pero además todas las cargas útiles de datos se cifran usando NaCl secretbox para que solo los suscriptores autorizados puedan leer el contenido. Incluso Pusher en sí mismo no puede descifrar los mensajes.

Para usar canales privados cifrados, debe proporcionar un SharedSecret durante la autenticación. El secreto compartido se utiliza para cifrar y descifrar los datos del mensaje.

Ejemplo: suscripción a un canal privado cifrado "my-encrypted-channel".


APIPusher.Subscribe('my-encrypted-channel', pscPrivateEncryptedChannel);

También está disponible una variante de caché cifrada privada, que combina el cifrado con el comportamiento del canal de caché:


APIPusher.Subscribe('my-encrypted-cache-channel', pscPrivateEncryptedCacheChannel);

Al utilizar el evento OnPusherAuthentication con canales privados cifrados, puede establecer la propiedad SharedSecret en el objeto de respuesta para proporcionar la clave de cifrado:


procedure OnPusherAuthenticationEvent(Sender: TObject;
  AuthRequest: TsgcWSPusherRequestAuthentication;
  AuthResponse: TsgcWSPusherResponseAuthentication);
begin
  AuthResponse.SharedSecret := 'your-shared-secret-key';
end;

Eventos de presencia

Los canales de presencia proporcionan eventos adicionales que notifican a su aplicación cuando los usuarios se unen a un canal o lo abandonan, y permiten realizar un seguimiento de los recuentos de suscripciones.

OnPusherMemberAdded

Se activa cuando un nuevo miembro se suscribe a un canal de presencia. Proporciona el nombre del canal, el ID de usuario y la información del miembro que se ha unido.


procedure PUSHERPusherMemberAdded(Sender: TObject;
  Channel, UserId, UserInfo: string);
begin
  Log('Member joined: ' + UserId + ' on ' + Channel);
end;

OnPusherMemberRemoved

Se activa cuando un miembro cancela la suscripción a un canal de presencia. Proporciona el nombre del canal, el ID de usuario y la información del miembro que abandonó.


procedure PUSHERPusherMemberRemoved(Sender: TObject;
  Channel, UserId, UserInfo: string);
begin
  Log('Member left: ' + UserId + ' on ' + Channel);
end;

OnPusherSubscriptionCount

Se activa cuando el recuento de suscripciones cambia en un canal. Proporciona el nombre del canal y el número actual de suscriptores. Este evento debe estar habilitado en su panel de Pusher.


procedure PUSHERPusherSubscriptionCount(Sender: TObject;
  Channel: string; SubscriptionCount: Integer);
begin
  Log(Channel + ' has ' + IntToStr(SubscriptionCount) + ' subscribers');
end;

OnPusherCacheMiss

Se activa al suscribirse a un canal de caché que no tiene ningún evento en caché. Proporciona el nombre del canal. Esto permite a su aplicación manejar el caso en que no hay datos en caché disponibles, por ejemplo, obteniendo los datos de otra fuente.


procedure PUSHERPusherCacheMiss(Sender: TObject; Channel: string);
begin
  Log('Cache miss on: ' + Channel);
end;

Publicar mensajes

No solo puede recibir mensajes de los canales suscritos, sino que también puede enviar mensajes a otros usuarios suscritos.

Llame al método Publish para enviar un mensaje a todos los usuarios suscritos al canal.

Ejemplo: enviar un evento a todos los usuarios suscritos de "my-channel"


APIPusher.Publish('my-event', 'my-channel');

No publique más de 10 mensajes por segundo por cliente (conexión). Cualquier evento que supere este límite de velocidad será rechazado por la API de Pusher. Esto no es un problema del sistema, sino del cliente. ¡100 clientes en un canal enviando mensajes a esta velocidad también tendrían que procesar cada uno 1.000 mensajes por segundo! Aunque algunos navegadores modernos podrían manejar esto, probablemente no sea una buena idea.

REST API

La API está alojada en http://api-CLUSTER.pusher.com, donde CLUSTER se reemplaza por el clúster de su propia aplicación (por ejemplo, eu).

Los códigos de estado HTTP se utilizan para indicar el éxito o el fracaso de las solicitudes. Los siguientes estados son comunes:

200 Solicitud exitosa. El cuerpo contendrá un hash JSON con los datos de respuesta

Error 400: detalles en el cuerpo de la respuesta

401 Error de autenticación: el cuerpo de la respuesta contendrá una explicación

403 Forbidden: aplicación deshabilitada o cuota de mensajes superada

Se han implementado las siguientes funciones de la API REST.

Función Descripción
TriggerEvent Activa un nuevo evento en el canal especificado. Admite los parámetros opcionales SocketId (para excluir un cliente) e Info.
TriggerBatchEvents Activa múltiples eventos en una sola solicitud HTTP. Acepta un array JSON de objetos de evento.
GetChannels Proporciona una lista de todos los canales activos. Admite los parámetros opcionales FilterByPrefix e Info.
GetChannel Proporciona información sobre un canal específico. Admite un parámetro Info opcional.
GetUsers Proporciona una lista de todos los usuarios conectados a un canal.
TerminateUserConnections Termina todas las conexiones de un usuario determinado mediante su ID de usuario.

TriggerEvent

Dispara un evento en uno o más canales. Requiere el nombre del evento, el nombre del canal y la carga útil de datos.

Parámetro Descripción
aEventName El nombre del evento a disparar.
aChannel El nombre del canal en el que se lanzará el evento.
aData Los datos del evento (cadena JSON).
aSocketId (opcional) Un ID de socket para excluir de la recepción del evento. Útil para evitar que el remitente reciba su propio mensaje.
aInfo (opcional) Una lista separada por comas de atributos a incluir en la respuesta (por ejemplo, "subscription_count").


// trigger event on a channel
APIPusher.TriggerEvent('my-event', 'my-channel', 'Hello World');

// trigger event excluding the sender
APIPusher.TriggerEvent('my-event', 'my-channel', 'Hello World', '123.456');

// trigger event requesting subscription_count in the response
APIPusher.TriggerEvent('my-event', 'my-channel', 'Hello World', '', 'subscription_count');

TriggerBatchEvents

Activa múltiples eventos en una sola llamada a la API, lo que resulta más eficiente que realizar solicitudes separadas para cada evento. El parámetro batch debe ser una cadena JSON que contenga un array de objetos de evento, donde cada objeto tiene los campos "channel", "name" y "data".


APIPusher.TriggerBatchEvents(
  '[{"channel":"my-channel","name":"my-event","data":"hello"},' +
  '{"channel":"my-channel-2","name":"my-event","data":"world"}]');

GetChannels

Devuelve una lista de canales activos. Admite parámetros opcionales para filtrar los resultados y solicitar información adicional.

Parámetro Descripción
aFilterByPrefix (opcional) Filtrar canales por un prefijo de nombre (p. ej., "presence-" para listar solo los canales de presencia).
aInfo (opcional) Una lista separada por comas de atributos a incluir en la respuesta (p. ej. "user_count").


// get all channels
APIPusher.GetChannels;

// get only presence channels with user count
APIPusher.GetChannels('presence-', 'user_count');

GetChannel

Devuelve información sobre un canal específico.

Parámetro Descripción
aChannel El nombre del canal sobre el que se desea obtener información.
aInfo (opcional) Una lista separada por comas de atributos a incluir (p. ej., "user_count,subscription_count").


// get channel info
APIPusher.GetChannel('presence-my-channel');

// get channel info with user count
APIPusher.GetChannel('presence-my-channel', 'user_count,subscription_count');

GetUsers

Devuelve una lista de usuarios conectados a un canal de presencia. El nombre del canal debe incluir el prefijo completo (p. ej. "presence-my-channel").


APIPusher.GetUsers('presence-my-channel');

TerminateUserConnections

Termina todas las conexiones establecidas por un usuario determinado. Esto se puede usar para forzar a un usuario específico a desconectarse de todos los canales. El ID de usuario debe coincidir con el "user_id" utilizado cuando el usuario se suscribió a un canal de presencia.


APIPusher.TerminateUserConnections('1234');

Autenticación personalizada

Pusher solo permite suscribirse a canales privados o de presencia; si la conexión proporciona un token de autenticación, esto le permite restringir el acceso.

Puede crear su propio flujo de autenticación utilizando el evento OnPusherAuthentication; este evento se llama antes de que el mensaje de suscripción se firme con la clave secreta proporcionada por Pusher. Este evento tiene 2 parámetros: una solicitud de autenticación con campos como SocketId, nombre del canal... que puede utilizar su propio servidor de autenticación para autenticar o no la solicitud. A continuación encontrará una captura de pantalla que muestra el flujo de autenticación de Pusher.

Cuando un cliente se conecta al servidor pusher, envía la clave proporcionada por pusher y el servidor devuelve un identificador de identificación (socket_id).

Cuando un cliente se suscribe a un canal privado (o de presencia), el cliente sgcWebSockets utiliza la clave secreta proporcionada por pusher para crear una firma que se incluye en el mensaje de suscripción. Mediante el evento OnPusherAutentication, puede capturar los campos necesarios para firmar el mensaje, implementar sus propios métodos de autenticación y, si estos tienen éxito, devolver la firma, que se incluirá en el mensaje de suscripción y se enviará al servidor.

Ejemplo:


oClient := TsgcWebSocketClient.Create(nil);
oPusher := TsgcWSAPI_Pusher.Create(nil);
oPusher.Client := oClient;
oPusher.Cluster := 'eu';
Pusher.Name := 'js';
Pusher.Version := '4.1';
Pusher.TLS := True;
Pusher.Key := '9c3b7ef25qe97a00116c';
Pusher.Secret := ''; // the secret key is not known by the client, only by the authentication module

oPusher.OnPusherAuthentication := OnPusherAuthenticationEvent;

procedure OnPusherAuthenticationEvent(Sender: TObject; AuthRequest: TsgcWSPusherRequestAuthentication;
  AuthResponse: TsgcWSPusherResponseAuthentication);
begin
  // if the authentication request is successful return the signature
  if CustomAuthentication(AuthRequest.Channel, AuthRequest.SocketID) then
    AuthResponse.Signature := GetCustomAuthenticationSignature;
end;

El formato de la firma es:

Canales privados: key:HMAC256(SocketID, ChannelName)

Canales Presence: clave: HMAC256(SocketID, ChannelName, Data)

El objeto TsgcWSPusherResponseAuthentication proporciona las siguientes propiedades:

Propiedad Descripción
Secreto La clave secreta de Pusher utilizada para calcular la firma HMAC. Prellenada con Pusher.Secret si está configurado.
Firma La firma de autenticación calculada. Si se deja vacía, el componente la calculará automáticamente usando el Secret.
SharedSecret La clave secreta compartida para canales privados cifrados. Requerida al suscribirse a pscPrivateEncryptedChannel o pscPrivateEncryptedCacheChannel. Se utiliza para el cifrado de extremo a extremo de los datos del mensaje.