基于 GatewayWorker 开发的 Laravel 扩展

Laravel GatewayWorker

在项目开发的过程中,我使用了基于 workerman 开发的 GatewayWorker 扩展,为了与 Laravel 进行整合,翻看了一些相关的技术文章,但感觉都不太符合我心中想要的效果。为了能够在 Laravel 中更优雅的使用 GatewayWorker 于是我自己造了个轮子,开发了 laravel-gateway-worker 扩展,使其能够开箱即用,并可灵活配置和增加服务。

安装

composer require smileymrking/laravel-gateway-worker

配置

Laravel

  1. config/app.php 注册 ServiceProvider 和 Facade (Laravel 5.5 + 无需手动注册)
'providers' => [
    // ...
    SmileyMrKing\GatewayWorker\GatewayWorkerServiceProvider::class,
];
  1. 创建配置文件:
php artisan vendor:publish --provider="SmileyMrKing\GatewayWorker\GatewayWorkerServiceProvider"
  1. 修改应用根目录下的 config/gateway-worker.php 中对应的配置即可。

Lumen

并未使用过 Lumen 未实际测试,以下参考其他扩展包编写

  1. bootstrap/app.php 中 82 行左右:
$app->register(SmileyMrKing\GatewayWorker\GatewayWorkerServiceProvider::class);
  1. 发布 config/gateway-worker.php 配置文件,将 vendor/smileymrking/laravel-gateway-worker/config/gateway-worker.php 拷贝到项目根目录/config目录下。

配置文件中已默认创建了一个名为 push 的 websocket 服务,配置如下,可自行调整相关配置,或无需发布配置文件,直接进入下一步启动服务

return [

    /*
    |--------------------------------------------------------------------------
    | Gateway Worker Service
    |--------------------------------------------------------------------------
    */

    'default_service' => 'push', # 默认的 Gateway::$registerAddress 设置为 push.register_address

    'push' => [
        'service' => \SmileyMrKing\GatewayWorker\Push\Push::class,
        'lan_ip' => env('WS_LAN_IP', '127.0.0.1'), #内网ip,多服务器分布式部署的时候需要填写真实的内网ip

        'register' => env('WS_REGISTER', 'text://0.0.0.0:20000'),
        'register_address' => env('WS_REGISTER_ADDRESS', '127.0.0.1:20000'), #注册服务地址

        'worker_name' => 'PushBusinessWorker', #设置 BusinessWorker 进程的名称
        'worker_count' => 1, #设置 BusinessWorker 进程的数量
        # 设置使用哪个类来处理业务,业务类至少要实现onMessage静态方法,onConnect 和 onClose 静态方法可以不用实现
        'event_handler' => \SmileyMrKing\GatewayWorker\Push\PushEvent::class,

        'gateway' => env('WS_GATEWAY', 'websocket://0.0.0.0:20010'),# 允许连接服务的地址
        'gateway_name' => 'PushGateway', #设置 Gateway 进程的名称,方便status命令中查看统计
        'gateway_count' => 1, # Gateway 进程的数量
        'start_port' => env('WS_START_PORT', '20100'),  #监听本机端口的起始端口
        'ping_interval' => 55,  # 心跳间隔时间,只针对服务端发送心跳
        'ping_not_response_limit' => 1,   # 0 服务端主动发送心跳, 1 客户端主动发送心跳
        'ping_data' => '{"type":"ping"}', # 服务端主动发送心跳的数据,只针对服务端发送心跳,客户端超时未发送心跳时会主动向客户端发送一次心跳检测

        'gateway_start' => true,
        'business_worker_start' => true,
        'register_start' => true,

        'gateway_transport' => 'tcp', // 当为 ssl 时,开启SSL,websocket+SSL 即 wss
        /*'gateway_context' => [
            // 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
            'ssl' => array(
                // 请使用绝对路径
                'local_cert' => '/your/path/of/server.pem', // 也可以是crt文件
                'local_pk' => '/your/path/of/server.key',
                'verify_peer' => false,
                'allow_self_signed' => true, //如果是自签名证书需要开启此选项
            )
        ],*/
    ],

];

启动服务

使用以下命令启动服务
php artisan gateway-worker {serviceName} {action} {--d}

参数 释义
serviceName 服务名称,即配置文件中的键名
action 操作命令,可用命令有 statusstartstoprestartreloadconnections
--d 使用 DAEMON 模式
> php artisan gateway-worker push start

Workerman[gateway-worker push] start in DEBUG mode
----------------------------------------------- WORKERMAN -----------------------------------------------
Workerman version:4.0.6          PHP version:7.2.5-1+ubuntu18.04.1+deb.sury.org+1
------------------------------------------------ WORKERS ------------------------------------------------
proto   user            worker                listen                       processes    status
tcp     vagrant         PushGateway           websocket://0.0.0.0:20010    1             [OK]
tcp     vagrant         PushBusinessWorker    none                         1             [OK]
tcp     vagrant         Register              text://0.0.0.0:20000         1             [OK]
---------------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.

push 为默认创建的服务名称,可同步发布配置文件,自行修改相关配置

创建多个服务

可同时启动多个服务

参考 push 服务,手动创建一个 Demao 类,继承 SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerService
定义一个 $serviceName 属性,值为下一步所添加配置文的键名


namespace App\GatewayWorker\Demo;

use SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerService;

class Demo extends GatewayWorkerService
{
    protected $serviceName = 'demo';
}

