栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

手把手教你Laravel 集成 GatewayWorker (Workerman),实现简单的聊天系统.

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

手把手教你Laravel 集成 GatewayWorker (Workerman),实现简单的聊天系统.

GatewayWorker 与 Workerman的关系

Workerman可以看做是一个纯粹的socket类库,可以开发几乎所有的网络应用,不管是TCP的还是UDP的,长连接的还是短连接的。Workerman代码精简,功能强大,使用灵活,能够快速开发出各种网络应用。同时Workerman相比GatewayWorker也更底层,需要开发者有一定的多进程编程经验。

因为绝大多数开发者的目标是基于Workerman开发TCP长连接应用,而长连接应用服务端有很多共同之处,例如它们有相同的进程模型以及单发、群发、广播等接口需求。所以才有了GatewayWorker框架,GatewayWorker是基于Workerman开发的一个TCP长连接框架,实现了单发、群送、广播等长连接必用的接口。GatewayWorker框架实现了Gateway Worker进程模型,天然支持分布式多服务器部署,扩容缩容非常方便,能够应对海量并发连接。可以说GatewayWorker是基于Workerman实现的一个更完善的专门用于实现TCP长连接的项目框架。

用GatewayWorker还是Workerman?

如果你的项目是长连接并且需要客户端与客户端之间通讯,建议使用GatewayWorker。
短连接或者不需要客户端与客户端之间通讯的项目建议使用Workerman。
GatewayWorker不支持UDP监听,所以UDP服务请选择Workerman。
如果你是一个有多进程socket编程经验的人,喜欢定制自己的进程模型,可以选择Workerman。

一、在 composer.json 文件的 require 引入包
    "workerman/gateway-worker": "^3.0",
    "workerman/gatewayclient": "^3.0",
    "workerman/workerman": "^3.5"


终端的项目根目录输入 composer install,也可以composer update不过不建议

二、在 AppConsoleCommands 目录创建 GatewayWorkerServer.php 文件,作为服务端口的启动文件
argument('action'), ['start', 'stop', 'restart'])) {
            $this->error('Error Arguments');
            exit;
        }
        $argv[0] = 'gateway-worker:server';
        $argv[1] = $action;
        $argv[2] = $this->option('daemon') ? '-d' : '';//该参数是以daemon(守护进程)方式启动
        $this->start();
    }

    public function start()
    {
        $this->startGateWay();
        $this->startBusinessWorker();
        $this->startRegister();
        Worker::runAll();
    }

    public function startBusinessWorker()
    {
        $work = new BusinessWorker();
        $work->name = 'BusinessWorker';#设置BusinessWorker进程的名称
        $work->count = 2;#设置BusinessWorker进程的数量
        $work->registerAddress = '127.0.0.1:9501';#注册服务地址
        $work->eventHandler = Events::class;#设置使用哪个类来处理业务,业务类至少要实现onMessage静态方法,onConnect和onClose静态方法可以不用实现
    }

    public function startGateWay()
    {
        $gateway = new Gateway("websocket://0.0.0.0:9502");
        $gateway->name = 'Gateway';#设置Gateway进程的名称,方便status命令中查看统计
        $gateway->count = 2;#进程的数量
        $gateway->lanIp = '127.0.0.1';#内网ip,多服务器分布式部署的时候需要填写真实的内网ip
        $gateway->startPort = 9000;#监听本机端口的起始端口
        $gateway->pingInterval = 30;
        $gateway->pingNotResponseLimit = 0;#服务端主动发送心跳
        $gateway->pingData = '{"mode":"heart"}';
        $gateway->registerAddress = '127.0.0.1:9501';#注册服务地址
    }

    public function startRegister()
    {
        new Register('text://127.0.0.1:9501');
    }

	//ws = new WebSocket("ws://127.0.0.1:9502");
	//ws.onopen = function() {
	//    ws . send('{"mode":"say","from_uid":1,to_uid:2,"content":"文字内容"}');
	//    ws . send('{"mode":"chats","from_uid":1}');
	//};
	//ws.onmessage = function(e) {
	//    console.log("收到服务端的消息:" + e.data);
	//};
}

注意事项:
(1)$gateway->startPort监听本机端口的起始端口要小与其它端口
(2)进程数为CPU核数的1-2倍左右即可,当然如果你是32核的你也可以设置进程数为8,看实际情况而定

三、在 AppConsoleKernel 引入 GatewayWorkerServer::class
command('inspire')
        //          ->hourly();
    }

    
    // protected function commands()
    // {
        // $this->load(__DIR__.'/Commands');

        // require base_path('routes/console.php');
    // }
}

也可加上面的 protected function commands ,然后在routes/consele.php里加以下代码

Artisan::command('inspire', function () {
    $this->comment(Inspiring::quote());
})->describe('Display an inspiring quote');

四、在 app 目录下创建 GatewayWorker/Events.php 监听文件
 'init', 'client_id' => $client_id]));
    }

    public static function onWebSocketConnect($client_id, $data)
    {

    }

    public static function onMessage($client_id, $message)
    {
    	//以下为业务逻辑,自行修改
        $response = ['status' => 200, 'msg' => 'ok', 'data' => $message];
        $message = json_decode($message);

        if (!isset($message->mode)) {
            $response['msg'] = 'missing parameter mode';
            $response['errcode'] = ERROR_CHAT;
            Gateway::sendToClient($client_id, json_encode($response));
            return false;
        }
        $from_uid = $message->from_uid;
        $to_uid = $message->to_uid;;
        switch ($message->mode) {
            case 'say':   #处理发送的聊天
                $chats = Chats::create(['from_id' => $from_uid, 'to_id' => $to_uid, 'content' => $content, 'no' => $count + 1]);
                $chats = Chats::select(['from_id', 'to_id', 'content'])->find($chats->id);
                $response['data'] = $chats;
                if (Gateway::isUidOnline($to_uid)) {
                    $response['msg'] = '已发送至uid为:' . $to_uid;
                    Gateway::sendToUid($to_uid, json_encode($response));
                } else {
                    $response['msg'] = '对方不在线';
                }
                break;
            case 'chats':  #获取聊天列表
                $chats = Chat::where('from_id', $message->from_id)->get();
                $response['data'] = ['chats' => $chats];
                break;
            default:
                $response['status'] = 201;
                $response['msg'] = 'Undefined';
        }

        Gateway::sendToClient($client_id, json_encode($response));
    }

    public static function onClose($client_id)
    {
        Log::info('close connection' . $client_id);
    }
}

注意:每次修改events.php后,记得重启,记得重启,记得重启

五、开启服务终端,命令行输入

php artisan gateway-worker:server start

其它命令:

以debug(调试)方式启动:php artisan gateway-worker:server start

以daemon(守护进程)方式启动:php artisan gateway-worker:server start --daemon

停止:php artisan gateway-worker:server stop

重启:php artisan gateway-worker:server restart

平滑重启:php artisan gateway-worker:server reload

查看状态:php artisan gateway-worker:server status
.

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

ws = new WebSocket("ws://127.0.0.1:9502");
ws.onopen = function() {
	ws . send('{"mode":"say","from_uid":1,to_uid:2,"content":"文字内容"}');
	ws . send('{"mode":"chats","from_uid":1}');
};
ws.onmessage = function(e) {
	console.log("收到服务端的消息:" + e.data);
};

就能打印出对应的信息了

参考:
Workerman官方手册、GatewayWorker官方手册、Laravel官方手册、
https://learnku.com/articles/25208

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/677635.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号