Il componente TsgcWS_API_Pusher è stato aggiornato per allinearsi all'ultima
Pusher Channels protocol specification.
Questa release introduce il supporto per canali private-encrypted, quattro nuovi eventi per canali presence e cache,
due nuovi endpoint REST API, parametri di query migliorati per gli endpoint esistenti e diverse correzioni di bug.
Tutte le modifiche sono retrocompatibili: il codice esistente continua a funzionare senza modifiche.
Indice
- Supporto canali private-encrypted
- Nuovi eventi WebSocket
- Nuovi metodi REST API
- Metodi REST API aggiornati
- Bug fix
- Riepilogo
1. Supporto canali private-encrypted
Pusher Channels supporta i canali private-encrypted che forniscono la cifratura end-to-end dei dati degli eventi
usando NaCl Secretbox (XSalsa20-Poly1305). I server Pusher non vedono mai il testo in chiaro: solo i client
in comunicazione possono decifrare i messaggi. Due nuovi tipi di canale sono stati aggiunti all'enumerazione
TsgcWSPusherChannels:
| Valore enum | Prefisso del canale | Descrizione |
|---|---|---|
pscPrivateEncryptedChannel |
private-encrypted- |
Canale privato cifrato end-to-end. I payload dei dati sono cifrati con un segreto condiviso per canale. |
pscPrivateEncryptedCacheChannel |
private-encrypted-cache- |
Come sopra, più il comportamento di cache channel: l'ultimo evento viene consegnato ai nuovi sottoscrittori. |
La classe TsgcWSPusherResponseAuthentication ora include la proprietà
SharedSecret. Quando ti sottoscrivi a un canale
private-encrypted-, il tuo endpoint di autorizzazione deve restituire
il segreto condiviso per canale codificato in base64. Imposta questo valore nel
gestore di eventi OnPusherAuthentication:
procedure TForm1.sgcPusherAuthentication(Sender: TObject;
AuthRequest: TsgcWSPusherRequestAuthentication;
AuthResponse: TsgcWSPusherResponseAuthentication);
begin
// For private-encrypted channels, set the shared secret
// returned by your authorization server
AuthResponse.Secret := 'your-app-secret';
AuthResponse.SharedSecret := 'base64-encoded-per-channel-key';
end;
Sottoscrizione a un canale cifrato
// Subscribe to a private-encrypted channel
sgcPusher.Subscribe('my-secret-channel', pscPrivateEncryptedChannel);
// Subscribe to a private-encrypted cache channel
sgcPusher.Subscribe('my-secret-cache', pscPrivateEncryptedCacheChannel);
Pubblicazione su un canale cifrato
// Client events work on private-encrypted channels just like private channels
sgcPusher.Publish('my-event', 'my-secret-channel',
pscPrivateEncryptedChannel, '{"message":"Hello encrypted!"}');
2. Nuovi eventi WebSocket
Sono stati aggiunti quattro nuovi eventi per gestire i messaggi di protocollo interno di Pusher che prima non erano gestiti.
Questi eventi vengono attivati automaticamente quando i corrispondenti messaggi
pusher_internal: arrivano sulla connessione WebSocket.
| Proprietà evento | Messaggio di protocollo | Descrizione |
|---|---|---|
OnPusherMemberAdded |
pusher_internal:member_added |
Attivato quando un nuovo utente entra in un canale presence. Fornisce il nome del canale, l'ID utente e le info utente. |
OnPusherMemberRemoved |
pusher_internal:member_removed |
Attivato quando un utente esce da un canale presence. Fornisce il nome del canale, l'ID utente e le info utente. |
OnPusherSubscriptionCount |
pusher_internal:subscription_count |
Attivato quando cambia il conteggio delle sottoscrizioni di un canale. Deve essere abilitato nella dashboard Pusher. |
OnPusherCacheMiss |
pusher_internal:cache_miss |
Attivato quando ci si sottoscrive a un cache channel che non ha alcun evento in cache disponibile. |
OnPusherMemberAdded / OnPusherMemberRemoved
Questi eventi usano il nuovo tipo di callback TsgcWSPusherMemberEvent,
che fornisce il nome del canale, l'ID utente e le info utente come parametri separati:
TsgcWSPusherMemberEvent = procedure(Sender: TObject;
Channel, UserId, UserInfo: String) of object;
procedure TForm1.sgcPusherMemberAdded(Sender: TObject;
Channel, UserId, UserInfo: String);
begin
Memo1.Lines.Add('User joined: ' + UserId + ' on ' + Channel);
if UserInfo '' then
Memo1.Lines.Add(' Info: ' + UserInfo);
end;
procedure TForm1.sgcPusherMemberRemoved(Sender: TObject;
Channel, UserId, UserInfo: String);
begin
Memo1.Lines.Add('User left: ' + UserId + ' from ' + Channel);
end;
OnPusherSubscriptionCount
Usa il nuovo tipo di callback TsgcWSPusherSubscriptionCountEvent.
Questo evento richiede che la funzionalità Subscription Count sia abilitata nelle impostazioni della dashboard Pusher.
TsgcWSPusherSubscriptionCountEvent = procedure(Sender: TObject;
Channel: String; SubscriptionCount: Integer) of object;
procedure TForm1.sgcPusherSubscriptionCount(Sender: TObject;
Channel: String; SubscriptionCount: Integer);
begin
Memo1.Lines.Add(Channel + ' now has ' + IntToStr(SubscriptionCount) +
' subscribers');
end;
OnPusherCacheMiss
Usa il nuovo tipo di callback TsgcWSPusherCacheMissEvent.
Questo evento viene attivato quando ti sottoscrivi a un cache channel (cache-,
private-cache-,
private-encrypted-cache- o
presence-cache-) e non è disponibile alcun evento in cache.
TsgcWSPusherCacheMissEvent = procedure(Sender: TObject;
Channel: String) of object;
procedure TForm1.sgcPusherCacheMiss(Sender: TObject; Channel: String);
begin
Memo1.Lines.Add('No cached event for channel: ' + Channel);
end;
3. Nuovi metodi REST API
Sono stati aggiunti due nuovi metodi REST API server-side al componente
TsgcWS_API_Pusher, che coprono
l'endpoint batch events e la terminazione delle connessioni utente.
| Metodo | Endpoint Pusher | Descrizione |
|---|---|---|
TriggerBatchEvents |
POST /apps/{app_id}/batch_events |
Attiva fino a 10 eventi in una singola richiesta HTTP. Ogni evento può puntare a un canale diverso. |
TerminateUserConnections |
POST /apps/{app_id}/users/{user_id}/terminate_connections |
Termina tutte le connessioni WebSocket per un utente autenticato specifico. |
TriggerBatchEvents
function TriggerBatchEvents(const aBatch: String): String;
Il parametro aBatch è una stringa JSON che contiene un
array batch di oggetti evento. Ogni oggetto deve includere
channel,
name e
data. Massimo 10 eventi per batch.
var
vBatch, vResult: string;
begin
vBatch :=
'{"batch": [' +
' {"channel": "my-channel-1", "name": "my-event", "data": "{\"msg\":\"hello\"}"}' + ',' +
' {"channel": "my-channel-2", "name": "my-event", "data": "{\"msg\":\"world\"}"}' +
']}';
vResult := sgcPusher.TriggerBatchEvents(vBatch);
Memo1.Lines.Add(vResult);
end;
TerminateUserConnections
function TerminateUserConnections(const aUserId: String): String;
Termina forzatamente tutte le connessioni WebSocket attive per un dato utente. È utile per disconnettere un utente da tutti i suoi dispositivi o revocare l'accesso dopo una modifica dei permessi. Richiede che User Authentication di Pusher sia configurato.
var
vResult: string;
begin
// Disconnect user "user-123" from all sessions
vResult := sgcPusher.TerminateUserConnections('user-123');
Memo1.Lines.Add(vResult);
end;
4. Metodi REST API aggiornati
Tre metodi REST API esistenti sono stati arricchiti con parametri opzionali aggiuntivi. Poiché i nuovi parametri hanno tutti valori predefiniti, il codice esistente è pienamente retrocompatibile.
TriggerEvent
Firma precedente
function TriggerEvent(const aEventName, aChannel, aData: String): String;
Nuova firma
function TriggerEvent(const aEventName, aChannel, aData: String;
const aSocketId: String = '';
const aInfo: String = ''): String;
| Parametro | Descrizione |
|---|---|
aSocketId |
Escludi questo socket ID dalla ricezione dell'evento. Utile per evitare che il mittente riceva il proprio broadcast. |
aInfo |
Lista di attributi separati da virgola da restituire. Valori validi: subscription_count, user_count. |
var
vResult: string;
begin
// Trigger event, exclude the sender, and request subscription count
vResult := sgcPusher.TriggerEvent('my-event', 'my-channel',
'{"msg":"hello"}', sgcPusher.FSocket_id, 'subscription_count');
Memo1.Lines.Add(vResult);
// Response: {"channels":{"my-channel":{"subscription_count":5}}}
end;
GetChannels
Previous Signature
function GetChannels: String;
New Signature
function GetChannels(
const aFilterByPrefix: String = '';
const aInfo: String = ''): String;
| Parametro | Descrizione |
|---|---|
aFilterByPrefix |
Filtra i canali restituiti per prefisso del nome. Esempio: presence- restituisce solo i canali presence. |
aInfo |
Attributi separati da virgola. Valori validi: user_count (solo presence), subscription_count. |
var
vResult: string;
begin
// List all presence channels with user counts
vResult := sgcPusher.GetChannels('presence-', 'user_count');
Memo1.Lines.Add(vResult);
// Response: {"channels":{"presence-room":{"user_count":3}}}
// List all channels (no filter) - backward-compatible call
vResult := sgcPusher.GetChannels;
Memo1.Lines.Add(vResult);
end;
GetChannel
Previous Signature
function GetChannel(const aChannel: String): String;
New Signature
function GetChannel(const aChannel: String;
const aInfo: String = ''): String;
| Parametro | Descrizione |
|---|---|
aInfo |
Attributi separati da virgola. Valori validi: subscription_count, user_count, cache. |
var
vResult: string;
begin
// Get channel info with subscription count and user count
vResult := sgcPusher.GetChannel('presence-room',
'subscription_count,user_count');
Memo1.Lines.Add(vResult);
// Response: {"occupied":true,"subscription_count":5,"user_count":3}
// Get basic channel info - backward-compatible call
vResult := sgcPusher.GetChannel('my-channel');
Memo1.Lines.Add(vResult);
end;
5. Bug fix
In questa release sono stati identificati e corretti diversi bug:
| Bug | Impatto | Correzione |
|---|---|---|
Typo in DoReadEvent: 'puserh:ping' |
Critico i ping del server non venivano mai riconosciuti, facendo perdere al client le richieste di heartbeat. Questo poteva portare il server a disconnettere il client per inattività. | Corretto in 'pusher:ping'. |
DoSendPong null access |
Alto accedere a JSON.Node['data'].Value senza controllo null poteva causare una access violation se il messaggio di ping non ha campo data. |
Aggiunto controllo null; default a {} quando data è assente. |
GetUsers hardcoded prefix |
Alto il metodo anteponeva sempre presence- al nome del canale, raddoppiando il prefisso se l'utente passava già il nome completo del canale (ad es. presence-presence-room). |
Rimosso il prefisso hardcoded. Gli utenti ora devono passare il nome completo del canale incluso il prefisso presence-. |
GetUsers double semicolon |
Basso alla fine del metodo era presente un doppio punto e virgola ;;. |
Rimosso il punto e virgola extra. |
Breaking change in GetUsers: il metodo GetUsers non antepone più
automaticamente presence-. Se il tuo codice passa solo il nome del canale
senza il prefisso (ad es. GetUsers('my-room')), devi aggiornarlo per
includere il nome completo: GetUsers('presence-my-room').
6. Riepilogo
| Categoria | Conteggio | Dettagli |
|---|---|---|
| Nuovi tipi di canale | 2 | pscPrivateEncryptedChannel, pscPrivateEncryptedCacheChannel |
| Nuovi eventi WebSocket | 4 | OnPusherMemberAdded, OnPusherMemberRemoved, OnPusherSubscriptionCount, OnPusherCacheMiss |
| Nuovi metodi REST | 2 | TriggerBatchEvents, TerminateUserConnections |
| Metodi REST aggiornati | 3 | TriggerEvent (+socket_id, +info), GetChannels (+filter, +info), GetChannel (+info) |
| Nuove proprietà | 1 | SharedSecret on TsgcWSPusherResponseAuthentication |
| Bug fix | 4 | Refuso nel ping, accesso null nel pong, prefisso di GetUsers, doppio punto e virgola |
Tutte le modifiche sono retrocompatibili. I nuovi parametri dei metodi usano valori predefiniti e le nuove proprietà di evento
sono opzionali. L'unico cambio di comportamento è in
GetUsers, che non antepone più automaticamente il prefisso
presence-.
