Pusher to łatwa i niezawodna platforma z przydatnymi funkcjami opartymi na protokole WebSocket: elastyczna obsługa wiadomości pub/sub, listy użytkowników na żywo (presence), uwierzytelnianie i wiele innych.
Pusher WebSocket API ma wersję 7.
Dane są przesyłane dwukierunkowo przez WebSocket jako dane tekstowe zawierające JSON zakodowany w UTF-8 (binarne ramki WebSocket nie są obsługiwane).
Można wywołać metodę Ping, aby przetestować połączenie z serwerem. Zasadniczo każda wiadomość odebrana od drugiej strony jest traktowana jako potwierdzenie aktywności połączenia. W przypadku braku wiadomości każda ze stron może sprawdzić, czy druga strona odpowiada, wysyłając wiadomość ping, na którą druga strona powinna odpowiedzieć wiadomością pong.
Przed nawiązaniem połączenia należy wypełnić następujące pola:
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)
Ważne
Pusher wymaga, aby klient WebSocket łączył się z adresem URL zbudowanym na podstawie wcześniejszych pól (klucz, klaster...). Pola te są używane do budowania adresu URL i dzieje się to w momencie przypisania klienta do komponentu Pusher. Dlatego, aby upewnić się, że adres URL jest prawidłowo zbudowany, należy ustawić klienta po wypełnieniu pól konfiguracyjnych Pusher. Poniżej znajduje się pseudokod:
// configure pusher fields
pusher.cluster = ...
pusher.key = ...
// ustaw klienta
pusher.client = websocket client
// start connection
websocket client.Active = true;
Po pomyślnym nawiązaniu połączenia wywoływane jest zdarzenie OnPusherConnect, które udostępnia następujące pola:
Socket ID: Unikalny identyfikator podłączonego klienta.
Timeout: Liczba sekund bezczynności serwera, po upływie których klient powinien zainicjować wiadomość ping (obsługiwane automatycznie przez komponent).
W przypadku błędu zostanie wywołane zdarzenie OnPusherError wraz z informacjami o błędzie. Błąd może zostać wysłany przez Pusher w odpowiedzi na nieprawidłowe uwierzytelnienie, nieprawidłowe polecenie itp.
4000-4099
Wskazuje błąd powodujący zamknięcie połączenia przez Pusher, przy czym próba ponownego połączenia z tymi samymi parametrami nie powiedzie się.
4000: Aplikacja akceptuje tylko połączenia SSL, należy ponownie połączyć używając wss://
4001: Aplikacja nie istnieje
4003: Aplikacja wyłączona
4004: Aplikacja przekroczyła limit połączeń
4005: Ścieżka nie znaleziona
4006: Nieprawidłowy format ciągu wersji
4007: Nieobsługiwana wersja protokołu
4008: Nie podano wersji protokołu
4100-4199
Oznacza błąd powodujący zamknięcie połączenia przez Pusher; klient może ponownie nawiązać połączenie po upływie co najmniej 1 sekundy.
4100: Przekroczono pojemność
4200-4299
Wskazuje błąd skutkujący zamknięciem połączenia przez Pusher i informuje, że klient może natychmiast ponownie nawiązać połączenie.
4200: Natychmiastowe ponowne połączenie ogólne
4201: Nie otrzymano odpowiedzi Pong: do klienta wysłano Ping, ale nie odebrano odpowiedzi — patrz wiadomości ping i pong.
4202: Zamknięto z powodu braku aktywności: Klient był nieaktywny przez długi czas (obecnie 24 godziny), a klient nie obsługuje polecenia ping. Należy zaktualizować do nowszej wersji roboczej WebSocket lub zaimplementować wersję 5 lub wyższą tego protokołu.
4300-4399
Każdy inny rodzaj błędu.
4301: Zdarzenie klienta odrzucone z powodu ograniczenia przepustowości
Kanały są fundamentalną koncepcją w Pusher. Każda aplikacja posiada wiele kanałów, a każdy klient może wybierać, które kanały subskrybuje.
Kanały zapewniają:
Sposób filtrowania danych. Na przykład w aplikacji czatu może istnieć kanał dla osób chcących dyskutować o „psach".
Sposób kontrolowania dostępu do różnych strumieni informacji. Na przykład aplikacja do zarządzania projektami może chcieć autoryzować użytkowników do otrzymywania aktualizacji dotyczących 'projectX'
Zdecydowanie zaleca się filtrowanie danych przy użyciu kanałów, a nie zdarzeń. Wynika to z faktu, że wszystkie zdarzenia publikowane na kanale są wysyłane do wszystkich subskrybentów, niezależnie od ich powiązań ze zdarzeniami.
Kanały nie wymagają jawnego tworzenia i są tworzone na żądanie klienta. Oznacza to, że tworzenie kanału jest proste. Wystarczy poinformować klienta, aby subskrybował dany kanał.
Obsługiwane są następujące typy kanałów:
Kanały publiczne mogą subskrybować wszyscy, którzy znają ich nazwę
Kanały prywatne wprowadzają mechanizm pozwalający serwerowi kontrolować dostęp do rozgłaszanych danych
Kanały presence są rozszerzeniem kanałów prywatnych. Umożliwiają rejestrowanie informacji o użytkowniku przy subskrypcji oraz informowanie innych członków kanału o tym, kto jest online.
Kanały pamięci podręcznej zapamiętują ostatnie wywołane zdarzenie i wysyłają je jako pierwsze zdarzenie do nowych subskrybentów (warianty publiczne, prywatne i presence)
Prywatne kanały szyfrowane zapewniają szyfrowanie end-to-end przy użyciu NaCl secretbox, gwarantując, że nawet Pusher nie może odczytać danych wiadomości.
Kanały publiczne powinny być używane do publicznie dostępnych danych, ponieważ nie wymagają żadnej formy autoryzacji w celu subskrypcji.
Można subskrybować i anulować subskrypcję kanałów w dowolnym momencie. Nie ma potrzeby czekania na zakończenie łączenia przez Pusher.
Przykład: subskrypcja kanału „my-channel".
Delphi
APIPusher.Subscribe('my-channel');
W przypadku pomyślnej subskrypcji zostanie wywołane zdarzenie OnPusherSubscribe; w przypadku błędu wiadomość zostanie przekazana za pośrednictwem zdarzenia OnPusherError.
Wszystkie wiadomości z subskrybowanego kanału będą odbierane przez zdarzenie OnPusherEvent.
Gdy wywoływana jest metoda Publish i kanał jest publiczny, komponent zamiast protokołu WebSocket używa protokołu HTTP i wywołuje metodę TriggerEvent (publikowanie przez protokół WebSocket nie jest dozwolone).
Wymaga Indy w wersji 10.5.7 lub nowszej
Kanały prywatne powinny być używane, gdy dostęp do kanału musi być w jakiś sposób ograniczony. Aby użytkownik mógł subskrybować kanał prywatny, wymagana jest autoryzacja.
Przykład: subskrybowanie kanału „my-private-channel".
Delphi
APIPusher.Subscribe('my-private-channel', pscPrivateChannel);
W przypadku pomyślnej subskrypcji zostanie wywołane zdarzenie OnPusherSubscribe; w przypadku błędu wiadomość zostanie przekazana za pośrednictwem zdarzenia OnPusherError.
Wszystkie wiadomości z subskrybowanego kanału będą odbierane przez zdarzenie OnPusherEvent.
Wymaga Indy w wersji 10.5.7 lub nowszej
Kanały Presence opierają się na bezpieczeństwie kanałów prywatnych i udostępniają dodatkową funkcję informowania o tym, kto jest subskrybentem danego kanału. Umożliwia to niezwykle łatwe tworzenie czatów i funkcji „kto jest online" w aplikacji. Doskonale sprawdza się w pokojach czatowych, przy współpracy nad dokumentem, przeglądaniu tej samej strony internetowej czy udziale w grze wieloosobowej.
Kanały obecności są subskrybowane z poziomu API klienta w taki sam sposób jak kanały prywatne, lecz nazwa kanału musi być poprzedzona prefiksem presence-. Podobnie jak w przypadku kanałów prywatnych, żądanie HTTP jest wysyłane do konfigurowalnego adresu URL uwierzytelniania w celu sprawdzenia, czy bieżący użytkownik ma uprawnienia dostępu do kanału.
Informacje o użytkownikach subskrybujących i anulujących subskrypcję kanału są dostępne poprzez powiązanie ze zdarzeniami na kanale presence, a bieżący stan użytkowników subskrybujących kanał jest dostępny za pomocą właściwości channel.members.
Przykład: subskrypcja kanału "my-presence-channel".
APIPusher.Subscribe('my-presence-channel', pscPresenceChannel,
'{"user_id":"John_Smith","user_info":{"name":"John Smith"}}')
W przypadku pomyślnej subskrypcji zostanie wywołane zdarzenie OnPusherSubscribe; w przypadku błędu wiadomość zostanie przekazana za pośrednictwem zdarzenia OnPusherError.
Wszystkie wiadomości z subskrybowanego kanału będą odbierane przez zdarzenie OnPusherEvent.
Kanał pamięci podręcznej zapamiętuje ostatnie wywołane zdarzenie i wysyła je jako pierwsze zdarzenie do nowych subskrybentów.
Gdy zdarzenie jest wywoływane na kanale pamięci podręcznej, Pusher Channels zapisuje to zdarzenie w pamięci, a gdy klient subskrybuje kanał pamięci podręcznej, jeżeli istnieje wartość w pamięci podręcznej, jest ona wysyłana do klienta jako pierwsze zdarzenie na tym kanale. To zachowanie pozwala programistom dostarczać stan początkowy bez dodawania dodatkowej logiki pobierania danych z innych źródeł.
Obsługiwane są następujące kanały pamięci podręcznej:
Przykład: subskrypcja publicznego kanału pamięci podręcznej "my-cache-channel".
APIPusher.Subscribe('my-cache-channel', pscCacheChannel);
W przypadku pomyślnej subskrypcji zostanie wywołane zdarzenie OnPusherSubscribe; w przypadku błędu wiadomość zostanie przekazana za pośrednictwem zdarzenia OnPusherError.
Wszystkie wiadomości z subskrybowanego kanału będą odbierane przez zdarzenie OnPusherEvent.
Jeśli podczas subskrybowania kanału cache nie istnieje żadne zbuforowane zdarzenie, zostanie wywołane zdarzenie OnPusherCacheMiss z podaniem nazwy kanału. Umożliwia to aplikacji obsługę sytuacji, w której żadne dane z pamięci podręcznej nie są dostępne.
Kanały prywatne szyfrowane zapewniają szyfrowanie end-to-end wiadomości. Podobnie jak kanały prywatne wymagają uwierzytelniania, ale dodatkowo wszystkie ładunki danych są szyfrowane przy użyciu NaCl secretbox, dzięki czemu tylko autoryzowani subskrybenci mogą odczytać treść. Nawet Pusher nie może odszyfrować wiadomości.
Aby korzystać z prywatnych zaszyfrowanych kanałów, podczas uwierzytelniania należy podać SharedSecret. Wspólny sekret jest używany do szyfrowania i deszyfrowania danych wiadomości.
Przykład: subskrybuj prywatny zaszyfrowany kanał "my-encrypted-channel".
APIPusher.Subscribe('my-encrypted-channel', pscPrivateEncryptedChannel);
Dostępny jest również wariant prywatny z szyfrowaniem i zachowaniem kanału buforującego:
APIPusher.Subscribe('my-encrypted-cache-channel', pscPrivateEncryptedCacheChannel);
Podczas używania zdarzenia OnPusherAuthentication z prywatnymi kanałami szyfrowanymi można ustawić właściwość SharedSecret w obiekcie odpowiedzi, aby podać klucz szyfrowania:
procedure OnPusherAuthenticationEvent(Sender: TObject;
AuthRequest: TsgcWSPusherRequestAuthentication;
AuthResponse: TsgcWSPusherResponseAuthentication);
begin
AuthResponse.SharedSecret := 'your-shared-secret-key';
end;
Kanały obecności udostępniają dodatkowe zdarzenia powiadamiające aplikację, gdy użytkownicy dołączają do kanału lub go opuszczają, oraz umożliwiają śledzenie liczby subskrypcji.
Wywoływane, gdy nowy członek subskrybuje kanał presence. Udostępnia nazwę kanału, identyfikator użytkownika oraz informacje o użytkowniku, który dołączył.
procedure PUSHERPusherMemberAdded(Sender: TObject;
Channel, UserId, UserInfo: string);
begin
Log('Member joined: ' + UserId + ' on ' + Channel);
end;
Wywoływane, gdy członek anuluje subskrypcję kanału obecności. Dostarcza nazwę kanału, identyfikator użytkownika i informacje o użytkowniku, który opuścił kanał.
procedure PUSHERPusherMemberRemoved(Sender: TObject;
Channel, UserId, UserInfo: string);
begin
Log('Member left: ' + UserId + ' on ' + Channel);
end;
Wywoływane, gdy liczba subskrybentów kanału ulega zmianie. Dostarcza nazwę kanału i bieżącą liczbę subskrybentów. Zdarzenie to musi być włączone w panelu Pusher.
procedure PUSHERPusherSubscriptionCount(Sender: TObject;
Channel: string; SubscriptionCount: Integer);
begin
Log(Channel + ' has ' + IntToStr(SubscriptionCount) + ' subscribers');
end;
Wywoływane przy subskrypcji kanału pamięci podręcznej, który nie zawiera buforowanego zdarzenia. Dostarcza nazwę kanału. Umożliwia to aplikacji obsługę sytuacji, gdy nie są dostępne żadne buforowane dane — na przykład przez pobranie danych z innego źródła.
procedure PUSHERPusherCacheMiss(Sender: TObject; Channel: string);
begin
Log('Cache miss on: ' + Channel);
end;
Nie tylko można odbierać wiadomości z subskrybowanych kanałów, ale również wysyłać wiadomości do innych subskrybowanych użytkowników.
Należy wywołać metodę Publish, aby wysłać wiadomość do wszystkich subskrybentów kanału.
Przykład: wysyłanie zdarzenia do wszystkich subskrybentów kanału "my-channel"
APIPusher.Publish('my-event', 'my-channel');
Publikuj nie więcej niż 10 wiadomości na sekundę na klienta (połączenie). Wszystkie zdarzenia wyzwolone powyżej tego limitu szybkości zostaną odrzucone przez Pusher API. Nie jest to problem systemowy, lecz problem po stronie klienta. 100 klientów w kanale wysyłających wiadomości z taką szybkością musiałoby każdorazowo przetwarzać 1000 wiadomości na sekundę! Chociaż niektóre nowoczesne przeglądarki mogłyby sobie z tym poradzić, prawdopodobnie nie jest to dobry pomysł.
API jest hostowane pod adresem http://api-CLUSTER.pusher.com, gdzie CLUSTER należy zastąpić własnym klastrem aplikacji (np. eu).
Kody stanu HTTP służą do informowania o powodzeniu lub niepowodzeniu żądań. Poniżej przedstawiono typowe kody:
200 Żądanie zostało zrealizowane pomyślnie. Treść odpowiedzi będzie zawierać skrót JSON z danymi odpowiedzi.
400 Błąd: szczegóły w treści odpowiedzi
401 Błąd uwierzytelniania: treść odpowiedzi będzie zawierać wyjaśnienie
403 Forbidden: aplikacja wyłączona lub przekroczony limit wiadomości
Zaimplementowano następujące funkcje REST API.
| Funkcja | Opis |
| TriggerEvent | Wyzwala nowe zdarzenie na określonym kanale. Obsługuje opcjonalne parametry SocketId (wykluczenie klienta) i Info. |
| TriggerBatchEvents | Wyzwala wiele zdarzeń w jednym żądaniu HTTP. Przyjmuje tablicę JSON obiektów zdarzeń. |
| GetChannels | Udostępnia listę wszystkich aktywnych kanałów. Obsługuje opcjonalne parametry FilterByPrefix i Info. |
| GetChannel | Dostarcza informacje o określonym kanale. Obsługuje opcjonalny parametr Info. |
| GetUsers | Dostarcza listę wszystkich użytkowników połączonych z kanałem. |
| TerminateUserConnections | Kończy wszystkie połączenia dla danego użytkownika według jego identyfikatora. |
Wyzwala zdarzenie na jednym lub kilku kanałach. Wymaga nazwy zdarzenia, nazwy kanału i ładunku danych.
| Parametr | Opis |
| aEventName | Nazwa zdarzenia do wywołania. |
| aChannel | Nazwa kanału, na którym ma zostać wywołane zdarzenie. |
| aData | Dane zdarzenia (ciąg JSON). |
| aSocketId (opcjonalny) | Identyfikator gniazda, który ma zostać wykluczony z odbierania zdarzenia. Przydatne, aby zapobiec otrzymywaniu przez nadawcę własnej wiadomości. |
| aInfo (opcjonalne) | Rozdzielana przecinkami lista atrybutów do uwzględnienia w odpowiedzi (np. "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');
Wyzwala wiele zdarzeń w jednym wywołaniu API, co jest wydajniejsze niż wykonywanie osobnych żądań dla każdego zdarzenia. Parametr batch musi być ciągiem JSON zawierającym tablicę obiektów zdarzeń, gdzie każdy obiekt posiada pola „channel", „name" i „data".
APIPusher.TriggerBatchEvents(
'[{"channel":"my-channel","name":"my-event","data":"hello"},' +
'{"channel":"my-channel-2","name":"my-event","data":"world"}]');
Zwraca listę aktywnych kanałów. Obsługuje opcjonalne parametry umożliwiające filtrowanie wyników i żądanie dodatkowych informacji.
| Parametr | Opis |
| aFilterByPrefix (opcjonalnie) | Filtruj kanały według prefiksu nazwy (np. "presence-", aby wyświetlić tylko kanały obecności). |
| aInfo (opcjonalne) | Rozdzielona przecinkami lista atrybutów do uwzględnienia w odpowiedzi (np. "user_count"). |
// get all channels
APIPusher.GetChannels;
// get only presence channels with user count
APIPusher.GetChannels('presence-', 'user_count');
Zwraca informacje o określonym kanale.
| Parametr | Opis |
| aChannel | Nazwa kanału, o którym mają zostać pobrane informacje. |
| aInfo (opcjonalne) | Rozdzielana przecinkami lista atrybutów do uwzględnienia (np. "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');
Zwraca listę użytkowników połączonych z kanałem presence. Nazwa kanału musi zawierać pełny prefiks (np. "presence-my-channel").
APIPusher.GetUsers('presence-my-channel');
Kończy wszystkie połączenia ustanowione przez danego użytkownika. Może być używane do wymuszenia rozłączenia konkretnego użytkownika ze wszystkich kanałów. Identyfikator użytkownika musi odpowiadać identyfikatorowi "user_id" użytemu podczas subskrybowania kanału obecności.
APIPusher.TerminateUserConnections('1234');
Pusher zezwala wyłącznie na subskrybowanie prywatnych kanałów lub kanałów obecności. Jeśli połączenie dostarcza token uwierzytelniający, umożliwia to ograniczenie dostępu.
Można zbudować własny przepływ uwierzytelniania przy użyciu zdarzenia OnPusherAuthentication. Zdarzenie jest wywoływane przed podpisaniem wiadomości subskrypcji tajnym kluczem dostarczonym przez Pusher. Zdarzenie ma 2 parametry: żądanie uwierzytelnienia z polami takimi jak SocketId, nazwa kanału itp., które mogą być używane przez własny serwer uwierzytelniania do autoryzacji lub odrzucenia żądania. Poniżej znajduje się zrzut ekranu przedstawiający przepływ uwierzytelniania Pusher

Gdy klient łączy się z serwerem pusher, wysyła klucz dostarczony przez pusher, a serwer zwraca identyfikator (socket_id).
Gdy klient subskrybuje prywatny (lub presence) kanał, klient sgcWebSockets używa klucza Secret Key dostarczonego przez pusher w celu utworzenia podpisu, który jest dołączany do wiadomości subskrypcji. Korzystając ze zdarzenia OnPusherAutentication, można przechwycić pola wymagane do podpisania wiadomości, zaimplementować własne metody uwierzytelniania i, w przypadku powodzenia, zwrócić podpis, który zostanie dołączony do wiadomości subskrypcji i przesłany do serwera.
Przykład:
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;
Format podpisu jest następujący:
Kanały prywatne: key:HMAC256(SocketID, ChannelName)
Kanały Presence: klucz: HMAC256(SocketID, ChannelName, Data)
Obiekt TsgcWSPusherResponseAuthentication udostępnia następujące właściwości:
| Właściwość | Opis |
| Sekret | Tajny klucz Pusher używany do obliczenia sygnatury HMAC. Wstępnie wypełniany wartością Pusher.Secret, jeśli jest skonfigurowana. |
| Podpis | Obliczony podpis uwierzytelniający. Jeśli pozostawiono puste, komponent obliczy go automatycznie przy użyciu klucza Secret. |
| SharedSecret | Wspólny klucz tajny dla prywatnych kanałów szyfrowanych. Wymagany podczas subskrybowania kanałów pscPrivateEncryptedChannel lub pscPrivateEncryptedCacheChannel. Używany do szyfrowania end-to-end danych wiadomości. |