一、在tp6项目下安装 GatewayWorker 命令如下:(注意:tp6请使用最新稳定版本,我刚开始用的 tp6.0.3,config 下并未出现对应的文件)
1.composer require topthink/think-worker
composer require workerman/gatewayclient
2.安装成功出现下图
3.配置gateway_worker .php 代码如下 仅供参考
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | Workerman设置 仅对 php think worker:gateway 指令有效
// +----------------------------------------------------------------------
return [
// 扩展自身需要的配置
'protocol' => 'websocket', // 协议 支持 tcp udp unix http websocket text
'host' => '0.0.0.0', // 监听地址
'port' => 7777, // 监听端口
'socket' => '', // 完整监听地址
'context' => [], // socket 上下文选项
'register_deploy' => true, // 是否需要部署register
'businessWorker_deploy' => true, // 是否需要部署businessWorker
'gateway_deploy' => true, // 是否需要部署gateway
// Register配置
'registerAddress' => '127.0.0.1:1236',
// Gateway配置
'name' => 'thinkphp',
'count' => 1,
'lanIp' => '127.0.0.1',
'startPort' => 2000,
'daemonize' => false,
'pingInterval' => 30,
'pingNotResponseLimit' => 0,
'pingData' => '{"type":"ping"}',
// BusinsessWorker配置
'businessWorker' => [
'name' => 'BusinessWorker',
'count' => 1,
//'eventHandler' => '\think\worker\Events',
'eventHandler' => 'app\http\Events',
],
];
protocol :为 websocket
port :改为自己的监测端口
windows 下运行看 4 ,linux 运行 跳过4 看 5--最后
4.现在可以启动 gateway 命令如下 :(记得看注释)
php think worker:gateway //相当于临时启动,关闭窗口进程就关闭了
php think worker:gateway -d //关闭窗口进程也不会关闭
如果你运行环境在windows 下,不出意外的话就要出意外了
原因是 tp的命令行运行方式不支持windows, 解决方法 去看官网文档 哦 ,网址如下:
5.讲一下我个人是怎么使用 gatewayworker的,最后项目肯定是要放在linux 的,我先用commposer 安装了gatewayworker 按照第一部分的命令安装,然后配置 gateway_worker.php 文件
6.我在tp6下 app 下新建文件夹 http,再创建文件 Events.php 如下图
7.找到 如下图路径,把Events.php 的内容复制到 app/http/Events.php 中
8.修改参数,把我的代码贴出来供大家参考
注意:namespace 一定要修改为自己的
APPlication 也要添加进入
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace app\http;
use GatewayWorker\Lib\Gateway;
use Workerman\Worker;
use think\worker\Application;
/**
* Worker 命令行服务类
*/
class Events
{
/**
* onWorkerStart 事件回调
* 当businessWorker进程启动时触发。每个进程生命周期内都只会触发一次
*
* @access public
* @param \Workerman\Worker $businessWorker
* @return void
*/
public static function onWorkerStart(Worker $businessWorker)
{
$app = new Application;
$app->initialize();
}
/**
* onConnect 事件回调
* 当客户端连接上gateway进程时(TCP三次握手完毕时)触发
*
* @access public
* @param int $client_id
* @return void
*/
public static function onConnect($client_id)
{
Gateway::sendToCurrentClient("Your client_id is $client_id");
}
/**
* onWebSocketConnect 事件回调
* 当客户端连接上gateway完成websocket握手时触发
*
* @param integer $client_id 断开连接的客户端client_id
* @param mixed $data
* @return void
*/
public static function onWebSocketConnect($client_id, $data)
{
var_export($data);
}
/**
* onMessage 事件回调
* 当客户端发来数据(Gateway进程收到数据)后触发
*
* @access public
* @param int $client_id
* @param mixed $data
* @return void
*/
public static function onMessage($client_id, $data)
{
Gateway::sendToAll($data);
}
/**
* onClose 事件回调 当用户断开连接时触发的方法
*
* @param integer $client_id 断开连接的客户端client_id
* @return void
*/
public static function onClose($client_id)
{
GateWay::sendToAll("client[$client_id] logout\n");
}
/**
* onWorkerStop 事件回调
* 当businessWorker进程退出时触发。每个进程生命周期内都只会触发一次。
*
* @param \Workerman\Worker $businessWorker
* @return void
*/
public static function onWorkerStop(Worker $businessWorker)
{
echo "WorkerStop\n";
}
}
9.我再说一下我理解的 Events 类 中 onWebSocketConnect 的方法理解
onWebSocketConnect:官方:当客户端连接上gateway完成websocket握手时触发的回调函数。可以接收参数,然后在events.php 中做一些细小的处理(如:加入某个组,组名是参数中的某个字段)
其他就去参考手册吧,手册地址如下
10.gatewayworker 在linux下 常用的命令
php think worker:gateway //相当于临时启动,关闭窗口进程就关闭了
Ctrl+ C 即可停止gatewayworker
-----------------------------------------------------------
php think worker:gateway -d //关闭窗口进程也不会关闭
php think worker:gateway stop // 停止gatewayworker
11.Lib/Gateway类提供的接口 比较常用的如下:
Gateway::sendToAll($data); // 向全部客户端发送数据
Gateway::sendToClient($client_id, $data); // 向某个客户端发送数据
Gateway::closeClient($client_id); // 关闭某个客户端
Gateway::isOnline($client_id); // 判断某客户端链接是否在线
Gateway::bindUid($client_id, $uid); // 绑定 uid 与 client_id
Gateway::unbindUid($client_id, $uid); // 取消 uid 与 某个 client_id 的绑定
Gateway::isUidOnline($uid); // 某个 uid 是否在线
Gateway::GetClientIdByUid(); // 获取与 uid 绑定的 client_id 列表(一对多)
Gateway::sendToUid($uid, $data); // 向全部 uid 发送
Gateway::joinGroup($client_id, $group); // 把该 client_id 加入群组
Gateway::leaveGroup($client_id, $group); // 将 client_id 离开群组
Gateway::sendToGroup($group, $data); // 向某群组 group 发送
Gateway::getClientCountByGroup($group); // 获取某个组的在线链接数
Gateway::getClientSessionsByGroup($group); // 获取某个组的链接信息
Gateway::getClientInfoByGroup($group); // getClientSessionsByGroup 的别名
Gateway::getAllClientCount(); // 获取全部的在线链接数
Gateway::getAllClientSessions(); // 获取全部在线用户的 session
Gateway::getAllClientInfo(); // getAllClientSessions 的别名
Gateway::setSession($client_id, $session); // 设置 session,原 session 值会被覆盖
Gateway::updateSession($client_id, $session); // 更新 session,其实是与旧的session合并
Gateway::getSession($client_id); // 获取某个 client_id的 session
12.因为我用的是wss 连接 websocket 所以配置了 ssl 证书,说明一下,我之所以直接配置在域名里,是因为我百度到 workerman 不再支持SSLV3协议,所以我用了这个方法, 我用自己的服务器搭建的宝塔,配置如下:
下边代码可以复制粘贴 但要注意括号里是注释。
location /wss (wss这个也可以修改成 其他的)
{
proxy_pass http://127.0.0.1:(自己的端口如:6666);
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
(任选其一即可)另一种配置ssl 的方法,这个是手册上的, 参考如下网址:
13.前端代码也展示一下
业务需求 我分的是教师端和学生端
教师端代码
<script>
ws = new WebSocket('wss://你自己的地址/wss/?data={"resource_id":191705,"role":2}');
ws.onopen = function(){
console.log("链接成功")
ws.send('{"mode":"send_ppt"}');
}
// 服务端主动推送消息时会触发这里的onmessage
ws.onmessage = function(e){
//json数据转换成js对象
// var data = eval("("+e.data+")");
console.log(e.data);
};
</script>
注意:wss://你自己的地址/wss/?data={"resource_id":191705,"role":2}
这里的 "你自己的地址/wss/" 中的 wss 与 宝塔的配置文件 保持一致
这个参数 “?data={"resource_id":191705,"role":2}” 一般用不到,这个参数是配合 onWebSocketConnect 方法使用的