1.客户端调用
整个push推送流程如下图所示
1.1 引入javascript客户端
<script src="/plugin/webman/push/push.js"> </script>
1.2 客户端使用(公有频道)
// 建立连接
var connection = new Push({
url: 'ws://127.0.0.1:8790', // websocket地址
app_key: '<app_key,在config/plugin/webman/push/app.php里获取>',
auth: '/plugin/webman/push/auth' // 订阅鉴权(仅限于私有频道)
});
// 假设用户uid为1
var uid = 1;
// 浏览器监听user-1频道的消息,也就是用户uid为1的用户消息
var user_channel = connection.subscribe('user-' + uid);
// 当user-1频道有message事件的消息时
user_channel.on('message', function(data) {
// data里是消息内容
console.log(data);
});
// 当user-1频道有friendApply事件时消息时
user_channel.on('friendApply', function (data) {
// data里是好友申请相关信息
console.log(data);
});
// 假设群组id为2
var group_id = 2;
// 浏览器监听group-2频道的消息,也就是监听群组2的群消息
var group_channel = connection.subscribe('group-' + group_id);
// 当群组2有message消息事件时
group_channel.on('message', function(data) {
// data里是消息内容
console.log(data);
});
2.服务端推送
use Webman\Push\Api;
$api = new Api(
// webman下可以直接使用config获取配置,非webman环境需要手动写入相应配置
'http://127.0.0.1:8791',
config('plugin.webman.push.app.app_key'),
config('plugin.webman.push.app.app_secret')
);
// 给订阅 user-1 的所有客户端推送 message 事件的消息
$api->trigger('user-1', 'message', [
'from_uid' => 2,
'content' => '你好,这个是消息内容'
]);
3.配置文件说明
安装完webman/push插件之后会在 config/plugin/webman/push 目录下生成三个配置文件
app.php、process和route.php
app.php 文件主要是配置文件,配置的参数给process.php 使用
<?php
return [
'enable' => true,
'websocket' => 'websocket://0.0.0.0:8790',
'api' => 'http://0.0.0.0:8791',
'app_key' => 'f0e7cf465169117e82b2d5a324c25ea7',
'app_secret' => 'a0c0dda29997b6ce7b346ec81a85b5ca',
'channel_hook' => 'http://127.0.0.1:8787/plugin/webman/push/hook',
'auth' => '/plugin/webman/push/auth'
];
process.php,该文件为webman的自定义进程配置文件,这配置文件就是说自己定义了一个websocket进程,对应的参数就是listen参数,一个端口为8790的websocket进程
这里还有个重要的参数就是constructor参数,这里的参数会当做handle的构造方法参数,就是说启动websocket进程的时候,同时会启动一个http的进程,监听端口为8791。
这样就是为什么后台发送http请求8791端口的时候能转发到websocket服务进程中,然后websocket服务器再把消息发送给客户端的连接中。
<?php
use Webman\Push\Server;
return [
'server' => [
'handler' => Server::class,
'listen' => config('plugin.webman.push.app.websocket'), //对应值:websocket://0.0.0.0:8790
'count' => 1, // 必须是1
'reloadable' => false, // 执行reload不重启
'constructor' => [
'api_listen' => config('plugin.webman.push.app.api'),//对应值:http://0.0.0.0:8791
'app_info' => [
config('plugin.webman.push.app.app_key') => [//对应值:f0e7cf465169117e82b2d5a324c25ea7
'channel_hook' => config('plugin.webman.push.app.channel_hook'),//对应值:http://127.0.0.1:8787/plugin/webman/push/hook
'app_secret' => config('plugin.webman.push.app.app_secret'),//对应值:/plugin/webman/push/auth
],
]
]
]
];
4.自定义进程实现
对应路径位置:vendor/webman/push/src/Server.php,对应的部分代码如下
class Server
{
...
/**
* 构造函数
*
* @param string $socket_name
* @param array $context
*/
public function __construct($api_listen, $app_info)
{
$this->apiListen = $api_listen;
$this->appInfo = $app_info;
}
/**
* @param $worker
* @return void
* @throws \Exception
*/
public function onWorkerStart($worker)
{
//在websocket进程中启动一个http的进程,主要是用来接收后台api接口推送的数据,因为是在websocket进程中又启动的一个http进程,所以进程间资源是互通的
//然后把数据转发给websocket服务端处理,然后推送给客户端
$api_worker = new Worker($this->apiListen);
$api_worker->onMessage = array($this, 'onApiClientMessage');
$api_worker->listen();
Timer::add($this->keepAliveTimeout/2, array($this, 'checkHeartbeat'));
Timer::add($this->webHookDelay, array($this, 'webHookCheck'));//这里是一个定时检测客户端上线离线的事件,会把事件转到到配置文件里的route.php中
}
...
}
webman push插件官网地址:https://www.workerman.net/plugin/2
自定义进程文档说明:https://www.workerman.net/doc/webman/process.html