Komponent TsgcWS_API_Pusher został zaktualizowany, aby był zgodny z najnowszą
specyfikacją protokołu Pusher Channels.
Ta wersja wprowadza obsługę kanałów private-encrypted, cztery nowe zdarzenia kanałów presence i cache,
dwa nowe punkty końcowe REST API, rozszerzone parametry zapytań dla istniejących punktów końcowych i kilka poprawek błędów.
Wszystkie zmiany są wstecznie zgodne — istniejący kod działa bez modyfikacji.
Spis treści
- Obsługa kanałów private-encrypted
- Nowe zdarzenia WebSocket
- Nowe metody REST API
- Zaktualizowane metody REST API
- Poprawki błędów
- Podsumowanie
1. Obsługa kanałów private-encrypted
Pusher Channels obsługuje kanały private-encrypted, które zapewniają szyfrowanie end-to-end danych zdarzeń
za pomocą NaCl Secretbox (XSalsa20-Poly1305). Serwery Pusher nigdy nie widzą tekstu jawnego — tylko
komunikujące się klienty mogą odszyfrować wiadomości. Do wyliczenia
TsgcWSPusherChannels dodano dwa nowe typy kanałów:
| Wartość wyliczenia | Prefiks kanału | Opis |
|---|---|---|
pscPrivateEncryptedChannel |
private-encrypted- |
Prywatny kanał z szyfrowaniem end-to-end. Dane zdarzeń są szyfrowane wspólnym sekretem per-kanał. |
pscPrivateEncryptedCacheChannel |
private-encrypted-cache- |
Jak powyżej, plus zachowanie kanału cache — ostatnie zdarzenie jest dostarczane nowym subskrybentom. |
Klasa TsgcWSPusherResponseAuthentication zawiera teraz właściwość
SharedSecret. Przy subskrypcji kanału
private-encrypted- twój punkt końcowy autoryzacji musi zwrócić
zakodowany w base64 sekret per-kanał. Ustaw tę wartość w procedurze obsługi zdarzenia
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;
Subskrybowanie kanału szyfrowanego
// 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);
Publikowanie na kanale szyfrowanym
// Client events work on private-encrypted channels just like private channels
sgcPusher.Publish('my-event', 'my-secret-channel',
pscPrivateEncryptedChannel, '{"message":"Hello encrypted!"}');
2. Nowe zdarzenia WebSocket
Dodano cztery nowe zdarzenia obsługujące wewnętrzne komunikaty protokołu Pusher, które wcześniej nie były obsługiwane.
Zdarzenia te są wywoływane automatycznie, gdy do połączenia WebSocket dotrą odpowiednie
wiadomości pusher_internal:.
| Właściwość zdarzenia | Komunikat protokołu | Opis |
|---|---|---|
OnPusherMemberAdded |
pusher_internal:member_added |
Wywoływane gdy nowy użytkownik dołącza do kanału presence. Dostarcza nazwę kanału, ID użytkownika i informacje o nim. |
OnPusherMemberRemoved |
pusher_internal:member_removed |
Wywoływane gdy użytkownik opuszcza kanał presence. Dostarcza nazwę kanału, ID użytkownika i informacje o nim. |
OnPusherSubscriptionCount |
pusher_internal:subscription_count |
Wywoływane gdy zmienia się liczba subskrypcji kanału. Musi być włączone w panelu Pusher. |
OnPusherCacheMiss |
pusher_internal:cache_miss |
Wywoływane przy subskrybowaniu kanału cache, gdy nie ma dostępnego zbuforowanego zdarzenia. |
OnPusherMemberAdded / OnPusherMemberRemoved
Te zdarzenia używają nowego typu wywołania zwrotnego TsgcWSPusherMemberEvent,
który dostarcza nazwę kanału, ID użytkownika i informacje o nim jako osobne parametry:
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
Używa nowego typu wywołania zwrotnego TsgcWSPusherSubscriptionCountEvent.
To zdarzenie wymaga włączenia funkcji Subscription Count w ustawieniach panelu 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
Używa nowego typu wywołania zwrotnego TsgcWSPusherCacheMissEvent.
To zdarzenie jest wywoływane przy subskrypcji kanału cache (cache-,
private-cache-,
private-encrypted-cache- lub
presence-cache-), gdy nie ma dostępnego zbuforowanego zdarzenia.
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. Nowe metody REST API
Do komponentu TsgcWS_API_Pusher dodano dwie nowe metody REST API po stronie serwera,
obejmujące punkt końcowy zdarzeń wsadowych
i zakończenie połączeń użytkownika.
| Metoda | Pusher Endpoint | Opis |
|---|---|---|
TriggerBatchEvents |
POST /apps/{app_id}/batch_events |
Wyzwala do 10 zdarzeń w jednym żądaniu HTTP. Każde zdarzenie może trafiać do innego kanału. |
TerminateUserConnections |
POST /apps/{app_id}/users/{user_id}/terminate_connections |
Kończy wszystkie połączenia WebSocket dla określonego uwierzytelnionego użytkownika. |
TriggerBatchEvents
function TriggerBatchEvents(const aBatch: String): String;
Parametr aBatch to ciąg JSON zawierający tablicę
batch obiektów zdarzeń. Każdy obiekt musi zawierać
channel,
name i
data. Maksymalnie 10 zdarzeń na wsad.
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;
Wymusza zakończenie wszystkich aktywnych połączeń WebSocket dla danego użytkownika. Przydatne do wylogowywania użytkownika na wszystkich jego urządzeniach lub cofania dostępu po zmianie uprawnień. Wymaga skonfigurowania uwierzytelniania użytkowników Pusher.
var
vResult: string;
begin
// Disconnect user "user-123" from all sessions
vResult := sgcPusher.TerminateUserConnections('user-123');
Memo1.Lines.Add(vResult);
end;
4. Zaktualizowane metody REST API
Trzy istniejące metody REST API zostały rozszerzone o dodatkowe opcjonalne parametry. Ponieważ nowe parametry mają wartości domyślne, istniejący kod jest w pełni wstecznie zgodny.
TriggerEvent
Poprzednia sygnatura
function TriggerEvent(const aEventName, aChannel, aData: String): String;
Nowa sygnatura
function TriggerEvent(const aEventName, aChannel, aData: String;
const aSocketId: String = '';
const aInfo: String = ''): String;
| Parametr | Opis |
|---|---|
aSocketId |
Wyklucza to ID gniazda z odbierania zdarzenia. Przydatne do zapobiegania, aby nadawca nie odbierał własnej transmisji. |
aInfo |
Rozdzielona przecinkami lista atrybutów do zwrócenia. Prawidłowe wartości: 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
Poprzednia sygnatura
function GetChannels: String;
Nowa sygnatura
function GetChannels(
const aFilterByPrefix: String = '';
const aInfo: String = ''): String;
| Parametr | Opis |
|---|---|
aFilterByPrefix |
Filtruje zwracane kanały według prefiksu nazwy. Przykład: presence- zwraca tylko kanały presence. |
aInfo |
Atrybuty rozdzielone przecinkami. Prawidłowe wartości: user_count (tylko 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
Poprzednia sygnatura
function GetChannel(const aChannel: String): String;
Nowa sygnatura
function GetChannel(const aChannel: String;
const aInfo: String = ''): String;
| Parametr | Opis |
|---|---|
aInfo |
Atrybuty rozdzielone przecinkami. Prawidłowe wartości: 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. Poprawki błędów
Several bugs were identified and corrected in this release:
| Błąd | Wpływ | Poprawka |
|---|---|---|
Typo in DoReadEvent: 'puserh:ping' |
Krytyczny Pingi serwera nigdy nie były rozpoznawane, co powodowało pomijanie żądań heartbeat przez klienta i mogło skutkować rozłączeniem klienta przez serwer z powodu braku aktywności. | Poprawiono na 'pusher:ping'. |
DoSendPong null access |
Wysoki Dostęp do JSON.Node['data'].Value bez sprawdzenia null mógł powodować naruszenie dostępu, gdy wiadomość ping nie miała pola data. |
Dodano sprawdzenie null; domyślnie {} gdy brak pola data. |
GetUsers hardcoded prefix |
Wysoki Metoda zawsze dodawała prefiks presence- do nazwy kanału, podwajając go gdy użytkownik podał już pełną nazwę (np. presence-presence-room). |
Usunięto stały prefiks. Użytkownicy powinni teraz podawać pełną nazwę kanału wraz z prefiksem presence-. |
GetUsers double semicolon |
Niski Na końcu metody znajdował się zbędny podwójny średnik ;;. |
Usunięto dodatkowy średnik. |
Zmiana niekompatybilna w GetUsers: Metoda GetUsers nie dodaje już
automatycznie prefiksu presence-. Jeśli twój kod przekazuje tylko nazwę kanału
bez prefiksu (np. GetUsers('my-room')), musisz zaktualizować go do
pełnej nazwy: GetUsers('presence-my-room').
6. Podsumowanie
| Kategoria | Liczba | Szczegóły |
|---|---|---|
| Nowe typy kanałów | 2 | pscPrivateEncryptedChannel, pscPrivateEncryptedCacheChannel |
| Nowe zdarzenia WebSocket | 4 | OnPusherMemberAdded, OnPusherMemberRemoved, OnPusherSubscriptionCount, OnPusherCacheMiss |
| Nowe metody REST | 2 | TriggerBatchEvents, TerminateUserConnections |
| Zaktualizowane metody REST | 3 | TriggerEvent (+socket_id, +info), GetChannels (+filter, +info), GetChannel (+info) |
| Nowe właściwości | 1 | SharedSecret on TsgcWSPusherResponseAuthentication |
| Poprawki błędów | 4 | Literówka w ping, dostęp null w pong, prefiks GetUsers, podwójny średnik |
Wszystkie zmiany są wstecznie zgodne. Nowe parametry metod mają wartości domyślne, a nowe właściwości zdarzeń
są opcjonalne. Jedyną zmianą behawioralną jest
GetUsers, który nie dodaje już automatycznie prefiksu
presence-.
