Pusherは、WebSocketプロトコルに基づいた優れた機能を持つ使いやすく信頼性の高いプラットフォームです。柔軟なpub/subメッセージング、ライブユーザーリスト(プレゼンス)、認証などの機能を提供します。
Pusher WebSocket API は7です。
データは UTF8 エンコードされた JSON を含むテキストデータとして WebSocket 経由で双方向に送信されます(バイナリ WebSocket フレームはサポートされていません)。
サーバーへの接続をテストするには Ping メソッドを呼び出すことができます。基本的に、相手側から受信したメッセージはすべて接続が生きていることを意味します。メッセージがない場合、どちらの側もピングメッセージを送信することで相手が応答しているか確認でき、相手側はポンで応答するはずです。
接続する前に、以下のフィールドを入力する必要があります:
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)
重要
Pusher では、WebSocket クライアントが前述のフィールド(キー、クラスターなど)を使用して構築された URL に接続する必要があります。これらのフィールドは、Pusher コンポーネントにクライアントを割り当てるときに URL の構築に使用されます。URL が正しく構築されるよう、Pusher 設定フィールドを入力した後にクライアントを設定してください。以下に擬似コードを示します:
// pusher フィールドを設定
pusher.cluster = ...
pusher.key = ...
// set client
pusher.client = websocket クライアント
// 接続を開始
websocket client.Active = true;
接続が成功すると、OnPusherConnect イベントが発生し、以下のフィールドが取得されます:
ソケット ID:接続されたクライアントの一意の識別子。
Timeout: クライアントが ping メッセージを開始するまでのサーバー非アクティブ秒数 (コンポーネントが自動的に処理します)。
エラーが発生すると OnPusherError が発生し、エラーに関する情報が提供されます。エラーは、無効な認証、無効なコマンドなどに応答して Pusher から送信される場合があります。
4000-4099
Pusherによって接続が閉じられるエラーであり、同じパラメータを使用して再接続を試みても成功しないことを示します。
4000: アプリケーションはSSL接続のみを受け付けます。wss:// を使用して再接続してください。
4001: アプリケーションが存在しません
4003: アプリケーションが無効になっています
4004: アプリケーションが接続クォータを超えています。
4005: パスが見つかりません
4006: バージョン文字列の形式が無効です
4007: サポートされていないプロトコルバージョン
4008: プロトコルバージョンが指定されていません
4100-4199
Pusher によって接続が閉じられたエラーを示しており、クライアントは 1 秒以上後に再接続できます。
4100: 容量オーバー
4200-4299
Pusher によって接続が閉じられるエラーが発生したことを示します。クライアントはすぐに再接続できます。
4200: すぐに汎用再接続
4201: Pong 返信が受信されませんでした: ping がクライアントに送信されましたが、返信が受信されませんでした。ping および pong メッセージを参照してください。
4202:非アクティブにより切断:クライアントが長時間非アクティブで(現在24時間)、クライアントが ping をサポートしていません。新しい WebSocket ドラフトにアップグレードするか、このプロトコルのバージョン5以上を実装してください。
4300-4399
その他の種類のエラー。
4301: レートリミットによりクライアントイベントが拒否されました
チャンネルは Pusher の基本的な概念です。各アプリケーションには複数のチャンネルがあり、各クライアントはサブスクライブするチャンネルを選択できます。
チャンネルは以下を提供します:
データをフィルタリングする方法。例えばチャットアプリケーションでは、「犬」について議論したい人々のためのチャンネルがあるかもしれません。
異なる情報ストリームへのアクセスを制御する方法。例えば、プロジェクト管理アプリケーションでは「projectX」の更新を取得するためにユーザーを認可したい場合があります。
チャンネルを使用してデータをフィルタリングすることを強くお勧めします。イベントを使用してフィルタリングするべきではありません。これは、チャンネルにパブリッシュされたすべてのイベントが、イベントバインディングに関わらずすべてのサブスクライバーに送信されるためです。
チャンネルを明示的に作成する必要はなく、クライアントの要求に応じてインスタンス化されます。これは、チャンネルの作成が簡単であることを意味します。クライアントにそれをサブスクライブするよう伝えるだけです。
以下の種類のチャンネルがサポートされています。
パブリックチャンネルは、名前を知っている人であれば誰でもサブスクライブできます
プライベートチャンネルは、ブロードキャストするデータへのアクセスをサーバーが制御できるメカニズムを導入します。
Presence チャンネルはプライベートチャンネルの拡張です。サブスクリプション時にユーザー情報を登録でき、チャンネルの他のメンバーに誰がオンラインかを知らせることができます。
キャッシュチャンネルは最後にトリガーされたイベントを記憶し、新しいサブスクライバーへの最初のイベントとして送信します (パブリック、プライベート、プレゼンスの各バリアント)
Private-Encryptedチャンネルは、NaCl secretboxを使用してエンドツーエンド暗号化を提供し、Pusherでさえメッセージデータを読み取れないようにします
パブリックチャンネルはサブスクライブするための認証を必要としないため、公開アクセス可能なデータに使用してください。
いつでもチャンネルにサブスクライブおよびサブスクライブ解除できます。Pusher の接続が完了するまで待つ必要はありません。
例: チャンネル「my-channel」にサブスクライブします。
Delphi
APIPusher.Subscribe('my-channel');
サブスクライブが成功した場合、OnPusherSubscribe イベントが発生します。エラーがある場合は OnPusherError イベントでメッセージを受け取ります。
サブスクライブされたチャネルからのすべてのメッセージは OnPusherEvent イベントで受信されます。
Publish メソッドが呼び出され、チャンネルがパブリックの場合、コンポーネントは WebSocket プロトコルを使用する代わりに HTTP プロトコルを使用し、TriggerEvent メソッドを呼び出します(WebSocket プロトコルを使用したパブリッシュは許可されていません)。
Indy 10.5.7 以降が必要です
プライベートチャンネルは、チャンネルへのアクセスを何らかの方法で制限する必要がある場合に使用します。ユーザーがプライベートチャンネルをサブスクライブするには、許可の認可が必要です。
使用例: チャンネル「my-private-channel」を購読します。
Delphi
APIPusher.Subscribe('my-private-channel', pscPrivateChannel);
サブスクライブが成功した場合、OnPusherSubscribe イベントが発生します。エラーがある場合は OnPusherError イベントでメッセージを受け取ります。
サブスクライブされたチャネルからのすべてのメッセージは OnPusherEvent イベントで受信されます。
Indy 10.5.7 以降が必要です
プレゼンスチャンネルはプライベートチャンネルのセキュリティを基盤として構築され、そのチャンネルを購読しているユーザーを把握するための追加機能を公開します。これにより、チャットルームや「オンラインユーザー」タイプの機能をアプリケーションに簡単に構築できます。チャットルーム、ドキュメントのコラボレーター、同じ Web ページを閲覧しているユーザー、ゲームの対戦相手などを考えてみてください。
Presence チャンネルはプライベートチャンネルと同じ方法でクライアント API からサブスクライブしますが、チャンネル名には presence- のプレフィックスを付ける必要があります。プライベートチャンネルと同様に、現在のユーザーがチャンネルへのアクセス権を持つかどうかを確認するために、設定可能な認証 URL に HTTP リクエストが送信されます。
プレゼンスチャンネルにバインドされたイベントにバインドすることで、チャンネルにサブスクライブおよびアンサブスクライブするユーザーの情報にアクセスでき、channel.members プロパティでチャンネルにサブスクライブしているユーザーの現在の状態が利用できます。
使用例: チャンネル "my-presence-channel" にサブスクライブします。
APIPusher.Subscribe('my-presence-channel', pscPresenceChannel,
'{"user_id":"John_Smith","user_info":{"name":"John Smith"}}')
サブスクライブが成功した場合、OnPusherSubscribe イベントが発生します。エラーがある場合は OnPusherError イベントでメッセージを受け取ります。
サブスクライブされたチャネルからのすべてのメッセージは OnPusherEvent イベントで受信されます。
キャッシュチャンネルは最後にトリガーされたイベントを記憶し、これを最初のイベントとして新しいサブスクライバーに送信します。
イベントがキャッシュチャンネルでトリガーされると、Pusher Channelsはこのイベントをキャッシュし、クライアントがキャッシュチャンネルをサブスクライブしたときに、キャッシュされた値が存在すれば、それがそのチャンネルの最初のイベントとしてクライアントに送信されます。この動作により、開発者は他の場所から取得するための追加のロジックを追加せずに初期状態を提供できます。
以下のキャッシュチャンネルがサポートされています:
例: パブリックキャッシュチャンネル「my-cache-channel」にサブスクライブします。
APIPusher.Subscribe('my-cache-channel', pscCacheChannel);
サブスクライブが成功した場合、OnPusherSubscribe イベントが発生します。エラーがある場合は OnPusherError イベントでメッセージを受け取ります。
サブスクライブされたチャネルからのすべてのメッセージは OnPusherEvent イベントで受信されます。
cacheチャンネルにサブスクライブする際にキャッシュされたイベントが存在しない場合、OnPusherCacheMissイベントが発生し、チャンネル名が提供されます。これにより、キャッシュされたデータが利用できない場合をアプリケーションで処理できます。
プライベート暗号化チャンネルは、メッセージのエンドツーエンド暗号化を提供します。プライベートチャンネルと同様に認証が必要ですが、さらに NaCl secretbox を使用してすべてのデータペイロードが暗号化されるため、認可されたサブスクライバーのみがコンテンツを読み取ることができます。Pusher 自身もメッセージを復号化できません。
private-encryptedチャンネルを使用するには、認証中にSharedSecretを提供する必要があります。共有シークレットは、メッセージデータの暗号化と復号化に使用されます。
使用例: プライベート暗号化チャンネル "my-encrypted-channel" をサブスクライブします。
APIPusher.Subscribe('my-encrypted-channel', pscPrivateEncryptedChannel);
暗号化とキャッシュチャンネルの動作を組み合わせたプライベート暗号化キャッシュのバリアントも利用可能です。
APIPusher.Subscribe('my-encrypted-cache-channel', pscPrivateEncryptedCacheChannel);
プライベート暗号化チャンネルで OnPusherAuthentication イベントを使用する場合、応答オブジェクトの SharedSecret プロパティに暗号化キーを設定できます。
procedure OnPusherAuthenticationEvent(Sender: TObject;
AuthRequest: TsgcWSPusherRequestAuthentication;
AuthResponse: TsgcWSPusherResponseAuthentication);
begin
AuthResponse.SharedSecret := 'your-shared-secret-key';
end;
Presenceチャンネルは、ユーザーがチャンネルに参加または退出したときにアプリケーションに通知する追加イベントを提供し、サブスクリプション数を追跡できるようにします。
新しいメンバーがプレゼンスチャンネルをサブスクライブしたときに発生します。チャンネル名、ユーザー ID、参加したメンバーのユーザー情報を提供します。
procedure PUSHERPusherMemberAdded(Sender: TObject;
Channel, UserId, UserInfo: string);
begin
Log('Member joined: ' + UserId + ' on ' + Channel);
end;
メンバーがプレゼンスチャンネルから購読解除したときに発生します。退出したメンバーのチャンネル名、ユーザー ID、ユーザー情報を提供します。
procedure PUSHERPusherMemberRemoved(Sender: TObject;
Channel, UserId, UserInfo: string);
begin
Log('Member left: ' + UserId + ' on ' + Channel);
end;
チャンネルのサブスクリプション数が変更されたときに発生します。チャンネル名と現在のサブスクライバー数を提供します。このイベントは Pusher ダッシュボードで有効にする必要があります。
procedure PUSHERPusherSubscriptionCount(Sender: TObject;
Channel: string; SubscriptionCount: Integer);
begin
Log(Channel + ' has ' + IntToStr(SubscriptionCount) + ' subscribers');
end;
キャッシュされたイベントがないキャッシュチャンネルにサブスクライブするときに発生します。チャンネル名を提供します。これにより、キャッシュされたデータが利用できない場合に、アプリケーションが別のソースからデータをフェッチするなどして対処できます。
procedure PUSHERPusherCacheMiss(Sender: TObject; Channel: string);
begin
Log('Cache miss on: ' + Channel);
end;
サブスクライブしたチャネルからメッセージを受信できるだけでなく、他のサブスクライブ中のユーザーにメッセージを送信することもできます。
チャンネルのすべてのサブスクライブユーザーにメッセージを送信するには Publish メソッドを呼び出してください。
例: "my-channel" のすべてのサブスクライブユーザーにイベントを送信する
APIPusher.Publish('my-event', 'my-channel');
クライアント(接続)ごとに1秒あたり最大10件のメッセージを公開してください。このレート制限を超えてトリガーされたイベントは Pusher API によって拒否されます。これはシステムの問題ではなく、クライアントの問題です。このレートでメッセージを送信するチャンネル内の100人のクライアントは、それぞれ1秒あたり1,000件のメッセージを処理する必要があります!一部の最新ブラウザーはこれを処理できるかもしれませんが、おそらく良いアイデアではありません。
API は http://api-CLUSTER.pusher.com でホストされています。CLUSTER はご自身のアプリのクラスター(例:eu)に置き換えてください。
HTTP ステータスコードはリクエストの成功または失敗を示すために使用されます。以下のステータスが一般的です:
200 リクエスト成功。本文にはレスポンスデータの JSON ハッシュが含まれます
400 エラー: レスポンスボディに詳細あり
401 認証エラー: レスポンスボディに説明が含まれます
403 Forbidden: アプリが無効またはメッセージクォータを超過しています。
以下の REST API 関数が実装されています。
| Function | 説明 |
| TriggerEvent | 指定されたチャンネルで新しいイベントをトリガーします。オプションの SocketId (クライアントを除外するため) と Info パラメータをサポートします。 |
| TriggerBatchEvents | 単一の HTTP リクエストで複数のイベントを発火します。イベントオブジェクトの JSON 配列を受け入れます。 |
| GetChannels | すべてのアクティブなチャンネルのリストを提供します。オプションの FilterByPrefix と Info パラメータをサポートします。 |
| GetChannel | 特定のチャンネルに関する情報を提供します。オプションの Info パラメーターをサポートします。 |
| GetUsers | チャンネルに接続しているすべてのユーザーのリストを提供します。 |
| TerminateUserConnections | ユーザー ID によって特定のユーザーのすべての接続を終了します。 |
1つ以上のチャンネルでイベントをトリガーします。イベント名、チャンネル名、データペイロードが必要です。
| パラメータ | 説明 |
| aEventName | トリガーするイベントの名前。 |
| aChannel | イベントをトリガーするチャンネル名。 |
| aData | イベントデータ(JSON 文字列)。 |
| aSocketId(オプション) | イベントの受信から除外するソケット ID。送信者が自分のメッセージを受信しないようにするのに便利です。 |
| aInfo(オプション) | レスポンスに含める属性のカンマ区切りリスト(例: "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');
単一の API 呼び出しで複数のイベントをトリガーします。各イベントに対して個別のリクエストを行うよりも効率的です。batch パラメーターは、各オブジェクトに「channel」、「name」、「data」フィールドを持つイベントオブジェクトの配列を含む JSON 文字列でなければなりません。
APIPusher.TriggerBatchEvents(
'[{"channel":"my-channel","name":"my-event","data":"hello"},' +
'{"channel":"my-channel-2","name":"my-event","data":"world"}]');
アクティブなチャネルの一覧を返します。結果をフィルタリングし、追加情報をリクエストするためのオプションパラメータをサポートします。
| パラメータ | 説明 |
| aFilterByPrefix(オプション) | 名前プレフィックスでチャネルをフィルタリングします(例: プレゼンスチャネルのみを一覧表示するには "presence-")。 |
| aInfo(オプション) | レスポンスに含める属性のカンマ区切りリスト(例:「user_count」)。 |
// get all channels
APIPusher.GetChannels;
// get only presence channels with user count
APIPusher.GetChannels('presence-', 'user_count');
特定のチャンネルに関する情報を返します。
| パラメータ | 説明 |
| aChannel | 情報を取得するチャンネル名。 |
| aInfo(オプション) | 含める属性のカンマ区切りリスト (例: "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');
Presence チャンネルに接続しているユーザーのリストを返します。チャンネル名には完全なプレフィックス(例: "presence-my-channel")を含める必要があります。
APIPusher.GetUsers('presence-my-channel');
特定のユーザーによって確立されたすべての接続を終了します。特定のユーザーをすべてのチャンネルから強制的に切断するために使用できます。ユーザー ID は、ユーザーがプレゼンスチャンネルをサブスクライブしたときに使用した「user_id」と一致する必要があります。
APIPusher.TerminateUserConnections('1234');
Pusher はプライベートチャンネルまたはプレゼンスチャンネルへのサブスクリプションのみを許可しており、接続が認証トークンを提供している場合はアクセスを制限できます。
OnPusherAuthentication イベントを使用して独自の認証フローを構築できます。このイベントはサブスクリプションメッセージが Pusher が提供する秘密鍵で署名される前に呼び出されます。このイベントには、SocketId、チャンネル名などのフィールドを持つリクエスト認証の 2 つのパラメーターがあります。これらは独自の認証サーバーがリクエストを認証するかどうかに使用できます。Pusher の認証フローを示すスクリーンショットを以下に示します

クライアントがPusherサーバーに接続すると、Pusherが提供するキーを送信し、サーバーは識別IDを返します(socket_id)。
クライアントがプライベート (またはプレゼンス) チャンネルにサブスクライブする場合、sgcWebSockets クライアントは Pusher が提供するシークレットキーを使用してサブスクリプションメッセージに含まれる署名を作成します。OnPusherAutentication イベントを使用すると、メッセージに署名するために必要なフィールドをキャプチャし、独自の認証メソッドを実装し、成功した場合に署名を返すことができます。この署名はサブスクリプションメッセージに含まれてサーバーに送信されます。
例:
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;
署名のフォーマットは次のとおりです:
プライベートチャンネル: key:HMAC256(SocketID, ChannelName)
プレゼンスチャンネル: キー: HMAC256(SocketID, ChannelName, Data)
TsgcWSPusherResponseAuthentication オブジェクトは次のプロパティを提供します:
| プロパティ | 説明 |
| シークレット | 署名の計算に使用される Pusher のシークレットキー。Pusher.Secret が設定されている場合はあらかじめ入力されます。 |
| 署名 | 計算された認証署名。空のままにすると、コンポーネントがSecretを使用して自動的に計算します。 |
| SharedSecret | プライベート暗号化チャンネルの共有シークレットキー。pscPrivateEncryptedChannel または pscPrivateEncryptedCacheChannel にサブスクライブする場合に必要です。メッセージデータのエンドツーエンド暗号化に使用されます。 |