用於與 Pusher Channels HTTP API 互動的 PHP 函式庫。
在 https://pusher.com 註冊並在您的應用程式中使用應用程式憑證,如下所示。
如需報告問題、錯誤和功能請求,請隨時提出拉取請求或提出問題。如果您沒有收到及時回复,請隨時查看我們的支援入口網站。
您可以透過名為pusher-php-server
Composer 套件來取得 Pusher Channels PHP 函式庫。請參閱 https://packagist.org/packages/pusher/pusher-php-server
$ composer require pusher/pusher-php-server
或添加到composer.json
:
"require" : {
"pusher/pusher-php-server" : " ^7.2 "
}
然後運行composer update
。
使用 Pusher Channels 應用程式中的憑證建立新的PusherPusher
實例。
$ app_id = ' YOUR_APP_ID ' ;
$ app_key = ' YOUR_APP_KEY ' ;
$ app_secret = ' YOUR_APP_SECRET ' ;
$ app_cluster = ' YOUR_APP_CLUSTER ' ;
$ pusher = new Pusher Pusher ( $ app_key , $ app_secret , $ app_id , [ ' cluster ' => $ app_cluster ]);
第四個參數是$options
數組。附加選項有:
scheme
- 例如 http 或 httpshost
- 主機,例如 api.pusherapp.com。沒有尾隨正斜杠port
- http 端口path
- 附加到所有請求路徑的前綴。只有當您針對自己控制的端點(例如,基於路徑前綴進行路由的代理程式)運行庫時,這才有用。timeout
- HTTP 超時useTLS
- 使用 https 和連接埠 443 方案的快速選項。cluster
- 指定執行應用程式的叢集。encryption_master_key_base64
- 32 個字元長的金鑰。此金鑰與通道名稱一起用於派生每個通道的加密金鑰。每通道密鑰用於加密加密通道上的事件資料。例如,預設情況下將透過 HTTPS 進行呼叫。若要使用純 HTTP,您可以將 useTLS 設定為 false:
$ options = [
' cluster ' => $ app_cluster ,
' useTLS ' => false
];
$ pusher = new Pusher Pusher ( $ app_key , $ app_secret , $ app_id , $ options );
建議的日誌記錄方法是使用實際PsrLogLoggerInterface
PSR-3 相容記錄器。 Pusher
物件實作PsrLogLoggerAwareInterface
,這表示您可以呼叫setLogger(LoggerInterface $logger)
來設定記錄器實例。
// where $logger implements `LoggerInterface`
$ pusher -> setLogger ( $ logger );
該庫在內部使用 Guzzle 進行 HTTP 呼叫。您可以將自己的 Guzzle 實例傳遞給 Pusher 建構子:
$ custom_client = new GuzzleHttp Client ();
$ pusher = new Pusher Pusher (
$ app_key ,
$ app_secret ,
$ app_id ,
[],
$ custom_client
);
這允許您傳遞自己的中間件,請參閱測試範例。
若要在一個或多個通道上觸發事件,請使用trigger
功能。
$ pusher -> trigger ( ' my-channel ' , ' my_event ' , ' hello world ' );
$ pusher -> trigger ([ ' channel-1 ' , ' channel-2 ' ], ' my_event ' , ' hello world ' );
也可以透過單一 API 呼叫傳送多個事件(多租用戶叢集上每次呼叫最多 10 個事件):
$ batch = [];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' hello ' => ' world ' ]];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' myname ' => ' bob ' ]];
$ pusher -> triggerBatch ( $ batch );
trigger
和triggerBatch
在triggerAsync
和triggerBatchAsync
中都有非同步對應項。這些函數傳回 Guzzle 承諾,可以與->then
連結:
$ promise = $ pusher -> triggerAsync ([ ' channel-1 ' , ' channel-2 ' ], ' my_event ' , ' hello world ' );
$ promise -> then ( function ( $ result ) {
// do something with $result
return $ result ;
});
$ final_result = $ promise -> wait ();
陣列會自動轉換為 JSON 格式:
$ array [ ' name ' ] = ' joe ' ;
$ array [ ' message_count ' ] = 23 ;
$ pusher -> trigger ( ' my_channel ' , ' my_event ' , $ array );
其輸出將是:
" {'name': 'joe', 'message_count': 23} "
為了避免重複,您可以選擇在觸發事件時指定發送者的套接字 ID:
$ pusher -> trigger ( ' my-channel ' , ' event ' , ' data ' , [ ' socket_id ' => $ socket_id ]);
$ batch = [];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' hello ' => ' world ' ], [ ' socket_id ' => $ socket_id ]];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' myname ' => ' bob ' ], [ ' socket_id ' => $ socket_id ]];
$ pusher -> triggerBatch ( $ batch );
可以使用info
參數請求有關已發佈到的通道的屬性:
$ result = $ pusher -> trigger ( ' my-channel ' , ' my_event ' , ' hello world ' , [ ' info ' => ' subscription_count ' ]);
$ subscription_count = $ result -> channels [ ' my-channel ' ]-> subscription_count ;
$ batch = [];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' hello ' => ' world ' ], ' info ' => ' subscription_count ' ];
$ batch [] = [ ' channel ' => ' presence-my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' myname ' => ' bob ' ], ' info ' => ' user_count,subscription_count ' ];
$ result = $ pusher -> triggerBatch ( $ batch );
foreach ( $ result -> batch as $ i => $ attributes ) {
echo " channel: { $ batch [ $ i ][ ' channel ' ]} , name: { $ batch [ $ i ][ ' name ' ]}" ;
if ( isset ( $ attributes -> subscription_count )) {
echo " , subscription_count: { $ attributes -> subscription_count }" ;
}
if ( isset ( $ attributes -> user_count )) {
echo " , user_count: { $ attributes -> user_count }" ;
}
echo PHP_EOL ;
}
如果您的資料已經以 JSON 格式編碼,您可以將第六個參數設為 true 來避免第二個編碼步驟,如下所示:
$ pusher -> trigger ( ' my-channel ' , ' event ' , ' data ' , [], true );
若要對應用程式上的 Pusher Channels 上的使用者進行身份驗證,您可以使用authenticateUser
函數:
$ pusher -> authenticateUser ( ' socket_id ' , ' user-id ' );
有關詳細信息,請參閱驗證用戶身份。
若要授權您的使用者存取 Pusher 上的私人頻道,您可以使用authorizeChannel
函數:
$ pusher -> authorizeChannel ( ' private-my-channel ' , ' socket_id ' );
有關詳細信息,請參閱授權使用者。
使用狀態通道與專用通道類似,但您可以指定額外的資料來識別該特定使用者:
$ pusher -> authorizePresenceChannel ( ' presence-my-channel ' , ' socket_id ' , ' user_id ' , ' user_info ' );
有關詳細信息,請參閱授權使用者。
該程式庫提供了一種方法來驗證您從 Pusher 收到的 Webhook 是否確實是來自 Pusher 的正版 Webhook。它還提供了儲存它們的結構。稱為webhook
的輔助方法可以實現此目的。傳入請求的標頭和正文,它將傳回一個包含已驗證事件的 Webhook 物件。如果程式庫無法驗證簽名,則會拋出異常。
$ webhook = $ pusher -> webhook ( $ request_headers , $ request_body );
$ number_of_events = count ( $ webhook -> get_events ());
$ time_received = $ webhook -> get_time_ms ();
該庫支援您的私人頻道的端對端加密。這意味著只有您和您連接的客戶端才能閱讀您的訊息。 Pusher 無法解密它們。您可以按照以下步驟啟用此功能:
您應該先設定私人頻道。這涉及在您的伺服器上建立授權端點。
接下來,產生 32 位元組主加密金鑰,對其進行 Base64 編碼並安全地儲存。這是秘密,您不應該與任何人分享。連推手也不行。
要從良好的隨機來源產生適當的密鑰,您可以使用openssl
命令:
openssl rand -base64 32
建立 Pusher 用戶端時指定主加密金鑰:
$ pusher = new Pusher Pusher (
$ app_key ,
$ app_secret ,
$ app_id ,
[
' cluster ' => $ app_cluster ,
' encryption_master_key_base64 ' => " <your base64 encoded master key> "
]
);
您希望使用端對端加密的通道應以private-encrypted-
為前綴。
在您的客戶端訂閱這些頻道,就完成了!您可以透過檢查 https://dashboard.pusher.com/ 上的偵錯控制台並查看加擾的密文來驗證它是否正常運作。
重要提示:這不會加密沒有private-encrypted-
前綴的通道上的消息。
限制:您不能在呼叫trigger
時在未加密和加密通道的混合上觸發單一事件,例如
$ data [ ' name ' ] = ' joe ' ;
$ data [ ' message_count ' ] = 23 ;
$ pusher -> trigger ([ ' channel-1 ' , ' private-encrypted-channel-2 ' ], ' test_event ' , $ data );
基本原理:此庫中的方法直接對應到各個 Channels HTTP API 請求。如果我們允許在多個通道(有些是加密的,有些是未加密的)上觸發單一事件,那麼將需要兩個API 請求:一個是事件加密到加密通道,另一個是事件未加密到未加密通道。
建立 Pusher 物件時,首先在 JS 應用程式中設定通道授權端點:
var pusher = new Pusher ( "app_key" ,
// ...
channelAuthorization : {
endpoint : "/presenceAuth.php" ,
} ,
) ;
接下來,在presenceAuth.php中建立以下內容:
<?php
header ( ' Content-Type: application/json ' );
if ( isset ( $ _SESSION [ ' user_id ' ])) {
$ stmt = $ pdo -> prepare ( " SELECT * FROM `users` WHERE id = :id " );
$ stmt -> bindValue ( ' :id ' , $ _SESSION [ ' user_id ' ], PDO :: PARAM_INT );
$ stmt -> execute ();
$ user = $ stmt -> fetch ();
} else {
die ( json_encode ( ' no-one is logged in ' ));
}
$ pusher = new Pusher Pusher ( $ key , $ secret , $ app_id );
$ presence_data = [ ' name ' => $ user [ ' name ' ]];
echo $ pusher -> authorizePresenceChannel ( $ _POST [ ' channel_name ' ], $ _POST [ ' socket_id ' ], $ user [ ' id ' ], $ presence_data );
注意:這假設您將使用者儲存在名為users
表中,並且這些使用者俱有name
列。它還假設您有一個登入機制,可以將登入使用者的user_id
儲存在會話中。
$ pusher -> getChannelInfo ( $ name );
也可以從 Channels HTTP API 取得有關通道的資訊。
$ info = $ pusher -> getChannelInfo ( ' channel-name ' );
$ channel_occupied = $ info -> occupied ;
對於線上狀態頻道,您還可以查詢目前訂閱該頻道的不同使用者數量(單一使用者可能訂閱多次,但僅算一次):
$ info = $ pusher -> getChannelInfo ( ' presence-channel-name ' , [ ' info ' => ' user_count ' ]);
$ user_count = $ info -> user_count ;
如果您啟用了查詢subscription_count
(目前訂閱該頻道的連線數)的功能,那麼您可以如下查詢該值:
$ info = $ pusher -> getChannelInfo ( ' presence-channel-name ' , [ ' info ' => ' subscription_count ' ]);
$ subscription_count = $ info -> subscription_count ;
$ pusher -> getChannels ();
也可以從 Channels HTTP API 取得應用程式的通道清單。
$ result = $ pusher -> getChannels ();
$ channel_count = count ( $ result -> channels ); // $channels is an Array
$ pusher -> getChannels ([ ' filter_by_prefix ' => ' some_filter ' ]);
也可以根據名稱前綴取得頻道清單。為此,您需要向呼叫提供$options
參數。在以下範例中,呼叫將傳回帶有presence-
前綴的所有頻道的清單。這是獲取所有線上頻道清單的想法。
$ results = $ pusher -> getChannels ([ ' filter_by_prefix ' => ' presence- ' ]);
$ channel_count = count ( $ result -> channels ); // $channels is an Array
這也可以使用通用的pusher->get
函數來實作:
$ pusher -> get ( ' /channels ' , [ ' filter_by_prefix ' => ' presence- ' ]);
傳回頻道清單的 HTTP API 不支援隨每個頻道傳回訂閱計數。相反,您可以透過迭代每個通道並發出另一個請求來獲取此資料。請注意:這種方法會消耗(通道數 + 1)則訊息!
<?php
$ subscription_counts = [];
foreach ( $ pusher -> getChannels ()-> channels as $ channel => $ v ) {
$ subscription_counts [ $ channel ] =
$ pusher -> getChannelInfo (
$ channel , [ ' info ' => ' subscription_count ' ]
)-> subscription_count ;
}
var_dump ( $ subscription_counts );
$ results = $ pusher -> getPresenceUsers ( ' presence-channel-name ' );
$ users_count = count ( $ results -> users ); // $users is an Array
這也可以使用通用的pusher->get
函數來實作:
$ response = $ pusher -> get ( ' /channels/presence-channel-name/users ' );
$response
的格式為:
Array (
[body] => { " users " :[{ " id " :"a_user_id"}]}
[status] => 200
[result] => Array (
[users] => Array (
[ 0 ] => Array (
[id] => a_user_id
),
/* Additional users */
)
)
)
$ pusher -> get ( $ path , $ params );
用於對 Channels HTTP API 進行GET
查詢。處理身份驗證。
響應是一個帶有result
索引的關聯數組。該索引的內容取決於所呼叫的 HTTP 方法。但是,允許 HTTP 狀態代碼的status
屬性始終存在,如果狀態代碼指示成功呼叫 API,則將設定result
屬性。
$ response = $ pusher -> get ( ' /channels ' );
$ http_status_code = $ response [ ' status ' ];
$ result = $ response [ ' result ' ];
需要 phpunit。
composer install
tests
目錄config.example.php
重新命名為config.php
並將這些值替換為有效的 Channels 憑證或建立環境變數。composer exec phpunit
來執行所有測試。 版權所有 2014,推手。根據 MIT 許可證獲得許可:https://www.opensource.org/licenses/mit-license.php
版權所有 2010,斯奎克斯。根據 MIT 許可證獲得許可:https://www.opensource.org/licenses/mit-license.php