pusher / pusher-php-server
用于与 Pusher REST API 交互的库
Requires
- php: ^7.3|^8.0
- ext-curl: *
- ext-json: *
- guzzlehttp/guzzle: ^7.2
- paragonie/sodium_compat: ^1.6
- psr/log: ^1.0|^2.0|^3.0
Requires (Dev)
- overtrue/phplint: ^2.3
- phpunit/phpunit: ^9.3
- 7.2.4
- 7.2.3
- 7.2.2
- 7.2.1
- 7.2.0
- 7.1.0-beta
- 7.0.2
- 7.0.1
- 7.0.0
- 6.1.0
- 6.0.1
- 6.0.0
- dev-master / 5.0.x-dev
- 5.0.3
- 5.0.2
- v5.0.1
- v5.0.0
- v4.1.5
- v4.1.4
- v4.1.3
- v4.1.2
- v4.1.1
- v4.1.0
- v4.0.0
- v3.4.1
- v3.4.0
- v3.3.1
- v3.3.0
- v3.2.0
- v3.1.1
- v3.1.0
- v3.0.4
- v3.0.3
- v3.0.2
- v3.0.1
- 3.0.0
- 2.6.4
- 2.6.3
- 2.6.2
- 2.6.1
- v2.6.0
- v2.5.0
- v2.5.0-rc4
- v2.5.0-rc3
- v2.5.0-rc2
- v2.5.0-rc1
- v2.4.2
- v2.4.1
- v2.4.0
- v2.3.0
- v2.2.1
- v2.2.0
- v2.1.3
- 2.1.2
This package is auto-updated.
Last update: 2024-09-15 12:44:45 UTC
README
PHP 库,用于与 Pusher Channels HTTP API 交互。
在 https://pusher.com 注册并使用以下方式在你的应用中使用应用凭据。
安装
您可以通过名为 pusher-php-server
的 composer 包获取 Pusher Channels PHP 库。请参阅 https://packagist.org.cn/packages/pusher/pusher-php-server
$ composer require pusher/pusher-php-server
或添加到 composer.json
"require": { "pusher/pusher-php-server": "^7.2" }
然后运行 composer update
。
支持的平台
- PHP - 支持 PHP 版本 7.3、7.4、8.0 和 8.1。
- Laravel - 8.29 版本及以上已内置对 Pusher Channels 的支持,作为 Broadcasting 后端。
- 其他 PHP 框架 - 在您使用受支持的 PHP 版本的情况下提供支持。
Pusher Channels 构造函数
使用您 Pusher Channels 应用的凭据来创建一个新的 Pusher\Pusher
实例。
$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);
日志配置
推荐的做法是使用符合 PSR-3 的 logger,实现 Psr\Log\LoggerInterface
。The Pusher
对象实现了 Psr\Log\LoggerAwareInterface
,这意味着您可以通过调用 setLogger(LoggerInterface $logger)
来设置 logger 实例。
// where $logger implements `LoggerInterface` $pusher->setLogger($logger);
自定义 Guzzle 客户端
此库内部使用 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 promises,可以与 ->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
为了避免重复,您可以在触发事件时可选地 指定发送者的套接字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格式
如果您的数据已经是JSON格式编码的,您可以通过设置第六个参数为true来避免第二次编码步骤,如下所示
$pusher->trigger('my-channel', 'event', 'data', [], true);
用户认证
要在您的应用程序上认证Pusher频道的用户,您可以使用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');
更多信息请参阅 授权用户。
Webhooks
此库提供了一种验证您从Pusher接收到的webhooks确实是来自Pusher的webhooks的方法。它还提供了一个存储它们的结构。一个名为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编码并安全存储。这是秘密的,您永远不应与任何人分享,甚至不应与Pusher分享。
要从良好的随机源生成适当的关键,您可以使用
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);
理由:此库中的方法直接映射到单个通道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
并将值替换为有效的 Channels 凭据 或 创建环境变量。 - 一些测试需要在配置中定义的应用程序中连接客户端;您可以通过在浏览器中打开 https://dashboard.pusher.com/apps/<YOUR_TEST_APP_ID>/getting_started 来完成此操作
- 从项目根目录执行
composer exec phpunit
以运行所有测试。
许可
版权 2014,Pusher。根据 MIT 许可证授权:https://www.opensource.org/licenses/mit-license.php
版权 2010,Squeeks。根据 MIT 许可证授权:https://www.opensource.org/licenses/mit-license.php