sylar源码解析---RPC框架之模块化分发机制

模块化分发机制

在文章 "sylar源码解析------RPC模块之Rock协议" 的最后,我们分析了 RockServer::handleClient 的核心逻辑。在这部分代码中,Sylar 并未直接将请求分发给固定的处理函数,而是通过模块化机制实现了灵活可扩展的 RPC 分发框架。具体而言,当有客户端连接建立、断开或发送请求、通知时,RockServer 会借助 ModuleManager 遍历当前系统中注册的所有 ROCK 类型模块,并依次调用它们的回调函数(如 onConnecthandleRequest 等)。这种"模块驱动式"的设计,使得 RPC 服务的扩展和接入不再依赖服务器核心逻辑,而是通过注册模块插件即可实现业务隔离、协议抽象与运行时热插拔。

因此,接下来我们将深入分析 Sylar 的模块化机制,重点理解 ModuleModuleManagerRockModule 以及其与 RockServer 的协作关系,进而揭示整个 RPC 系统的可插拔服务治理架构是如何实现的。

cpp 复制代码
void RockServer::handleClient(Socket::ptr client) {
    SYLAR_LOG_DEBUG(g_logger) << "handleClient " << *client;
    sylar::RockSession::ptr session(new sylar::RockSession(client));
    session->setWorker(m_worker);
    // 通知所有 ROCK 类型模块有连接建立
    ModuleMgr::GetInstance()->foreach(Module::ROCK,
        [session](Module::ptr m) {
            m->onConnect(session);
    });
    // 设置连接断开时的回调
    session->setDisconnectCb([](AsyncSocketStream::ptr stream) {
        ModuleMgr::GetInstance()->foreach(Module::ROCK,
        [stream](Module::ptr m) {
                m->onDisconnect(stream);
            })
            });
    // 设置请求处理函数
    // 当客户端发来一个 RockRequest(ROCK协议的请求包)时,调用这个 lambda。
    // 遍历所有注册的 ROCK 模块:
    // 调用每个模块的 handleRequest() 来处理请求。
    // 如果有一个模块返回了 true(表示处理了该请求),就不再继续调用其他模块(短路逻辑)。
    session->setRequestHandler([](sylar::RockRequest::ptr req, sylar::RockResponse::ptr rsp, sylar::RockStream::ptr conn)->bool {
            bool rt = false;
            ModuleMgr::GetInstance()->forearch(Module::ROCK, [&rt, req, rsp, conn](Module::ptr m) {
                if (rt) {
                    return;
                }
                rt = m->handleRequest(req, rsp, conn);
                });
            return rt;
        })
    // 设置通知处理函数
    session->setNotifyHandler([](sylar::RockNotify::ptr nty, sylar::RockStream::ptr conn)->bool {
        SYLAR_LOG_INFO(g_logger) << "handleNty " << nty->toString()
            << " body=" << nty->getBody();
        bool rt = false;
        ModuleMgr::GetInstance()->foreach(Module:; ROCK, [&rt, nty, conn](Module::ptr m) {
            if (rt) return;
            rt = m->handleNotify(nty, conn);});
        return rt;
    }
    );
    // 启动会话,开始异步读写
    // 会在设置的m_worker中持续进行
    session->start();
}

library.h

核心类

Library

该类是是 Sylar 框架中专门用于动态加载模块(Module)插件的核心工具类,它通过封装 dlopen / dlsym 等系统调用机制,实现了对 .so 动态库的加载、模块对象的创建以及资源的自动释放管理。在模块化架构中,每一个模块都被构建为独立的共享库文件,Library::GetModule(path) 会在运行时打开该 .so 文件,提取出符合约定的 CreateModule()DestoryModule() 函数,并以智能指针封装返回模块实例。这使得模块可以按需加载、热插拔部署、与主程序解耦,是 Sylar 实现模块化治理、插件式扩展的关键支撑组件。

仿函数ModuleCloser

