14、Workerman 基本使用 - Laravel 10.x 中使用 Workerman

作者: 温新

图书: 【Workerman 基本使用】

阅读: 192

时间: 2024-04-23 00:40:28

hi,我是温新,一名 PHPer

前置条件:假设 PHP 相关环境已经准备完成。

Laravel 10.x 中使用 Workerman

1、安装 Laravel 项目

$ laravel new latest

2、安装 workerman

$ cd latest
$ composer require workerman/workerman

3、创建 workerman 命令

由于 workerman 是给予 cli 模式启动的,因此需要使用 Laravel 的自定义命令来实现。

1)生成文件

$ php artisan make:command WorkermanHttpServer

2)编写逻辑代码

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Workerman\Connection\TcpConnection;
use Workerman\Worker;

/**
 * Workerman 服务
 */
class WorkermanHttpServer extends Command
{
    protected $signature = 'workerman:httpserver {action} {--d}';

    protected $description = 'Workerman HTTP Server';

    public function handle()
    {
        $action = $this->argument('action');
        if (! in_array($action, ['start', 'stop', 'reload'])) {
            $this->error('参数错误');
            exit;
        }

        $worker = new Worker('websocket://0.0.0.0:8888');

        switch ($action) {
            case 'start':
                $worker->onConnect = function (TcpConnection $connection) {
                    echo '客户端连接:' . $connection->id . PHP_EOL;
                };

                if ($this->option('d')) {
                    $worker->daemonize = true;
                }

                $worker->onMessage = function (TcpConnection $connection, $data) {
                    $connection->send($data . mt_rand(10000, 99999));
                };

                Worker::runAll();
                break;
            case 'stop':
                break;
            case 'reload':
                break;
        }
    }
}

4、启动服务

$ php artisan workerman:httpserver start
Workerman[artisan] start in DEBUG mode
------------------------------------------- WORKERMAN --------------------------------------------
Workerman version:4.1.15          PHP version:8.2.0           Event-Loop:\Workerman\Events\Event
-------------------------------------------- WORKERS ---------------------------------------------
proto   user            worker          listen                      processes    status           
tcp     codeing         none            websocket://0.0.0.0:8888    1             [OK]            
--------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
客户端连接:1

测试 Workerman 服务

1、创建控制器

$ php artisan make:controller TestController

2、定义路由

<?php
// routes/web.php
    
...

Route::get('test/index', [\App\Http\Controllers\TestController::class, 'index']);

3、编写控制器

app/Http/Controllers/TestController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index()
    {
        return view('test.index');
    }
}

4、编写视图页面

resources/views/test/index.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel & Workerman</title>
</head>
<body>
    <h1>Laravel 10 & Workerman</h1>

    <input type="text" name="msg" value="" id="msg">
    <input type="button" value="发送" id="send">
    <ul id="messageList"></ul>

    <script>
        let msgObj  = document.getElementById('msg');
        let sendObj = document.getElementById('send');
        let ulObj   = document.getElementById('messageList');

        const ws = new WebSocket("ws://localhost:8888");

        ws.onopen = function(event) {
        }


        ws.onmessage = function(event) {
            let msg = event.data;
            let newLi = document.createElement('li');
            newLi.textContent = msg;
            ulObj.appendChild(newLi);

            console.log(msg);
        }

        sendObj.addEventListener('click', function() {
            if (msgObj.value) {
                // 发送消息至服务器
                ws.send(msgObj.value);
                // 清空输入框
                msgObj.value = '';
            } else {
                alert('请输入要发送的消息!');
            }
        });
    </script>
</body>
</html>

现在,打开浏览器测试一下吧。

把服务写在 WorkermanHttpServer 中有点臃肿,那么,可以使用 PSR 把服务单独存放到一个文件中,如 app/Workerman,我这里就不演示了。

请登录后再评论