1.使用 composer 安装
composer require workerman/workerman-for-win composer require workerman/gateway-worker-for-win
2.构造启动方法 Gate.php,命名空间根据位置自己的文件位置调整。
其中 $worker->eventHandler 参数填写的是逻辑文件的地址,逻辑文件创建在下一步
<?php /** * linux workerman例子测试 */ namespace app\common\controller; use think\Env; use Workerman\Worker; use GatewayWorker\Gateway; use GatewayWorker\Register; use GatewayWorker\BusinessWorker; class Gate { /** * 构造函数 * @access public */ public function __construct(){ //初始化各个GatewayWorker //初始化register register 服务必须是text协议 $register = new Register('text://0.0.0.0:1236'); //初始化 bussinessWorker 进程 $worker = new BusinessWorker(); // worker名称 $worker->name = 'ChatBusinessWorker'; // bussinessWorker进程数量 $worker->count = 4; // 服务注册地址 $worker->registerAddress = '127.0.0.1:1236'; //设置处理业务的类,此处制定Events的命名空间 $worker->eventHandler = 'app\common\socket\Workerman'; // 初始化 gateway 进程 $gateway = new Gateway("websocket://".Env::get('socket.host', '0.0.0.0').":".Env::get('socket.port', '9004')); // 设置名称,方便status时查看 $gateway->name = 'ChatGateway'; $gateway->count = 4; // 分布式部署时请设置成内网ip(非127.0.0.1) $gateway->lanIp = '127.0.0.1'; // 内部通讯起始端口,假如$gateway->count=4,起始端口为4000 // 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口 $gateway->startPort = 2300; // 心跳间隔 $gateway->pingInterval = 10; // 心跳数据 $gateway->pingData = '{"a":1,"d":"pong","t":1}'; // 服务注册地址 $gateway->registerAddress = '127.0.0.1:1236'; //运行所有Worker; Worker::runAll(); } }
3.创建逻辑执行文件 Workerman.php,同样的命名空间根据位置修改。
其他推送消息给个人、推送消息给某个组、用户加入某个组、绑定client_id和uid 等方法均在类GatewayWorker\Lib\Gateway里面。文档可以参考 http://doc2.workerman.net/on-messsge.html
<?php namespace app\common\socket; use think\Env; use Exception; use Workerman\Worker; use Workerman\Lib\Timer; use GatewayWorker\Lib\Gateway; class Workerman { /** * 消息处理 * @param int $client_id * @param mixed $message */ public static function onMessage($client_id, $message) { try { // 客户端传递的是json数据 self::handle_message($client_id, $message); } catch (Exception $e) { return Gateway::sendToCurrentClient('请求数据不正确'); } } /** * 当客户端断开连接时 * @param integer $client_id 客户端id */ public static function onClose($client_id) { // debug echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']} client_id:{$client_id} onClose:''\n"; } /** * 定时推送 * * @param [type] $worker * @return void */ public static function onWorkerStart($worker) { Timer::add(1, function() use($worker) { }); } /** * 客户端消息处理 * * @param [type] $client_id * @param string $data * @return void */ protected static function handle_message($client_id, $data) { $param = json_decode($data, true); // TODO 处理数据 } }
需要注意长连接,容易出现数据库连接中断的问题,报错 mysql has gone away,可以在定时任务中每30秒执行一次查询来解决数据库断开的问题
4.最后创建启动文件 gateway.php 放在根目录
<?php /** * 此文件只能在Linux运行 */ ini_set('display_errors', 'on'); if(strpos(strtolower(PHP_OS), 'win') === 0) { exit("not support windows.\n"); } //检查扩展 if(!extension_loaded('pcntl')) { exit("Please install pcntl extension"); } if(!extension_loaded('posix')) { exit("Please install posix extension"); } define('APP_PATH', __DIR__ . '/application/'); define('BIND_MODULE','common/Gate'); // 加载框架引导文件 require __DIR__ . '/thinkphp/start.php';
5.启动命令
php gateway.php start php gateway.php start -d 守护进程
6.(可选)监听文件 listen.sh 主要作用是在 workerman 主进程崩溃之后,重启进程
创建 listen.sh 在根目录,写入内容。添加到 linux 的定时任务中 ,/home/wwwroot/project 替换成自己的项目路径
#! /bin/bash cd /home/wwwroot/live; # need to listen process process=('WorkerMan: master'); # exec process action actions=('php /home/wwwroot/project/gateway.php start -d'); for((i=0;i<"${#process[@]}";i++)) do pid=$(ps aux | grep "${process[i]}" | grep -v grep | awk '{print $2}'); if [ "${pid}" == '' ] && [ "${actions[i]}" != '' ]; then eval "${actions[i]}"; fi done;
写入定时任务的流程
# 编辑定时任务,没有crontab的话百度自行安装 crontab -e # 输入 * * * * sh /home/wwwroot/project/listen.sh > /dev/null 2>&1 # 然后保存 :wq # 查看是否保存成功 crontab -l
评论已关闭。