用于在智能指针释放 Module* 时执行自定义清理逻辑。

cpp 复制代码
typedef void (*destory_module)(Module*);

class ModuleCloser {
public:
	ModuleCloser(void* handle, destory_module d)
		: m_handle(handle), m_destory(d) {
	}

	// 重载()运算符  仿函数
	void operator()(Module* module) {
		// 当 std::shared_ptr<Module> 被销毁时会调用这个 operator() 来做清理工作。
		std::string name = module->getName();
		std::string version = module->getVersion();
		std::string path = module->getFilename();
		m_destory(module);
		int rt = dlclose(m_handle);
		if (rt) {
			SYLAR_LOG_ERROR(g_logger) << "dlclose handle fail handle="
				<< m_handle << " name=" << name
				<< " version=" << version
				<< " path=" << path
				<< " error=" << dlerror();
		}
		else {
			SYLAR_LOG_INFO(g_logger) << "destory module=" << name
				<< " version=" << version
				<< " path=" << path
				<< " handle=" << m_handle
				<< " success";
		}
	}

private:
	// 动态库句柄(由dlopen返回)
	void* m_handle;
	// Module的销毁函数
	destory_module m_destory;
};

GetModule()

从指定路径加载一个动态模块(.so共享库),并返回其对应的 Module 对象智能指针。

注意:

在 Sylar 框架中,每个模块(.so 文件)必须按照统一的接口格式实现下面两个函数:

extern "C" sylar::Module* CreateModule(); 用于创建Module对象

extern "C" void DestoryModule(sylar::Module* m); 用于销毁Module对象

cpp 复制代码
typedef Module* (create_module)();
typedef void (*destory_module)(Module*);

Module::ptr Library::GetModule(const std::string& path) {
	// RTLD_NOW 表示立即解析出所有符号(函数、变量),不延迟
	void* handle = dlopen(path.c_str(), RTLD_NOW);
	if (!handle) {
		SYLAR_LOG_ERROR(g_logger) << "cannot load library path="
			<< path << " error=" << dlerror();
		return nullptr;
	}
	// 从共享库中获取函数指针CreateModule
	create_module create = (create_module)dlsym(handle, "CreateModule");
	if (!create) {
		SYLAR_LOG_ERROR(g_logger) << "cannot load symbol CreateModule in "
			<< path << " error=" << dlerror();
		dlclose(handle);
		return nullptr;
	}
	// 从共享库中获取销毁函数
	destory_module destory = (destory_module)dlsym(handle, "DestoryModule");
	if (!destory) {
		SYLAR_LOG_ERROR(g_logger) << "cannot load symbol DestoryModule in "
			<< path << " error=" << dlerror();
		dlclose(handle);
		return nullptr;
	}
	Module::ptr module(create(), ModuleCloser(handle, destory));
	module->setFilename(path);
	SYLAR_LOG_INFO(g_logger) << "load module name=" << module->getName()
		<< " version=" << module->getVersion()
		<< " path=" << module->getFilename()
		<< " success";
	// 重新加载配置目录
	//强制重新加载配置目录(. / conf 或用户通过 - c 参数指定的路径)。
	//	原因:
	//	加载模块后,模块可能会注册新的配置项;
	//	因此需要重新读取.yml 文件,以确保新模块的配置生效。
	Config::LoadFromConfDir(sylar::EnvMgr::GetInstance()->getConfigPath(), true);
	// 该module已经具备自动销毁和资源释放的机制
	return module;
}

module.h

核心类

Module

该类是 Sylar 框架里用来管理各个功能模块的基础类,它统一了模块的加载、卸载、连接管理和请求处理接口。它既能支持普通模块,也能专门用来做基于 Rock 协议的 RPC 模块,是实现模块化和插件化的基础。

枚举Type

用来区分模块的类型

cpp 复制代码
enum Type {
	MODULE = 0,    // 通用模块
	ROCK = 1,      // 支持ROCK协议的模块
};

成员变量

