安装gateway-worker

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

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

php artisan make:command GatewayWorkerServer

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

创建一个 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";
    }
 
}

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

php artisan workman start --d

客户端js html代码测试一下

var ws = new WebSocket("ws://192.168.1.118: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("服务已断开" );
}

**如果用到ssl,本地测试时
本地可以用openssl生成自定义证书**

yum install openssl yum install openssl-devel
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 3650 -out certificate.pem

在执行此命令后,将被提示输入一些信息,例如国家/地区、州、城市、公司等。在输入完这些信息后,将生成名为 key.pem 和 certificate.pem 的文件。key.pem 文件包含 SSL 密钥,certificate.pem 文件包含 SSL 证书。

$ws_domain = env('WS_DOMAIN'); // ws_domain最好不要直接用主域名 用子域
$context = array(
    'ssl' => array(
        // 请使用绝对路径
        'local_cert'                 => '/micro/conf/nginx/conf.d/cert/'.$ws_domain.'.pem', // 也可以是crt文件
        'local_pk'                   => '/micro/conf/nginx/conf.d/cert/'.$ws_domain.'.key',
        'verify_peer'                => false,
        // 'allow_self_signed' => true, //如果是自签名证书需要开启此选项
    )
);

$gateway = new Gateway("websocket://0.0.0.0:12396", $context);// 外部连接 用0.0.0.0
$gateway->name                 = 'Gateway';
$gateway->transport            = 'ssl';
$gateway->count                = 2;
$gateway->lanIp                = '127.0.0.1';
$gateway->startPort            = 2300;
$gateway->pingInterval         = 50;
$gateway->pingNotResponseLimit = 0;
$gateway->pingData             = '{"type":"ping"}';
$gateway->registerAddress      = '127.0.0.1:1236';   // Worker

//2
$gateway2 = new Gateway("websocket://127.0.0.1:15396"); // 内部连接 用127.0.0.1
$gateway2->name                 = 'Gateway2';
$gateway2->count                = 1;
$gateway2->lanIp                = '127.0.0.1';
$gateway2->startPort            = 5300;
$gateway2->pingInterval         = 30;
$gateway2->pingNotResponseLimit = 0;
$gateway2->pingData             = '{"type":"ping"}';
$gateway2->registerAddress      = '127.0.0.1:1236';   // Worker

标签: none

评论已关闭