您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
workerman接口listen接合reusePort实现端口复用多实例共用端口
发布时间:2021-12-02 22:43:34编辑:雪饮阅读()
listen
void Worker::listen(void)
用于实例化Worker后执行监听。
此方法主要用于在Worker进程启动后动态创建新的Worker实例,能够实现同一个进程监听多个端口,支持多种协议。需要注意的是用这种方法只是在当前进程增加监听,并不会动态创建新的进程,也不会触发onWorkerStart方法。
例如一个http Worker启动后实例化一个websocket Worker,那么这个进程即能通过http协议访问,又能通过websocket协议访问。由于websocket Worker和http Worker在同一个进程中,所以它们可以访问共同的内存变量,共享所有socket连接。可以做到接收http请求,然后操作websocket客户端完成向客户端推送数据类似的效果。
注意:
如果PHP版本<=7.0,则不支持在多个子进程中实例化相同端口的Worker。例如A进程创建了监听2016端口的Worker,那么B进程就不能再创建监听2016端口的Worker,否则会报Address already in use错误。例如下面的代码是无法运行的。
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker();
// 4个进程
$worker->count = 4;
// 每个进程启动后在当前进程新增一个Worker监听
$worker->onWorkerStart = function($worker)
{
/**
* 4个进程启动的时候都创建2016端口的Worker
* 当执行到worker->listen()时会报Address already in use错误
* 如果worker->count=1则不会报错
*/
$inner_worker = new Worker('http://0.0.0.0:2016');
$inner_worker->onMessage = 'on_message';
// 执行监听。这里会报Address already in use错误
$inner_worker->listen();
};
$worker->onMessage = 'on_message';
function on_message(TcpConnection $connection, $data)
{
$connection->send("hello\n");
}
// 运行worker
Worker::runAll();
上面这些我没有测试,因为我的php版本是7.0.33,大于上面提到的这个版本。
如果您的PHP版本>=7.0,可以设置Worker->reusePort=true, 这样可以做到多个子进程创建相同端口的Worker。见下面的例子:
实例test.php:
<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('text://0.0.0.0:2015');
// 4个进程
$worker->count = 4;
// 每个进程启动后在当前进程新增一个Worker监听
$worker->onWorkerStart = function($worker)
{
$inner_worker = new Worker('http://0.0.0.0:2016');
// 设置端口复用,可以创建监听相同端口的Worker(需要PHP>=7.0)
$inner_worker->reusePort = true;
$inner_worker->onMessage = 'on_message';
// 执行监听。正常监听不会报错
$inner_worker->listen();
};
$worker->onMessage = 'on_message';
function on_message(TcpConnection $connection, $data)
{
$connection->send("hello\n");
}
// 运行worker
Worker::runAll();
?>
服务端部署运行:
[root@izj6c2jeancylo0ppo4vz5z workerman]# php test.php start
Workerman[test.php] start in DEBUG mode
----------------------------------------- WORKERMAN -----------------------------------------
Workerman version:4.0.22 PHP version:7.0.33
------------------------------------------ WORKERS ------------------------------------------
proto user worker listen processes status
tcp root none text://0.0.0.0:2015 4 [OK]
---------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
从实例中可以看到理论应该会有4个进程都是2016端口,理论来说应该会报端口占用错误。但这里因为使用了端口复用reusePort为true,所以不会报端口占用的相关错误。
然后客户端请求也是正常的。
[root@izj6c2jeancylo0ppo4vz5z workerman]# elinks http://127.0.0.1:2016 -dump
hello
关键字词:workerman,listen,reusePort
相关文章
- workerman接口runAll运行多个不同woker实例(不同协议)
- workerman接口stopAll及多线程请求测试
- workerman利用Timer库的persistent属性实现仅定时执行
- workerman利用daemonize属性实现代码层控制进程启动方
- workerman利用reloadable属性实现新增业务代码载入并
- workerman属性stdoutFile(输出重定向)及daemonize实现脚
- workerman利用属性user实现指定用户运行进程
- workerman利用属性pidFile自定义进程pid文件
- workerman利用属性connections遍历向客户端定时发消息
- workerman利用logFile属性指定自身运行日志存储路径(不