cpp 复制代码
std::string m_name;      // 模块名称
std::string m_version;   // 模块版本
std::string m_filename;  // 模块对应的.so文件路径
std::string m_id;        // 模块唯一id
uint32_t m_type;         // 模块类型(MODULE/ROCK)

成员函数

cpp 复制代码
/**
    * @brief 参数解析前的钩子函数
    * @param argc 命令行参数个数
    * @param argv 命令行参数数组
    *
    * 可以在这里做参数检查、预处理等操作
    */
virtual void onBeforeArgsParse(int argc, char** argv);

/**
* @brief 参数解析后的钩子函数
* @param argc 命令行参数个数
* @param argv 命令行参数数组
*
* 可以在这里做参数确认、日志初始化等操作
*/
virtual void onAfterArgsParse(int argc, char** argv);

// 模块加载时的回调函数,返回是否加载成功
virtual bool onLoad();

// 模块卸载时的回调函数,返回是否卸载成功
virtual bool onUnload();

/**
    * @brief 有新连接时的回调函数(适用于 ROCK 模块)
    * @param stream 与客户端的连接对象
    * @return 是否处理成功
    */
virtual bool onConnect(sylar::Stream::ptr stream);

/**
    * @brief 连接断开时的回调函数(适用于 ROCK 模块)
    * @param stream 与客户端的连接对象
    * @return 是否处理成功
    */
virtual bool onDisconnect(sylar::Stream::ptr stream);

/**
    * @brief 服务器初始化完成(即将启动)时的回调函数
    * @return 是否启动准备成功
    */
virtual bool onServerReady();

/**
    * @brief 服务器已经完全启动时的回调函数
    * @return 是否启动成功
    */
virtual bool onServerUp();

/**
    * @brief 处理请求消息(适用于 ROCK 模块)
    * @param req 请求消息对象
    * @param rsp 响应消息对象
    * @param stream 与客户端的连接对象
    * @return 是否处理成功
    */
virtual bool handleRequest(sylar::Message::ptr req,
                            sylar::Message::ptr rsp,
                            sylar::Stream::ptr stream);

/**
    * @brief 处理通知消息(适用于 ROCK 模块)
    * @param notify 通知消息对象
    * @param stream 与客户端的连接对象
    * @return 是否处理成功
    */
virtual bool handleNotify(sylar::Message::ptr notify,
    sylar::Stream::ptr stream);

registerService()

注册服务信息(通常用于服务发现),向服务发现中心(如 ZooKeeper)注册服务节点。

这个模块对外提供服务,外部访问时是通过模块底层服务器监听的IP和端口来连接的。因此,我们需要把模块底层监听的IP和端口信息,连同我们自己传入的域名和服务名称,一起注册到服务发现模块里。这里传入的域名和服务名称,就是用来标识这个模块底层服务器具体提供了什么服务。通过这种注册,外部才能找到并访问到这个模块对应的服务。

cpp 复制代码
void Module::registerService(const std::string& server_type,
            const std::string& domain, const std::string& service) {
    // 获取当前应用中的服务发现模块ServiceDiscovery实例
    auto sd = Application::GetInstance()->getServiceDiscovery();
    if (!sd) return;

    std::vector<TcpServer::ptr> svrs;
    // 获取指定类型(如 "http")的所有 TcpServer 对象。
    if (!Application::GetInstance()->getServer(server_type, svrs)) {
        return;
    }
    // 遍历所有同类型的服务器(一个类型可能启动了多个端口或监听多个地址)。
    // 一个 TcpServer 通常会有多个 socket,是因为它可能监听多个地址(IP 或端口),而不是因为有多个客户端连接。
    for (auto& i : svrs) {
        auto socks = i->getSocks();
        for (auto& s : socks) {
            // 拿到它的监听地址(服务器端)。
            auto addr = std::dynamic_pointer_cast<IPv4Address>(s->getLocalAddress());
            if (!addr) {
                continue;
            }
            auto str = addr->toString();
            if (str.find("127.0.0.1") == 0) {
                // 如果地址是 127.0.0.1,即本地环回地址,不注册(其他服务访问不到它)。
                continue;
            }
            std::string ip_and_port;
            if (str.find("0.0.0.0") == 0) {
                // 如果监听地址是 0.0.0.0(即监听所有 IP),那就用本机外网 IP 替代 0.0.0.0。
                // 不能直接注册 0.0.0.0:8080,服务消费者无法使用这个地址。必须转换为真实 IP
                ip_and_port = sylar::GetIPv4() + ":" + std::string(addr->getPort());
            } else {
                ip_and_port = addr->toString();
            }
            sd->registerServer(domain, service, ip_and_port, server_type);
        }
    }
}
RockModule

