欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

laravel+workerman/gateway-worker 从安装到运行

程序员文章站 2022-05-19 19:18:52
...

使用composer安装, 所以先要确保安装了composer工具

1. 为了安装快, 安装一个composer扩展hirak/prestissimo, 可以多线程下载

composer global require hirak/prestissimo

2. 设置镜像地址为阿里云(使用官方镜像会有被墙资源, 安装很可能失败)

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

3. 安装laravel, 我选择了最新版7.x

composer create-project laravel/laravel my-project--prefer-dist "7.*.*"

4. 安装 gateway-worker

composer require workerman/gateway-worker 

安装完gateway-worker, 在vendor目录会看到workman目录, 如下图:
laravel+workerman/gateway-worker 从安装到运行

5. 创建 Workerman 启动文件

5.1 用artisan命令创建command文件

// 创建一个artisan command文件
// 生成的文件路径: Console\Commands\GatewayWorkerServer.php
php artisan make:command GatewayWorkerServer

生成文件 如下图结构:
laravel+workerman/gateway-worker 从安装到运行

5.2 GatewayWorkerServer.php 写入以下内容

<?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("服务已断开" );
     };*/

}


6. 创建事件监听文件

在app目录下新建目录GatewayWorker, 然后在该目录下新建文件Events.php , 然后写入以下内容

<?php
/**
 * Created by PhpStorm.
 * User: dozhihong
 * Date: 2020/5/3
 * Time: 15.19
 */
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";
    }

}

7. 测试

7.1 部署一台linux服务器

打开php禁用函数

1. pcntl_fork()
2. pcntl_wait()
3. pcntl_signal_dispatch()
4. pcntl_signal()
5. pcntl_alarm()

运营商服务器控制面板 入站规则, 放开端口
TCP:2346
如图:

laravel+workerman/gateway-worker 从安装到运行
linux防火墙放行 2346, 这里使用宝塔面板, 直接在里面放行, 如下图
laravel+workerman/gateway-worker 从安装到运行

说明: 需要放行的端口, 就是GatewayWorkerServer.php中, new Gateway(“websocket://0.0.0.0:2346”); 中所写的端口

7.2 把代码部署在linux服务器上

7.3 启动workman

/www/server/php/73/bin/php artisan workman

laravel+workerman/gateway-worker 从安装到运行

7.4 测试连接

打开浏览器, 输入网站随便一个页面, F12打开控制台, 输入代码

ws = new WebSocket("ws://58.87.95.128:2346")

观查network,Status为101, 就是成功
如图:
laravel+workerman/gateway-worker 从安装到运行

laravel+workerman/gateway-worker 从安装到运行

PS: 在这过程中, 会有很多小伙伴遇到客户端连接失败问题 , workman官方总结的很到位, 地址: http://doc.workerman.net/faq/client-connect-fail.html