在 Laravel 中使用 GatewayWorker 进行 socket 长连接通讯
初次接触GatewayWorker框架,先阅读示例:Linux系统快速开始(从一个精简的聊天demo开始)。查看文件目录结构:
GatewayWorker ├── Applications // 这里是所有开发者应用项目 │ └── YourApp // 其中一个项目目录,目录名可以自定义 │ ├── Events.php // 开发者只需要关注这个文件 │ ├── start_gateway.php // gateway进程启动脚本,包括端口号等设置 │ ├── start_businessworker.php // businessWorker进程启动脚本 │ └── start_register.php // 注册服务启动脚本 │ ├──start.php // 全局启动脚本,此脚本会依次加载Applications/项目/start_*.php启动脚本 │ └──vendor // GatewayWorker框架和Workerman框架源码目录,此目录开发者不用关心
在 Laravel 框架中使用,有两种方式:
- 方式一:根据示例,复制
Applications
目录下文件,到 Laravel 框架到app
目录下,可以自定义新目录,并且修改start.php文件中的相应的加载位置。 - 方式二:使用 Laravel 框架提供的
php artisan
命令工具来做启动。把start.php
、start_gateway.php
、start_register.php
、start_businessworker.php
四个文件内容,合并在一起。
1、安装 GatewayWorker
composer require workerman/gateway-workercomposer require workerman/gatewayclient
2、创建 Workerman 启动文件
创建一个 artisan 命令行工具来启动 Socket 服务端,在app/Console/Commands
目录下建立命令行文件。
php artisan make:command GatewayworkerCommand
app/Console/Commands/GatewayworkerCommand 内容如下:
<?phpnamespace App\Console\Commands;use Illuminate\Console\Command;use Workerman\Worker;use Workerman\WebServer;use Workerman\Autoloader;use GatewayWorker\Gateway;use GatewayWorker\Register;use GatewayWorker\BusinessWorker;use App\Gatewayworker\Events; class GatewayworkerCommand extends Command { protected $signature = 'Workerman {action} {--d}'; protected $description = 'Start a Workerman server'; public function __construct() { parent::__construct(); } public function handle() { $this->startGateWay(); $this->startBusinessWorker(); $this->startRegister(); Worker::runAll(); } private function startBusinessWorker() { $worker = new BusinessWorker(); $worker->name = 'BusinessWorker'; $worker->count = 4; $worker->registerAddress = '127.0.0.1:1236'; $worker->eventHandler = \App\Gatewayworker\Events::class; } private function startGateWay() { $gateway = new Gateway("websocket://0.0.0.0:2346"); $gateway->name = 'Gateway'; $gateway->count = 4; $gateway->lanIp = '127.0.0.1'; $gateway->registerAddress = '127.0.0.1:1236'; } private function startRegister() { new Register('text://0.0.0.0:1236'); } }
3、创建事件监听文件
创建一个app/Gatewayworker/Events.php文件来监听处理 workman 的各种事件。
<?phpnamespace App\Gatewayworker;use GatewayWorker\Lib\Gateway; class Events { public static function onWorkerStart($businessWorker) { echo "onWorkerStart\r\n"; } public static function onConnect($client_id) { Gateway::sendToClient($client_id, json_encode(['type' => 'onConnect', 'client_id' => $client_id])); echo "onConnect\r\n"; } public static function onWebSocketConnect($client_id, $data) { echo "onWebSocketConnect\r\n"; } public static function onMessage($client_id, $message) { Gateway::sendToClient($client_id, json_encode(['type' => 'onMessage', 'client_id' => $client_id, 'name' => json_decode($message)->name])); echo "onMessage\r\n"; } public static function onClose($client_id) { echo "onClose\r\n"; } }
4、开启服务
在命令行里面执行,支持的命令有start|stop|restart
,其中--d
的意思是 daemon 模式,后台守护进程。
php artisan workerman start
显示如下:
Workerman[artisan] start in DEBUG mode -------------------------------------------- WORKERMAN --------------------------------------------- Workerman version:4.0.20 PHP version:8.0.12 --------------------------------------------- WORKERS ---------------------------------------------- proto user worker listen processes status tcp root Gateway websocket://0.0.0.0:2346 4 [OK] tcp root BusinessWorker none 4 [OK] tcp root Register text://0.0.0.0:1236 1 [OK] ---------------------------------------------------------------------------------------------------- Press Ctrl+C to stop. Start success. onWorkerStart onWorkerStart onWorkerStart onWorkerStart
5、在浏览器中测试
用 chrome 浏览器打开此 Laravel 框架建设的网站,打开控制台(快捷键按F12)。在Console里输入:
var ws =new WebSocket("ws://127.0.0.1:2346"); ws.onopen = function(e) { ws.send('{"name":"one","user_id":"111"}'); ws.send('{"name":"two","user_id":"222"}'); }; ws.onmessage = function(e) { console.log("收到服务端的消息:" + e.data); }; ws.onclose = function(e) { console.log("服务已断开" ); }
成功!