该类是对 Module 基类的扩展,专门用于处理基于 Rock 协议的通信模块。它在 Module 的基础上,新增了处理 Rock 协议请求和通知消息的纯虚函数,使得继承它的模块必须实现具体的请求和通知处理逻辑。同时,它重载了基类的通用请求和通知处理接口,将底层的 Message 类型消息转换为 Rock 协议的具体请求或通知对象,并调用对应的处理函数,从而实现了对 Rock 协议消息的专门分发和处理。

cpp 复制代码
// 处理 Rock 协议的请求消息
virtual bool handleRockRequest(sylar::RockRequest::ptr request,
                                sylar::RockResponse::ptr response,
                                sylar::RockStream::ptr stream) = 0;
// 处理 Rock 协议的通知消息
virtual bool handleRockNotify(sylar::RockNotify::ptr notify,
                                sylar::RockStream::ptr stream) = 0;    

// 重载基类 Module 的 handleRequest
// 将 Message 转换为 RockRequest/RockResponse 并分发给 handleRockRequest
virtual bool handleRequest(sylar::Message::ptr req,
                            sylar::Message::ptr rsp,
                            sylar::Stream::ptr stream) override;

// 重载基类 Module 的 handleNotify
// 将 Message 转换为 RockNotify 并分发给 handleRockNotify
virtual bool handleNotify(sylar::Message::ptr notify,
                            sylar::Stream::ptr stream) override;

bool RockModule::handleRequest(sylar::Message::ptr req
                               ,sylar::Message::ptr rsp
                               ,sylar::Stream::ptr stream) {
    auto rock_req = std::dynamic_pointer_cast<sylar::RockRequest>(req);                            
    auto rock_rsp = std::dynamic_pointer_cast<sylar::RockResponse>(rsp);                            
    auto rock_stream = std::dynamic_pointer_cast<sylar::RockStream>(stream);                            
    return handleRockRequest(rock_req, rock_rsp, rock_stream);                            
}

bool RockModule::handleNotify(sylar::Message::ptr notify
                              ,sylar::Stream::ptr stream) {
    auto rock_nty = std::dynamic_pointer_cast<sylar::RockNotify>(notify);
    auto rock_stream = std::dynamic_pointer_cast<sylar::RockStream>(stream);
    return handleRockNotify(rock_nty, rock_stream);
}
ModuleManage

该类是 Sylar 框架中用于统一管理系统模块的核心类,它负责对所有模块(Module 实例)进行注册、注销、查找、分类和遍历等操作。该类支持通过模块名称或模块类型(如 MODULEROCK)进行访问,同时在连接建立或断开等关键时机,自动调用各个模块的相关钩子函数(如 onConnectonDisconnect),从而实现模块间的事件驱动协作。

成员变量

cpp 复制代码
// 模块名 -> 模块对象的映射表。
std::unordered_map<std::string, Module::ptr> m_modules;
// 按模块类型分类的模块映射:
// 第一层 key 是模块类型(如 MODULE = 0, ROCK = 1)
// 第二层 key 是模块名,value 是模块对象
std::unordered_map<uint32_t, std::unordered_map<std::string, Module::ptr>> m_type2Modules;]

