workerman-todpole 执行流程(3)

Posted on   jiaoqing。  阅读(259)  评论(0编辑  收藏  举报

通过前两篇文章的分析:

我们已经详细了解了主进程以及子进程的启动细节,但之前的文章并没有考虑 Worker 各个子类其实重写了部分方法,这篇文章将逐一分析下它们的启动流程。

Gateway

首先,我们比较关心的是子进程使用的 run() 方法的重写情况:

public function run()
{
// 保存用户的回调,当对应的事件发生时触发
$this->_onWorkerStart = $this->onWorkerStart;
$this->onWorkerStart = array($this, 'onWorkerStart');
// 保存用户的回调,当对应的事件发生时触发
$this->_onConnect = $this->onConnect;
$this->onConnect = array($this, 'onClientConnect');
 
// onMessage禁止用户设置回调
$this->onMessage = array($this, 'onClientMessage');
 
// 保存用户的回调,当对应的事件发生时触发
$this->_onClose = $this->onClose;
$this->onClose = array($this, 'onClientClose');
// 保存用户的回调,当对应的事件发生时触发
$this->_onWorkerStop = $this->onWorkerStop;
$this->onWorkerStop = array($this, 'onWorkerStop');
 
// 记录进程启动的时间
$this->_startTime = time();
// 运行父方法
parent::run();
}

该方法在调用父方法之前初始化了一些回调。

onWorkerStart()

该回调是在 run() 最后一步开启 event-loop 之前触发的。

public function onWorkerStart()
{
// 1、分配一个内部通讯端口
$this->lanPort = $this->startPort + $this->id;
 
// 2、如果有设置心跳,则定时执行
if ($this->pingInterval > 0) {
$timer_interval = $this->pingNotResponseLimit > 0 ? $this->pingInterval / 2 : $this->pingInterval;
Timer::add($timer_interval, array($this, 'ping'));
}
 
// 3、如果BusinessWorker ip不是127.0.0.1,则需要加gateway到BusinessWorker的心跳
if ($this->lanIp !== '127.0.0.1') {
Timer::add(self::PERSISTENCE_CONNECTION_PING_INTERVAL, array($this, 'pingBusinessWorker'));
}
 
// 4、如果 Register 服务器不在本地服务器,则需要保持心跳
if (strpos($this->registerAddress, '127.0.0.1') !== 0) {
Timer::add(self::PERSISTENCE_CONNECTION_PING_INTERVAL, array($this, 'pingRegister'));
}
 
if (!class_exists('\Protocols\GatewayProtocol')) {
class_alias('GatewayWorker\Protocols\GatewayProtocol', 'Protocols\GatewayProtocol');
}
 
// 5、初始化 gateway 内部的监听,用于监听 worker 的连接已经连接上发来的数据
$this->_innerTcpWorker = new Worker("GatewayProtocol://{$this->lanIp}:{$this->lanPort}");
$this->_innerTcpWorker->listen();
 
// 6、重新设置自动加载根目录
Autoloader::setRootPath($this->_autoloadRootPath);
 
// 7、设置内部监听的相关回调
$this->_innerTcpWorker->onMessage = array($this, 'onWorkerMessage');
$this->_innerTcpWorker->onConnect = array($this, 'onWorkerConnect');
$this->_innerTcpWorker->onClose = array($this, 'onWorkerClose');
 
// 8、注册 gateway 的内部通讯地址,worker 去连这个地址,以便 gateway 与 worker 之间建立起 TCP 长连接
$this->registerAddress();
if ($this->_onWorkerStart) {
call_user_func($this->_onWorkerStart, $this);
}
}

关于 Timer::add() 这里就不展开分析了,其实是通过 alarm 闹钟信号循环触发来实现定时执行的;注释 3/4 在分布式部署时使用,此时 Gateway 和 BusinessWorker/Register 不是同一台机器,所以需要心跳来保持连接。

编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~

随笔 - 287, 文章 - 0, 评论 - 3, 阅读 - 42万

Copyright © 2025 jiaoqing。
Powered by .NET 9.0 on Kubernetes

点击右上角即可分享
微信分享提示