4、Workerman 基本使用 - Workerman 异步连接代理

作者: 温新

图书: 【Workerman 基本使用】

阅读: 233

时间: 2024-05-19 19:25:49

hi,我是温新,一名 PHPer

AsyncTcpConnection 是 TcpConnection的子类,拥有与TcpConnection一样的属性与接口。AsyncTcpConnection 用于异步创建一个 TcpConnection 连接。

异步 TCP

以下案例是异步代理访问 MySQL

<?php
/**
 * conn-async-proxy.php
 *
 * 异步代理
 */
require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;
use Workerman\Connection\AsyncTcpConnection;
use Workerman\Connection\TcpConnection;

// 创建一个代理 Worker,监听本地 8888 端口,用于接收客户端连接请求
$proxy = new Worker('tcp://0.0.0.0:8888');

// 当有客户端连接到代理时触发 onConnect 回调函数
$proxy->onConnect = function (TcpConnection $connection) {
    // 假设tcp://127.0.0.1:3306是真实的MySQL数据库服务地址
    // 创建一个新的异步TCP连接,尝试与MySQL服务建立连接
    $connectionMySQL = new AsyncTcpConnection('tcp://127.0.0.1:3306');

    // 当从 MySQL 服务接收到数据时,转发给发起请求的客户端连接
    $connectionMySQL->onMessage = function (AsyncTcpConnection $connectionMySQL, $data) use ($connection) {
        $connection->send($data);
    };

    // 当 MySQL 服务连接关闭时,也关闭与该请求对应的客户端代理连接
    $connectionMySQL->onClose = function () use ($connection) {
        $connection->close();
    };

    // 若 MySQL 服务连接出现错误,同样关闭与之关联的客户端代理连接
    $connectionMySQL->onError = function () use ($connection) {
        $connection->close();
    };

    // 尝试与 MySQL 服务建立连接
    $connectionMySQL->connect();

    // 当客户端通过代理发送消息(向 MySQL 服务发送查询等操作)时触发此回调
    $connection->onMessage = function (TcpConnection $connection, $data) use ($connectionMySQL) {
        // 将客户端发送的数据转发给 MySQL 服务
        $connectionMySQL->send($data);
    };

    // 当客户端断开连接时,同时关闭与 MySQL 服务的连接
    $connection->onClose = function () use ($connectionMySQL) {
        $connectionMySQL->close();
    };

    // 当客户端连接发生错误时,关闭与 MySQL 服务的连接
    $connection->onError = function () use ($connectionMySQL) {
        $connectionMySQL->close();
    };
};

Worker::runAll();

服务启动后连接测试

$ mysql -utest -P8888 -h127.0.0.1 -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.30 Source distribution

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

注意:

  • AsyncTcpConnection 目前只支持 tcp、ssl、ws、frame、text 协议。

当启用一个异步连接时,需要执行 connect 方法启动执行异步连接操作。

异步 UDP

<?php
/**
 * conn-async-udp.php
 *
 * 异步 UDP 连接
 */

use Workerman\Worker;
use Workerman\Connection\AsyncUdpConnection;
use Workerman\Connection\UdpConnection;
use Workerman\Timer;


require_once __DIR__ . '/vendor/autoload.php';


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

// 当 Worker 启动时触发此回调函数
$worker->onWorkerStart = function () {
    // 定时器,3 秒后客户端发送数据
    Timer::add(3, function () {
        // 创建一个新的异步 UDP 客户端连接实例,指向本地 127.0.0.1:8888 端口(这里实际上是向自己发送)
        $udpConnection = new AsyncUdpConnection('udp://127.0.0.1:8888');
        // 设置当客户端与服务端建立连接后触发的回调函数
        $udpConnection->onConnect = function (AsyncUdpConnection $udpConnection) {
            // 客户端发向服务端发送数据
            $udpConnection->send('hi, i am client');
        };

        // 设置接收到服务端响应时触发的回调函数
        $udpConnection->onMessage = function (AsyncUdpConnection $udpConnection, $data) {
            echo "收到服务端数据:" . $data . PHP_EOL;
            $udpConnection->close();
        };
        $udpConnection->connect();
    }, null, false);
};

// 当 Worker 收到 UDP 消息时触发的回调函数
$worker->onMessage = function (UdpConnection $connection, $data) {
    echo '客户端数据:' . $data . PHP_EOL;
    $connection->send('hello client');
};

Worker::runAll();;

测试

$ php conn-async-udp.php start
Workerman[conn-async-udp.php] 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           
udp     codeing         none            udp://0.0.0.0:8888    1             [OK]            
-------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
客户端数据:hi, i am client
收到服务端数据:hello client
^CWorkerman[conn-async-udp.php] stopping ...
Workerman[conn-async-udp.php] has been stopped

AsyncUdpConnectionAsyncTcpConnection 有所不同,它有许多不支持的属性与方法,详情请看文档。

请登录后再评论