成员函数

对内部维护的Module集合进行增删改查操作

cpp 复制代码
Module::ptr ModuleManager::get(const std::string& name) {
    RWMutexType::ReadLock lock(m_mutex);
    auto it = m_modules.find(name);
    return it == m_modules.end() ? nullptr : it->second;
}

void ModuleManager::add(Module::ptr m) {
    del(m->getId());
    RWMutexType::WriteLock lock(m_mutex);
    m_modules[m->getId()] = m;
    m_type2Modules[m->getType()][m->getId()] = m;
}

void ModuleManager::del(const std::string& name) {
    Module::ptr module;
    RWMutexType::WriteLock lock(m_mutex);
    auto it = m_modules.find(name);
    if (it == m_modules.end()) {
        return;
    }
    module = it->second;
    m_module.erase(it);
    m_type2Modules[module->getType()].erase(module->getId());
    if (m_type2Modules[module->getType()].empty()) {
        m_type2Modules.erase(module->getType());
    }
    lock.unlock();
    module->onUnload();
}

void ModuleManager::delAll() {
    RWMutexType::ReadLock lock(m_mutex);
    auto tmp = m_modules;
    lock.unlock();

    for(auto& i : tmp) {
        del(i.first);
    }
}

void ModuleManager::listAll(std::vector<Module::ptr>& ms) {
    RWMutexType::ReadLock lock(m_mutex);
    for(auto& i : m_modules) {
        ms.push_back(i.second);
    }
}

void ModuleManager::listByType(uint32_t type, std::vector<Module::ptr>& ms) {
    RWMutexType::ReadLock lock(m_mutex);
    auto it = m_type2Modules.find(type);
    if(it == m_type2Modules.end()) {
        return;
    }
    for(auto& i : it->second) {
        ms.push_back(i.second);
    }
}

init()/initModule()

从指定的模块目录中加载所有 .so 动态库文件,并将其中定义的模块注册到系统中。init() 函数会先获取模块目录路径,然后扫描该目录下所有以 .so 结尾的文件,并对其排序后逐个调用 initModule() 进行加载。initModule() 则使用 Library::GetModule() 动态加载模块对象,如果加载成功就调用 add() 方法将其添加到模块管理器中,从而完成模块的注册与统一管理。

cpp 复制代码
void ModuleManager::init() {
    auto path = EnvMgr::GetInstance()->getAbsolutePath(g_module_path->getValue());
    
    std::vector<std::string> files;
    sylar::FSUtil::ListAllFile(files, path, ".so");

    std::sort(files.begin(), files.end());
    for(auto& i : files) {
        initModule(i);
    }
}

void ModuleManager::initModule(const std::string& path) {
    Module::ptr m = Library::GetModule(path);
    if(m) {
        add(m);
    }
}

foreach()

对指定类型模块的统一遍历操作,接收一个模块类型(如 Module::ROCK)和一个回调函数 cb,首先通过 listByType 获取该类型下的所有模块列表,然后逐个调用回调函数 cb(i) 对每个模块执行指定逻辑。

cpp 复制代码
void ModuleManager::foreach(uint32_t type, std::function<void(Module::ptr)> cb) {
    std::vector<Module::ptr> ms;
    listByType(type, ms);
    for(auto& i : ms) {
        cb(i);
    }
}

onConnect()/onDisconnect()

这两个函数用于在连接建立或断开时,统一通知系统中所有已加载的模块。
onConnect 会遍历所有模块,并调用它们的 onConnect 方法,传入新建立的 stream 连接对象;
onDisconnect 则在连接断开时进行同样的处理,调用模块的 onDisconnect 方法。

cpp 复制代码
void ModuleManager::onConnect(Stream::ptr stream) {
    std::vector<Module::ptr> ms;
    listAll(ms);

    for(auto& m : ms) {
        m->onConnect(stream);
    }
}

