WebSocket 服务器实现详解:ws_svr 模块深度剖析
WebSocket 服务器实现详解:ws_svr 模块深度剖析
前言
在当今的 Web 应用开发领域,WebSocket 协议凭借其建立持久化双向通信通道的独特优势,已经成为实时通信不可或缺的技术选择。无论是即时通讯、在线协作,还是实时数据监控,WebSocket 都扮演着至关重要的角色。
本文将带领读者深入探索 ws_svr 模块的内部实现,从架构设计到代码细节,全方位解析一个功能完善的 WebSocket 服务器是如何从零构建的。无论你是 WebSocket 技术的初学者,还是希望深入了解服务器实现细节的开发者,都能从本文中获得有价值的见解。
一、整体架构概览
ws_svr 模块建立在 hv(libhv)库的坚实基础之上,采用了经典的单例模式设计,为开发者提供了一套完整且易于使用的 WebSocket 服务功能。该模块的设计充分考虑了性能、安全性和可扩展性,使其能够胜任各种实时通信场景的需求。
整体架构如下图所示,清晰地展示了各个核心组件之间的协作关系:
二、核心类设计
2.1 webSocketSvr 类
webSocketSvr 作为整个模块的核心类,承担着服务器初始化、连接管理和消息分发等重要职责。该类采用了单例模式,确保在整个应用程序的生命周期中只存在一个服务器实例,从而避免了资源浪费和状态冲突的问题。
class webSocketSvr : public wheels::dm::singleton< webSocketSvr >
{
private:
std::string m_listen_ip__; // 监听IP地址
int m_listen_port__; // 监听端口
std::shared_ptr<hv::WebSocketService > pt_ws_service__; // WebSocket服务
std::shared_ptr<hv::WebSocketServer> pt_ws_svr__; // WebSocket服务器
std::shared_ptr<hv::HttpService> pt_ping__; // HTTP心跳服务
std::map< uint32_t , std::shared_ptr< stConnection > > m_channels__; // 连接管理
token * p_token__; // Token认证器
std::atomic< uint32_t > m_conn_id__; // 连接ID计数器
};
设计亮点:
- 智能指针管理资源:通过
std::shared_ptr管理核心组件的生命周期,有效避免了内存泄漏和悬垂指针等常见问题,确保了系统的稳定性和可靠性。 - 线程安全的 ID 生成:采用
std::atomic实现连接 ID 的原子递增操作,在多线程环境下依然能够保证 ID 的唯一性和正确性,消除了竞态条件带来的潜在风险。 - 高效的连接管理:利用
std::map数据结构存储所有活跃连接,不仅提供了 O(log n) 时间复杂度的查找性能,还支持自动排序和快速遍历,为后续的广播和消息分发功能奠定了坚实基础。
2.2 stConnection 类
stConnection 类封装了单个 WebSocket 连接的所有必要信息,是连接管理的最小单元。每个连接对象都包含一个唯一的标识符和对应的 WebSocket 通道,使得服务器能够精确地定位和管理每一个客户端连接。
class stConnection
{
private:
uint32_t m_id; // 连接唯一ID
WebSocketChannelPtr p_channel__; // WebSocket通道
};
三、初始化流程详解
3.1 构造函数与初始化
服务器的初始化过程被精心设计为三个紧密衔接的阶段,每个阶段都承担着特定的职责,确保服务器能够以最佳状态启动并运行。整个初始化流程如下图所示:
关键代码分析:
webSocketSvr::webSocketSvr( token* p_token )
: p_token__( p_token ), m_conn_id__( 0 )
{
if( !p_token ){
ERROR_MSG( "token不能为空" );
throw std::runtime_error( "token不能为空" );
}
init__();
}
构造函数的设计体现了防御性编程的思想。首先,它会对传入的 Token 认证器进行严格的参数校验,确保其有效性。如果 Token 认证器为空,构造函数会立即抛出异常,阻止服务器进入不完整的状态。这种"快速失败"的策略有助于在问题发生的早期阶段就将其暴露出来,避免了后续可能出现的难以追踪的错误。通过参数校验后,构造函数会调用 init__() 方法,正式启动服务器的初始化流程。
3.2 WebSocket 服务初始化
init_ws_service__() 方法是整个初始化流程的核心,它负责注册三个关键的事件处理器,这些处理器将贯穿 WebSocket 连接的整个生命周期。事件处理器的注册流程如下图所示:





