您现在的位置是:首页 > 经验记录>磨刀不误砍柴工>在 Laravel 中使用 基于Workerman 的Gateway-worker进行 socket 长连接通讯 网站首页 磨刀不误砍柴工

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

1、安装gateway-worker

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


composer require workerman/gateway-worker

composer require workerman/gatewayclient

如果找不到此包,建议更换composer源。阿里的源找不到,我重置到官方源可以安装。源连接


它们两个接口很多是类似的。


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://192.168.136.128: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

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://192.168.136.128: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("服务已断开" );

    }

 



OK!

 


如果需要在控制器里手动发送消息?

<?php

 

namespace App\Http\Controllers;

 

use Illuminate\Http\Request;

use GatewayClient\Gateway;

use Illuminate\Support\Facades\Log;

 

class H5ssController extends Controller

{

 

    public function __construct()

    {

        // 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值(ip不能是0.0.0.0)

        Gateway::$registerAddress = '127.0.0.1:1236';

 

    }

 

    public static function sendMessage(Request $request)

    {

 

        $data = $request->json()->all();

        $message = json_encode($data);

        Gateway::sendToAll($message); //给所有客户端发消息

        Gateway::sendToClient($client_id, $data);

        Gateway::sendToUid($uid, $message);// 向任意uid的网站页面发送数据 

    }

Gateway::sendToAll($data);

Gateway::sendToClient($client_id, $data);

Gateway::closeClient($client_id);

Gateway::isOnline($client_id);

Gateway::bindUid($client_id, $uid);

Gateway::isUidOnline($uid);

Gateway::getClientIdByUid($uid);

Gateway::unbindUid($client_id, $uid);

Gateway::sendToUid($uid, $data);

Gateway::joinGroup($client_id, $group);

Gateway::sendToGroup($group, $data);

Gateway::leaveGroup($client_id, $group);

Gateway::getClientCountByGroup($group);

Gateway::getClientSessionsByGroup($group);

Gateway::getAllClientCount();

Gateway::getAllClientSessions();

Gateway::setSession($client_id, $session);

Gateway::updateSession($client_id, $session);

Gateway::getSession($client_id);

参考1    参考2 

————————————————

版权声明:本文为CSDN博主「追梦赤子心刘大哥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_37035946/article/details/105101436


文章评论

未开放
Top