void ModuleManager::onDisconnect(Stream::ptr stream) {
    std::vector<Module::ptr> ms;
    listAll(ms);

    for(auto& m : ms) {
        m->onDisconnect(stream);
    }
}

在前文我们梳理了 Sylar 框架中模块化机制的核心组成部分,包括 ModuleRockModuleModuleManagerLibrary 等关键类及其职责和交互方式。每一个模块都可以被动态加载为 .so 文件,并注册到 ModuleManager 中进行统一管理。当有连接建立、断开或收到请求/通知时,ModuleManager 会统一分发事件到所有相关模块中,从而实现模块驱动式的运行时可插拔服务治理架构。

接下来我们结合上面分析的机制,继续解读 RockServer::handleClient() 这一函数的核心逻辑,看看模块系统如何真正参与 RockServer 的请求分发和连接管理过程:

cpp 复制代码
void RockServer::handleClient(Socket::ptr client) {
    SYLAR_LOG_DEBUG(g_logger) << "handleClient " << *client;
    sylar::RockSession::ptr session(new sylar::RockSession(client));
    session->setWorker(m_worker);
    // 通知所有 ROCK 类型模块有连接建立
    ModuleMgr::GetInstance()->foreach(Module::ROCK,
        [session](Module::ptr m) {
            m->onConnect(session);
    });
    // 设置连接断开时的回调
    session->setDisconnectCb([](AsyncSocketStream::ptr stream) {
        ModuleMgr::GetInstance()->foreach(Module::ROCK,
        [stream](Module::ptr m) {
                m->onDisconnect(stream);
            })
            });
    // 设置请求处理函数
    // 当客户端发来一个 RockRequest(ROCK协议的请求包)时,调用这个 lambda。
    // 遍历所有注册的 ROCK 模块:
    // 调用每个模块的 handleRequest() 来处理请求。
    // 如果有一个模块返回了 true(表示处理了该请求),就不再继续调用其他模块(短路逻辑)。
    session->setRequestHandler([](sylar::RockRequest::ptr req, sylar::RockResponse::ptr rsp, sylar::RockStream::ptr conn)->bool {
            bool rt = false;
            ModuleMgr::GetInstance()->forearch(Module::ROCK, [&rt, req, rsp, conn](Module::ptr m) {
                if (rt) {
                    return;
                }
                rt = m->handleRequest(req, rsp, conn);
                });
            return rt;
        })
    // 设置通知处理函数
    session->setNotifyHandler([](sylar::RockNotify::ptr nty, sylar::RockStream::ptr conn)->bool {
        SYLAR_LOG_INFO(g_logger) << "handleNty " << nty->toString()
            << " body=" << nty->getBody();
        bool rt = false;
        ModuleMgr::GetInstance()->foreach(Module:; ROCK, [&rt, nty, conn](Module::ptr m) {
            if (rt) return;
            rt = m->handleNotify(nty, conn);});
        return rt;
    }
    );
    // 启动会话,开始异步读写
    // 会在设置的m_worker中持续进行
    session->start();
}

该函数是 RockServer 在接收到客户端连接时负责处理的回调入口,它的整体流程如下:

1.建会话并绑定 worker

这段代码会将当前客户端连接包装成一个 RockSession,并绑定到指定的 IO 协程调度器 m_worker 上,后续该会话的读写处理都会交给这个线程池去调度执行。

cpp 复制代码
sylar::RockSession::ptr session(new sylar::RockSession(client));
session->setWorker(m_worker);

2.通知所有 ROCK 模块:有新连接建立

在连接刚建立后,系统会遍历所有已注册的 ROCK 类型模块 (即继承了 RockModule 的模块),并调用它们的 onConnect() 方法,将当前 session 传入。模块可以借此机会进行一些会话级初始化操作,比如绑定用户上下文、创建会话状态、打印日志等。

这正体现了模块驱动式的设计思想:服务模块自己定义连接建立后的行为,而不是写死在服务器逻辑里。

