在 Laravel6 中使用 基于Workerman 的Gateway-worker进行 socket 长连接通讯

1、安装gateway-worker

gateway-worker 它已经引入了 workerman/workerman.

composer require workerman/gateway-worker
composer require workerman/gatewayclient

2. 创建 Workerman 启动文件

创建一个 artisan 命令行工具来启动 Socket 服务端,在 app/Console/Commands 目录下建立命令行文件。

php artisan make:command GatewayWorkerServer
<?php
 
namespace App\Console\Commands;
 
use Illuminate\Console\Command;
use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use Workerman\Worker;
 
 
class GatewayWorkerServer extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'workman {action} {--d}';
 
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Start a Workerman server.';
 
    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
 
    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
        global $argv;
        $action = $this->argument('action');
 
        $argv[0] = 'artisan workman';
        $argv[1] = $action;
        $argv[2] = $this->option('d') ? '-d' : '';   //必须是一个-,上面定义命令两个--,后台启动用两个--
 
        $this->start();
    }
 
    private function start()
    {
        $this->startGateWay();
        $this->startBusinessWorker();
        $this->startRegister();
        Worker::runAll();
    }
 
    private function startBusinessWorker()
    {
        $worker                  = new BusinessWorker();
        $worker->name            = 'BusinessWorker';
        $worker->count           = 1;
        $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                = 1;
        $gateway->lanIp                = '127.0.0.1';
        $gateway->startPort            = 2300;
        $gateway->pingInterval         = 30;
        $gateway->pingNotResponseLimit = 0;
        $gateway->pingData             = '{"type":"ping"}';
        $gateway->registerAddress      = '127.0.0.1:1236';
    }
 
    private function startRegister()
    {
        new Register('text://0.0.0.0:1236');
    }
 
       //php artisan workman start --d  之后    打开浏览器F12 将内容复制到console里return就行
       /* ws = new WebSocket("ws://*.*.*.*:2346");
        ws.onopen = function() {
            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("服务已断开" );
        };*/
 
}

3. 创建事件监听文件

创建一个 app/GatewayWorker/Events.php 文件来监听处理 workman 的各种事件。

<?php
/**
 * Created by PhpStorm.
 * User: ls
 * Date: 2020/3/25
 * Time: 16:09
 */
namespace App\GatewayWorker;
 
use GatewayWorker\Lib\Gateway;
use Illuminate\Support\Facades\Log;
 
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)
    {
        Log::info('Workerman close connection' . $client_id);
        echo "onClose\r\n";
    }
 
}

4、测试。 启动 Workerman 服务端

在命令行里面执行,支持的命令大概有 start|stop|restart,其中 --d 的意思是 daemon 模式,后台守护进程。

php artisan workman start --d //正式环境开发命令
php artisan workman start  //测试环境开发命令
ls@ls-virtual-machine:/var/www/html/socket/socket$ php artisan workman start --d
Workerman[artisan workman] start in DAEMON mode
-------------------------------------------- WORKERMAN ---------------------------------------------
Workerman version:4.0.2          PHP version:7.2.24-0ubuntu0.18.04.3
--------------------------------------------- WORKERS ----------------------------------------------
proto   user            worker            listen                      processes    status           
tcp     ls              Gateway           websocket://0.0.0.0:2346    1             [OK]            
tcp     ls              BusinessWorker    none                        1             [OK]            
tcp     ls              Register          text://0.0.0.0:1236         1             [OK]            
----------------------------------------------------------------------------------------------------
Input "php artisan workman stop" to stop. Start success.

在浏览器 F12 打开调试模式,在 Console 里输入

ws = new WebSocket("ws://*.*.*.*:2346");
    ws.onopen = function() {
        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("服务已断开" );
    }

使用swoole连接WebSocket时报错: WebSocket connection to ‘ws://124.207.120.104:9502/’ failed: Error in connection establish

请运行以下代码:
关闭防火墙:

systemctl stop firewalld.service

关闭后客户端出现如下图则说明连接成功。

官方手册:与ThinkPHP等框架结合-gateway-worker手册

具体功能的实现需要借助官方手册就可以实现轻松的完成

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xingxingwuxin

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值