sondt-1245 / 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: ^8.5|^9.3
- v7.1.0-beta
- v7.0.3
- v7.0.2.x-dev
- 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
- dev-psalm_check
This package is auto-updated.
Last update: 2024-09-29 06:14:54 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.0" }
然后运行 composer update。
支持的平台
- PHP - 支持 PHP 版本 7.3、7.4 和 8.0。
- 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- 一个 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
为了避免重复,您可以在触发事件时可选地指定发送者的socket 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上的私有频道,您可以使用socketAuth函数
$pusher->socketAuth('private-my-channel','socket_id');
验证存在频道
使用存在频道与私有频道类似,但您可以指定额外数据来识别特定用户
$pusher->presenceAuth('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请求:一个用于将事件加密到加密频道,另一个用于将事件解密到未加密频道。
存在示例
首先在您的JS应用程序中设置此变量
Pusher.channel_auth_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->presenceAuth($_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://open-source.org.cn/licenses/mit-license.php
版权 2010,Squeeks。根据 MIT 许可证授权:https://open-source.org.cn/licenses/mit-license.php