cpp 复制代码
ModuleMgr::GetInstance()->foreach(Module::ROCK, [session](Module::ptr m) {
    m->onConnect(session);
});

3.设置连接断开时的回调

当该连接断开时,会调用 setDisconnectCb() 设置的 lambda,系统同样会遍历所有 ROCK 模块,并依次调用它们的 onDisconnect() 方法。模块可以在此处进行资源回收、状态清理、断连通知等逻辑处理。

cpp 复制代码
session->setDisconnectCb([](AsyncSocketStream::ptr stream) {
    ModuleMgr::GetInstance()->foreach(Module::ROCK, [stream](Module::ptr m) {
        m->onDisconnect(stream);
    });
});

4.设置请求处理函数(handleRequest)

这是处理客户端 Rock 请求的核心逻辑:

  • 客户端发送过来的 RockRequest 会被解析并传入这个 lambda。

  • 然后,系统遍历所有 ROCK 类型模块,依次调用每个模块的 handleRequest() 方法。

  • 如果某个模块返回了 true,代表该请求已成功处理,后续模块就不再继续处理(即 短路机制)。

这种方式允许多个模块响应不同类型的业务请求,而不需要改动核心服务器代码,极大增强了系统的扩展性和可插拔性。

cpp 复制代码
session->setRequestHandler([](sylar::RockRequest::ptr req,
                              sylar::RockResponse::ptr rsp,
                              sylar::RockStream::ptr conn) -> bool {
    bool rt = false;
    ModuleMgr::GetInstance()->foreach(Module::ROCK, [&rt, req, rsp, conn](Module::ptr m) {
        if (rt) return;
        rt = m->handleRequest(req, rsp, conn);
    });
    return rt;
});

5.设置通知处理函数(handleNotify)

同理,对于 Rock 协议中的通知类型(RockNotify),也通过遍历模块的方式分发处理。每个模块可以根据 notify 消息内容决定是否处理;一旦某个模块处理了,就停止继续分发。

cpp 复制代码
session->setNotifyHandler([](sylar::RockNotify::ptr nty,
                             sylar::RockStream::ptr conn) -> bool {
    bool rt = false;
    ModuleMgr::GetInstance()->foreach(Module::ROCK, [&rt, nty, conn](Module::ptr m) {
        if (rt) return;
        rt = m->handleNotify(nty, conn);
    });
    return rt;
});

6.启动异步会话

调用 start() 开启这个 RockSession,进入真正的异步事件处理流程。它会持续监听 socket 上的数据,并根据收到的请求/通知分发给上面注册的处理函数(即模块逻辑)。

cpp 复制代码
session->start();

至此,sylar RPC框架的"模块驱动式 RPC 分发机制"介绍完毕。

更详细的sylar注释:jinkezhen/sylar: for self study

相关推荐
molvqingtai13 小时前
Comctx:比 Comlink 更好的跨上下文通信库
前端·javascript·rpc
麻辣长颈鹿Sir15 小时前
【C++】使用箱线图算法剔除数据样本中的异常值
算法·信息可视化·数据分析·c/c++·数据处理
weixin_524749963 天前
RPC(Remote Procedure Call,远程过程调用)介绍
网络·网络协议·rpc
武子康3 天前
Java-78 深入浅出 RPC Dubbo 负载均衡全解析:策略、配置与自定义实现实战
java·数据库·分布式·后端·缓存·rpc·dubbo
笑衬人心。3 天前
RPC 与 Feign 的区别笔记
笔记·网络协议·rpc
zaiyang遇见4 天前
牛客NC14661 简单的数据结构(deque双端队列)
数据结构·stl·双端队列·c/c++·信息学奥赛·程序设计竞赛
橘子在努力5 天前
【橘子分布式】gRPC(编程篇-下)
java·分布式·rpc
橘子在努力6 天前
【橘子分布式】gRPC(编程篇-中)
java·分布式·rpc
橘子在努力6 天前
【橘子分布式】gRPC(理论篇)
分布式·rpc