直接复制一份 push 的配置文件进行修改,注意需要修改 worker_namegateway_name 和相关端口的配置,避免重复
添加配置的键名为 上一步定义的 $serviceName 的值,配置中 service 执行上一步配置的 Demo 类

return [
    // ...
    'demo' => [
        'service' => \App\GatewayWorker\Demo\Demo::class,
        'lan_ip' => env('WS_LAN_IP_DEMO', '127.0.0.1'), #内网ip,多服务器分布式部署的时候需要填写真实的内网ip

        'register' => env('WS_REGISTER_DEMO', 'text://0.0.0.0:20000'),
        'register_address' => env('WS_REGISTER_ADDRESS_DEMO', '127.0.0.1:20000'), #注册服务地址

        'worker_name' => 'DemoBusinessWorker', #设置 BusinessWorker 进程的名称
        'worker_count' => 1, #设置 BusinessWorker 进程的数量
        # 设置使用哪个类来处理业务,业务类至少要实现onMessage静态方法,onConnect 和 onClose 静态方法可以不用实现
        'event_handler' => \App\GatewayWorker\Demo\DemoEvent::class,

        'gateway' => env('WS_GATEWAY_DEMO', 'websocket://0.0.0.0:20010'),# 允许连接服务的地址
        'gateway_name' => 'DemoGateway', #设置 Gateway 进程的名称,方便status命令中查看统计
        'gateway_count' => 1, # Gateway 进程的数量
        'start_port' => env('WS_START_PORT_DEMO', '20100'),  #监听本机端口的起始端口
        'ping_interval' => 55,  # 心跳间隔时间,只针对服务端发送心跳
        'ping_not_response_limit' => 1,   # 0 服务端主动发送心跳, 1 客户端主动发送心跳
        'ping_data' => '{"type":"ping"}', # 服务端主动发送心跳的数据,只针对服务端发送心跳,客户端超时未发送心跳时会主动向客户端发送一次心跳检测

        'gateway_start' => true,
        'business_worker_start' => true,
        'register_start' => true,

        'gateway_transport' => 'tcp', // 当为 ssl 时,开启SSL,websocket+SSL 即 wss
        /*'gateway_context' => [
            // 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
            'ssl' => array(
                // 请使用绝对路径
                'local_cert' => '/your/path/of/server.pem', // 也可以是crt文件
                'local_pk' => '/your/path/of/server.key',
                'verify_peer' => false,
                'allow_self_signed' => true, //如果是自签名证书需要开启此选项
            )
        ],*/
    ],

];

配置修改完成后使用 php artisan gateway-worker demo start 命令启动,demo 为刚刚配置的键名
event_handler 未配置时默认使用 SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerEvents ,实现了 onMessageonConnectonClose 三个静态方法
可自定义 event_handler 类,需要继承 SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerEvents 然后重写相关静态方法

namespace App\GatewayWorker\Demo;

use SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerEvents;

class DemoEvent extends GatewayWorkerEvents
{
    public static function onMessage($client_id, $message)
    {
        // Do something
    }
}

default_service 配置是指定 Gateway::$registerAddress 默认连接的哪个服务的注册地址 register_address

消息推送

可直接使用 GatewayWorker 中的 \GatewayWorker\Lib\Gateway 类,具体用法请查看 GatewayWorker 手册

日志查看

通过配置文件中 service 项所配置的类的命名空间查看
push 服务的日志文件路径为 vendor/smileymrking/laravel-gateway-worker/src/GatewayWorker/worker
日志名称为 smileymrking_gatewayworker_push_push.log

启动进程 pid 文件与日志文件路径和名称相同,后缀为 .pid

参考

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 16
mouyong

这是被雪藏的文章吗

3年前 评论
i-am-king (楼主) 3年前
mouyong (作者) 3年前
i-am-king (楼主) 3年前

安装失败已经提交Issues了

3年前 评论
i-am-king (楼主) 3年前

多开 照着操作下来提示demo’s GatewayWorker config doesn’t exist
service和event_handler都改了
端口也都改了
是哪里还有问题吗

3年前 评论

@samuelt 是配置文件中的 service 没有填写吗?这个配置为空的话会提示这个错误

# config/gateway-worker.php
return [
    'demo' => [
    //···
        'service' => \App\Gatewayworker\Demo\Demo::class,// 指向自定义服务的类
    //···
    ]
];
3年前 评论
samuelt 3年前
i-am-king (作者) (楼主) 3年前

大佬,这个能用在实际生产中么?想用这个来实现服务器主动推送消息给客户端(安卓,ios)

3年前 评论

@shuluo 可以的,我的荣幸,这个包主要是为了使 GatewayWorker 扩展能够方便的在 Laravel 中安装启动,使用方法完全可以直接参考其官方文档 GatewayWorker2.x 3.x 手册

3年前 评论

请教下。开启wss一直连接不上,这个一直没有找到原因。

3年前 评论

@qinhai 看是不是证书或配置的问题,gateway_transport 这个配置要改下,另外我是通过 nginx反向代理实现的 wss

3年前 评论

你好,我完全按照步骤开发的,为什么启动不了呢,没有任何启动状态 PS D:\phpstudy_pro\WWW\pandaGoRent> php artisan gateway-worker push start ----------------------- WORKERMAN ----------------------------- Workerman version:4.1.5 PHP version:8.0.2 ------------------------ WORKERS ------------------------------- worker listen processes status

2年前 评论
alex1122 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!