|
|
# nnet 网络库 - 需求提炼与设计方案
|
|
|
|
|
|
## 一、需求提炼与整合
|
|
|
|
|
|
### 1. 核心功能模块
|
|
|
|
|
|
#### 1.1 多协议支持层
|
|
|
- **基础协议**:TCP、UDP、WebSocket、Unix Domain Socket
|
|
|
- **安全协议**:TLS/SSL(支持多种TLS版本和配置)
|
|
|
- **扩展协议**:串口通信(Serial Port)、命名管道(Named Pipe)等gnet不直接支持的协议
|
|
|
- **协议抽象**:统一的协议接口,便于扩展新协议类型
|
|
|
|
|
|
#### 1.2 协议版本管理系统
|
|
|
- **多版本识别机制**:
|
|
|
- 协议头识别:通过固定位置的版本字段识别
|
|
|
- 消息头识别:通过消息头中的版本信息识别
|
|
|
- 消息体识别:通过特定消息(如设备注册消息)中的软件版本号、硬件版本号等字段识别
|
|
|
- 用户自定义识别:支持用户自定义版本识别逻辑
|
|
|
- **版本选择策略**:
|
|
|
- 自动识别:系统自动根据识别规则选择版本
|
|
|
- 手动指定:允许用户手动指定协议版本
|
|
|
- 版本协商:支持客户端与服务端进行版本协商
|
|
|
- **版本持久化**:连接建立后,版本信息与连接绑定,重连时无需重新识别(通过连接标识或Session)
|
|
|
|
|
|
#### 1.3 路由系统(重新设计)
|
|
|
- **路由匹配策略**(高度可扩展):
|
|
|
- **基于URL/String匹配**:传统的字符串路由匹配(如:"/user/login")
|
|
|
- **基于协议帧头匹配**:通过协议帧头的特定字段进行路由匹配(如:消息类型、命令码等)
|
|
|
- **基于协议帧数据匹配**:通过协议帧数据内容的某部分进行路由匹配(如:消息体中的字段值)
|
|
|
- **组合匹配**:支持多种匹配策略组合使用
|
|
|
- **自定义匹配器**:支持用户自定义匹配逻辑
|
|
|
- **路由分组**:
|
|
|
- 按功能模块分组(如:用户模块、设备模块)
|
|
|
- 按权限分组(如:公开路由、认证路由)
|
|
|
- 支持嵌套分组(分组内可再分组)
|
|
|
- 分组可绑定匹配策略
|
|
|
- **函数集式路由**:
|
|
|
- 支持多个处理函数组合成路由链
|
|
|
- 支持路由级别的中间件绑定
|
|
|
- 支持路由级别的协议版本限制
|
|
|
- **路由优先级**:
|
|
|
- 支持路由优先级设置
|
|
|
- 精确匹配优先于通配符
|
|
|
- 帧头匹配优先于帧数据匹配
|
|
|
|
|
|
#### 1.4 中间件系统
|
|
|
- **全局中间件**:
|
|
|
- 在所有请求处理前后执行
|
|
|
- 支持中间件链的执行顺序控制
|
|
|
- 支持中间件的启用/禁用
|
|
|
- **路由级中间件**:
|
|
|
- 绑定到特定路由或路由组
|
|
|
- 支持中间件参数传递
|
|
|
- **中间件类型**:
|
|
|
- 前置中间件(Before):请求处理前执行
|
|
|
- 后置中间件(After):请求处理后执行
|
|
|
- 错误处理中间件(Error):异常捕获和处理
|
|
|
- 认证中间件(Auth):身份验证
|
|
|
- 限流中间件(RateLimit):请求限流
|
|
|
- 日志中间件(Logging):请求日志记录
|
|
|
|
|
|
#### 1.5 数据报文拦截器(责任链模式)
|
|
|
- **拦截器链**:
|
|
|
- 支持多个拦截器按顺序执行
|
|
|
- 支持拦截器的中断(提前返回)
|
|
|
- 支持拦截器的跳过(条件执行)
|
|
|
- **拦截点**:
|
|
|
- 接收拦截:数据接收后、解析前
|
|
|
- 解析拦截:数据解析后、路由前
|
|
|
- 路由拦截:路由匹配后、处理前
|
|
|
- 处理拦截:业务处理中
|
|
|
- 响应拦截:响应生成后、发送前
|
|
|
- **拦截器功能**:
|
|
|
- 数据验证
|
|
|
- 数据转换
|
|
|
- 数据加密/解密
|
|
|
- 数据压缩/解压
|
|
|
- 数据统计
|
|
|
|
|
|
#### 1.6 编解码与序列化系统
|
|
|
- **编解码器接口**:
|
|
|
- 编码器(Encoder):将消息对象编码为字节流
|
|
|
- 解码器(Decoder):将字节流解码为消息对象
|
|
|
- 支持协议级别的编解码器
|
|
|
- 支持消息级别的编解码器
|
|
|
- **序列化器**:
|
|
|
- 支持多种序列化格式:JSON、Protobuf、MessagePack、Binary等
|
|
|
- 支持自定义序列化器
|
|
|
- 结构体到字节流的序列化
|
|
|
- 字节流到结构体的反序列化
|
|
|
- **粘包拆包处理**:
|
|
|
- 内置支持常见协议:
|
|
|
- 固定长度协议
|
|
|
- 长度字段协议(支持大端/小端)
|
|
|
- 分隔符协议
|
|
|
- 自定义帧头协议
|
|
|
- 支持用户自定义粘包拆包逻辑
|
|
|
- 支持多协议混合使用(通过协议识别器区分)
|
|
|
|
|
|
#### 1.7 内置nnet协议
|
|
|
- **协议特点**:
|
|
|
- 简单高效:最小化协议开销
|
|
|
- 功能强大:支持游戏服务器、物联网等场景
|
|
|
- 可扩展:支持协议版本升级
|
|
|
- **协议格式**(建议):
|
|
|
```
|
|
|
[Magic(2B)][Version(1B)][Type(1B)][Length(4B)][Payload(NB)][Checksum(2B)]
|
|
|
```
|
|
|
- **协议功能**:
|
|
|
- 消息类型区分(请求/响应/推送)
|
|
|
- 消息ID支持(请求-响应匹配)
|
|
|
- 压缩支持(可选)
|
|
|
- 加密支持(可选)
|
|
|
|
|
|
#### 1.8 连接管理系统
|
|
|
- **连接生命周期管理**:
|
|
|
- 连接建立
|
|
|
- 连接保持
|
|
|
- 连接关闭
|
|
|
- 连接超时检测
|
|
|
- **连接操作**:
|
|
|
- 读取连接数据
|
|
|
- 写入连接数据
|
|
|
- 关闭连接
|
|
|
- 获取连接信息(IP、端口、协议版本等)
|
|
|
- 跨连接操作:在A连接的处理中操作B连接
|
|
|
- **连接分组**:
|
|
|
- 服务端控制分组:服务端主动将连接加入/移出分组
|
|
|
- 消息控制分组:通过消息内容(如用户ID、设备类型)自动分组
|
|
|
- 分组操作:向分组内所有连接广播消息
|
|
|
- 分组查询:查询分组内的连接列表
|
|
|
- **连接标识**:
|
|
|
- 连接ID:唯一标识一个连接
|
|
|
- 连接标签:支持给连接打标签,便于查询和分组
|
|
|
|
|
|
#### 1.9 Session管理系统
|
|
|
- **Session职责**:
|
|
|
- **仅作为数据存储**:Session只负责存储键值对数据
|
|
|
- **不负责广播**:广播功能由连接管理器实现
|
|
|
- **职责分离**:Session与连接管理解耦
|
|
|
- **Session存储策略**:
|
|
|
- **内存存储(Memory)**:默认实现,高性能(默认使用)
|
|
|
- 文件存储(File):持久化到本地文件
|
|
|
- Redis存储:分布式Session支持
|
|
|
- 自定义存储:用户可实现自定义存储策略
|
|
|
- **Session操作**:
|
|
|
- 创建Session
|
|
|
- 获取Session
|
|
|
- 更新Session
|
|
|
- 删除Session
|
|
|
- Session过期管理
|
|
|
- **Session与连接关联**:
|
|
|
- 连接可获取关联的Session
|
|
|
- Session可获取关联的连接(通过连接管理器)
|
|
|
- 支持一个Session关联多个连接(如多设备登录)
|
|
|
|
|
|
#### 1.10 Context系统
|
|
|
- **丰富的Context功能**:
|
|
|
- 请求上下文:包含请求相关的所有信息
|
|
|
- 连接上下文:包含连接相关的信息
|
|
|
- 用户上下文:包含用户相关的信息
|
|
|
- 协议上下文:包含协议版本、编解码器等信息
|
|
|
- **Context传递**:
|
|
|
- 在中间件、拦截器、处理器之间传递
|
|
|
- 支持Context值的设置和获取
|
|
|
- 支持Context的超时和取消
|
|
|
- **Context扩展**:
|
|
|
- 支持用户自定义Context字段
|
|
|
- 支持Context的序列化和反序列化(用于跨进程传递)
|
|
|
|
|
|
#### 1.11 配置管理系统
|
|
|
- **配置来源**:
|
|
|
- 配置文件:支持JSON、YAML、TOML等格式
|
|
|
- 环境变量:支持从环境变量读取配置
|
|
|
- 代码配置:支持通过代码直接配置
|
|
|
- 配置优先级:代码配置 > 环境变量 > 配置文件 > 默认值
|
|
|
- **配置项**:
|
|
|
- 服务器配置:监听地址、端口、协议类型等
|
|
|
- 性能配置:连接数限制、缓冲区大小、超时时间等
|
|
|
- 协议配置:协议版本、编解码器选择等
|
|
|
- 中间件配置:中间件的启用/禁用、参数配置
|
|
|
- Session配置:存储策略、过期时间等
|
|
|
- 日志配置:日志级别、输出格式等
|
|
|
- Metrics配置:监控指标配置
|
|
|
|
|
|
#### 1.12 日志系统(日志门面)
|
|
|
- **日志接口**:
|
|
|
- 定义统一的日志接口
|
|
|
- 支持日志级别:Debug、Info、Warn、Error、Fatal
|
|
|
- 支持结构化日志
|
|
|
- 支持日志字段(Fields)
|
|
|
- **默认实现**:
|
|
|
- 使用Go标准库log实现
|
|
|
- 支持日志输出到控制台、文件
|
|
|
- **第三方集成**:
|
|
|
- 支持logrus
|
|
|
- 支持zap
|
|
|
- 支持zerolog
|
|
|
- 支持用户自定义日志实现
|
|
|
- **日志配置**:
|
|
|
- 日志级别控制
|
|
|
- 日志格式配置
|
|
|
- 日志轮转配置
|
|
|
|
|
|
#### 1.13 指标监控(Metrics)
|
|
|
- **监控协议**:
|
|
|
- **Prometheus格式**:仅支持Prometheus格式(业内最流行)
|
|
|
- **监控指标**:
|
|
|
- 连接数:当前连接数、总连接数、连接建立速率
|
|
|
- 请求数:请求总数、请求速率、请求耗时分布
|
|
|
- 错误数:错误总数、错误率、错误类型分布
|
|
|
- 流量:接收字节数、发送字节数、流量速率
|
|
|
- 协议统计:各协议版本的请求数、错误数
|
|
|
- **指标导出**:
|
|
|
- 提供HTTP Handler(推荐挂载 `/metrics`)由使用者的HTTP服务调用
|
|
|
- 支持直接写出Prometheus文本以适配自定义传输(`ExportMetrics`)
|
|
|
- 支持自定义指标
|
|
|
|
|
|
#### 1.14 插件系统
|
|
|
- **插件接口**:
|
|
|
- 定义标准的插件接口
|
|
|
- 支持插件的初始化、启动、停止、销毁
|
|
|
- **插件类型**:
|
|
|
- **协议插件**:扩展新的协议支持
|
|
|
- **中间件插件**:提供可复用的中间件
|
|
|
- **编解码插件**:提供新的编解码器
|
|
|
- **存储插件**:提供新的Session存储实现
|
|
|
- **监控插件**:扩展监控功能
|
|
|
- **工具插件**:提供开发工具和辅助功能
|
|
|
- **插件管理**:
|
|
|
- 插件注册
|
|
|
- 插件加载(支持动态加载)
|
|
|
- 插件卸载
|
|
|
- 插件依赖管理
|
|
|
- **插件示例场景**:
|
|
|
- **协议转换插件**:将HTTP协议转换为内部协议
|
|
|
- **数据统计插件**:统计特定业务数据
|
|
|
- **消息队列插件**:将消息推送到消息队列
|
|
|
- **缓存插件**:提供缓存功能
|
|
|
- **限流插件**:提供限流功能
|
|
|
|
|
|
#### 1.15 生命周期管理
|
|
|
- **Server生命周期阶段**:
|
|
|
1. **初始化(Init)**:配置加载、组件初始化
|
|
|
2. **启动前(BeforeStart)**:启动前的准备工作
|
|
|
3. **启动(Start)**:服务启动,开始监听
|
|
|
4. **运行中(Running)**:服务正常运行
|
|
|
5. **停止前(BeforeStop)**:停止前的清理工作
|
|
|
6. **停止(Stop)**:服务停止,停止监听
|
|
|
7. **销毁(Destroy)**:资源释放
|
|
|
- **Connection生命周期阶段**:
|
|
|
1. **连接建立(OnOpen)**:连接建立时触发
|
|
|
2. **数据接收(OnTraffic)**:数据到达时触发
|
|
|
3. **连接关闭(OnClose)**:连接关闭时触发
|
|
|
4. **连接错误(OnError)**:连接错误时触发
|
|
|
- **生命周期钩子**:
|
|
|
- 支持Server生命周期钩子注册
|
|
|
- 支持Connection生命周期钩子注册
|
|
|
- 支持钩子函数的执行顺序控制
|
|
|
- 支持钩子函数的错误处理
|
|
|
- **优雅关闭**:
|
|
|
- 支持优雅关闭(Graceful Shutdown)
|
|
|
- 等待正在处理的请求完成
|
|
|
- 关闭空闲连接
|
|
|
- 资源清理
|
|
|
|
|
|
#### 1.16 客户端支持
|
|
|
- **内置nnet客户端**:
|
|
|
- 支持TCP、UDP、WebSocket等协议连接
|
|
|
- 支持TLS连接
|
|
|
- 支持协议版本协商
|
|
|
- 支持自动重连
|
|
|
- 支持连接池
|
|
|
- **客户端功能**:
|
|
|
- 请求-响应模式
|
|
|
- 异步消息推送
|
|
|
- 连接状态管理
|
|
|
- 超时控制
|
|
|
- 错误处理
|
|
|
|
|
|
#### 1.17 健康检查接口
|
|
|
- **健康检查端点**:
|
|
|
- 提供简单的HTTP健康检查接口(/health)
|
|
|
- 返回服务状态(健康/不健康)
|
|
|
- 可扩展健康检查逻辑
|
|
|
- **健康检查内容**:
|
|
|
- 服务运行状态
|
|
|
- 连接数统计
|
|
|
- 资源使用情况(可选)
|
|
|
|
|
|
#### 1.18 Shell连接支持(低优先级)
|
|
|
- **Shell连接功能**:
|
|
|
- 支持Shell连接建立
|
|
|
- 支持Shell命令执行
|
|
|
- 支持子进程管理
|
|
|
- 支持数据传输
|
|
|
- 支持连接控制
|
|
|
- **应用场景**:
|
|
|
- 远程命令执行
|
|
|
- 系统管理
|
|
|
- 调试工具
|
|
|
|
|
|
#### 1.19 测试支持
|
|
|
- **单元测试**:各模块的单元测试
|
|
|
- **集成测试**:模块间的集成测试
|
|
|
- **性能测试**:压力测试、性能基准测试
|
|
|
- **测试工具**:提供测试辅助工具和Mock对象
|
|
|
- **测试覆盖率**:目标80%+
|
|
|
|
|
|
### 2. 非功能性需求
|
|
|
|
|
|
#### 2.1 性能要求
|
|
|
- 充分利用gnet的事件驱动模型
|
|
|
- 减少内存分配和GC压力
|
|
|
- 支持连接池和对象池
|
|
|
- 高性能的序列化/反序列化
|
|
|
|
|
|
#### 2.2 可扩展性
|
|
|
- 模块化设计,低耦合高内聚
|
|
|
- 接口驱动,便于扩展
|
|
|
- 插件化架构,支持功能扩展
|
|
|
|
|
|
#### 2.3 可维护性
|
|
|
- 代码简洁清晰
|
|
|
- 充分的注释和文档
|
|
|
- 遵循Go代码规范
|
|
|
|
|
|
#### 2.4 依赖管理
|
|
|
- 最小化外部依赖
|
|
|
- 核心功能不依赖第三方库
|
|
|
- 可选功能通过接口隔离,支持可选依赖
|
|
|
|
|
|
## 二、架构设计
|
|
|
|
|
|
### 2.1 整体架构
|
|
|
|
|
|
```
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
│ 应用层 (Application) │
|
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
|
│ │ 路由 │ │ 中间件 │ │ 拦截器 │ │ 处理器 │ │
|
|
|
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
│
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
│ 核心层 (Core) │
|
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
|
│ │连接管理 │ │Session │ │Context │ │生命周期 │ │
|
|
|
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
│
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
│ 协议层 (Protocol) │
|
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
|
│ │协议管理 │ │版本管理 │ │编解码 │ │粘包拆包 │ │
|
|
|
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
│
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
│ 传输层 (Transport) │
|
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
|
│ │ TCP │ │ UDP │ │WebSocket │ │ Unix │ │
|
|
|
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
|
│ │ TLS │ │ 串口 │ │ 扩展 │ │
|
|
|
│ └──────────┘ └──────────┘ └──────────┘ │
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
│
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
│ 基础设施层 (Infrastructure) │
|
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
|
│ │ 配置 │ │ 日志 │ │ 监控 │ │ 插件 │ │
|
|
|
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
│
|
|
|
┌───────┐
|
|
|
│ gnet │
|
|
|
└───────┘
|
|
|
```
|
|
|
|
|
|
### 2.2 核心模块设计
|
|
|
|
|
|
#### 2.2.1 服务器核心(Server Core)
|
|
|
```go
|
|
|
// 伪代码示例
|
|
|
type Server struct {
|
|
|
// 配置
|
|
|
config *Config
|
|
|
|
|
|
// 协议管理器
|
|
|
protocolManager *ProtocolManager
|
|
|
|
|
|
// 连接管理器
|
|
|
connManager *ConnectionManager
|
|
|
|
|
|
// 路由管理器
|
|
|
router *Router
|
|
|
|
|
|
// 中间件链
|
|
|
middlewares []Middleware
|
|
|
|
|
|
// 拦截器链
|
|
|
interceptors []Interceptor
|
|
|
|
|
|
// Session管理器
|
|
|
sessionManager *SessionManager
|
|
|
|
|
|
// 生命周期管理器
|
|
|
lifecycle *Lifecycle
|
|
|
|
|
|
// 插件管理器
|
|
|
pluginManager *PluginManager
|
|
|
|
|
|
// 日志
|
|
|
logger Logger
|
|
|
|
|
|
// Metrics
|
|
|
metrics Metrics
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### 2.2.2 协议管理器(Protocol Manager)
|
|
|
- **职责**:
|
|
|
- 协议注册和发现
|
|
|
- 协议版本管理
|
|
|
- 协议识别和选择
|
|
|
- 编解码器管理
|
|
|
- **关键接口**:
|
|
|
```go
|
|
|
type Protocol interface {
|
|
|
Name() string
|
|
|
Versions() []Version
|
|
|
Identify(data []byte) (Version, error)
|
|
|
CreateCodec(version Version) (Codec, error)
|
|
|
}
|
|
|
|
|
|
type Version interface {
|
|
|
Version() string
|
|
|
Identify(data []byte) bool
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### 2.2.3 连接管理器(Connection Manager)
|
|
|
- **职责**:
|
|
|
- 连接的创建、维护、销毁
|
|
|
- 连接分组管理
|
|
|
- 连接查询和操作
|
|
|
- 跨连接操作
|
|
|
- **关键接口**:
|
|
|
```go
|
|
|
type ConnectionManager interface {
|
|
|
Add(conn Connection) error
|
|
|
Remove(connID string) error
|
|
|
Get(connID string) (Connection, error)
|
|
|
Group(groupID string) ConnectionGroup
|
|
|
Broadcast(groupID string, data []byte) error
|
|
|
}
|
|
|
|
|
|
type Connection interface {
|
|
|
ID() string
|
|
|
Write(data []byte) error
|
|
|
Close() error
|
|
|
Context() Context
|
|
|
Session() Session
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### 2.2.4 路由管理器(Router)- 重新设计
|
|
|
- **职责**:
|
|
|
- 路由注册和匹配(支持多种匹配策略)
|
|
|
- 路由分组管理
|
|
|
- 路由中间件绑定
|
|
|
- **关键接口**:
|
|
|
```go
|
|
|
// 路由匹配器接口
|
|
|
type Matcher interface {
|
|
|
Match(input MatchInput, ctx Context) bool
|
|
|
Priority() int // 优先级,数字越大优先级越高
|
|
|
}
|
|
|
|
|
|
// 字符串匹配器(传统URL匹配)
|
|
|
type StringMatcher struct {
|
|
|
pattern string
|
|
|
}
|
|
|
|
|
|
// 帧头匹配器(基于协议帧头)
|
|
|
type FrameHeaderMatcher struct {
|
|
|
field string // 字段名(如:消息类型、命令码)
|
|
|
operator string // 操作符(如:==、!=、>、<等)
|
|
|
value interface{}
|
|
|
}
|
|
|
|
|
|
// 帧数据匹配器(基于协议帧数据内容)
|
|
|
type FrameDataMatcher struct {
|
|
|
path string // 数据路径(如:JSON路径、字段路径)
|
|
|
operator string // 操作符
|
|
|
value interface{}
|
|
|
}
|
|
|
|
|
|
// 自定义匹配器
|
|
|
type CustomMatcher struct {
|
|
|
fn func(input MatchInput, ctx Context) bool
|
|
|
}
|
|
|
|
|
|
// 路由接口
|
|
|
type Router interface {
|
|
|
// 注册路由(使用匹配器)
|
|
|
Register(matcher Matcher, handler Handler) Route
|
|
|
|
|
|
// 便捷方法:字符串匹配
|
|
|
RegisterString(pattern string, handler Handler) Route
|
|
|
|
|
|
// 便捷方法:帧头匹配
|
|
|
RegisterFrameHeader(field string, operator string, value interface{}, handler Handler) Route
|
|
|
|
|
|
// 便捷方法:帧数据匹配
|
|
|
RegisterFrameData(path string, operator string, value interface{}, handler Handler) Route
|
|
|
|
|
|
// 路由分组
|
|
|
Group() RouterGroup
|
|
|
|
|
|
// 路由匹配
|
|
|
Match(input MatchInput, ctx Context) (Handler, []Matcher, error)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### 2.2.5 Session管理器(Session Manager)
|
|
|
- **职责**:
|
|
|
- Session的创建、获取、更新、删除
|
|
|
- Session存储策略管理
|
|
|
- Session过期管理
|
|
|
- **关键接口**:
|
|
|
```go
|
|
|
type SessionManager interface {
|
|
|
Create(connID string) (Session, error)
|
|
|
Get(sessionID string) (Session, error)
|
|
|
Delete(sessionID string) error
|
|
|
}
|
|
|
|
|
|
type Session interface {
|
|
|
ID() string
|
|
|
Get(key string) (interface{}, error)
|
|
|
Set(key string, value interface{}) error
|
|
|
Delete(key string) error
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 2.3 数据流设计
|
|
|
|
|
|
```
|
|
|
客户端数据
|
|
|
│
|
|
|
▼
|
|
|
[传输层接收] (gnet事件)
|
|
|
│
|
|
|
▼
|
|
|
[协议识别] (ProtocolManager)
|
|
|
│
|
|
|
▼
|
|
|
[粘包拆包] (Unpacker)
|
|
|
│
|
|
|
▼
|
|
|
[版本识别] (VersionManager) ──→ [版本持久化]
|
|
|
│
|
|
|
▼
|
|
|
[解码] (Decoder)
|
|
|
│
|
|
|
▼
|
|
|
[拦截器链] (InterceptorChain)
|
|
|
│
|
|
|
▼
|
|
|
[路由匹配] (Router)
|
|
|
│
|
|
|
▼
|
|
|
[中间件链] (MiddlewareChain)
|
|
|
│
|
|
|
▼
|
|
|
[业务处理] (Handler)
|
|
|
│
|
|
|
▼
|
|
|
[编码] (Encoder)
|
|
|
│
|
|
|
▼
|
|
|
[拦截器链] (InterceptorChain)
|
|
|
│
|
|
|
▼
|
|
|
[传输层发送] (gnet事件)
|
|
|
│
|
|
|
▼
|
|
|
客户端
|
|
|
```
|
|
|
|
|
|
### 2.4 目录结构设计
|
|
|
|
|
|
```
|
|
|
nnet/
|
|
|
├── cmd/ # 命令行工具和示例
|
|
|
│ ├── server/ # 服务器示例
|
|
|
│ └── client/ # 客户端示例
|
|
|
├── internal/ # 内部实现(不对外暴露)
|
|
|
│ ├── server/ # 服务器核心
|
|
|
│ ├── protocol/ # 协议实现
|
|
|
│ │ ├── tcp/ # TCP协议
|
|
|
│ │ ├── udp/ # UDP协议
|
|
|
│ │ ├── websocket/ # WebSocket协议
|
|
|
│ │ ├── unix/ # Unix Domain Socket
|
|
|
│ │ ├── tls/ # TLS协议
|
|
|
│ │ ├── serial/ # 串口协议
|
|
|
│ │ └── nnet/ # 内置nnet协议
|
|
|
│ ├── router/ # 路由实现
|
|
|
│ ├── middleware/ # 中间件实现
|
|
|
│ ├── interceptor/ # 拦截器实现
|
|
|
│ ├── connection/ # 连接管理
|
|
|
│ ├── session/ # Session管理
|
|
|
│ │ ├── memory/ # 内存存储
|
|
|
│ │ ├── file/ # 文件存储
|
|
|
│ │ └── redis/ # Redis存储
|
|
|
│ ├── codec/ # 编解码器
|
|
|
│ ├── unpacker/ # 粘包拆包
|
|
|
│ ├── version/ # 版本管理
|
|
|
│ ├── config/ # 配置管理
|
|
|
│ ├── logger/ # 日志实现
|
|
|
│ ├── metrics/ # 指标监控
|
|
|
│ ├── plugin/ # 插件系统
|
|
|
│ └── lifecycle/ # 生命周期
|
|
|
├── pkg/ # 对外暴露的包
|
|
|
│ ├── nnet/ # 主包
|
|
|
│ ├── protocol/ # 协议接口
|
|
|
│ ├── router/ # 路由接口
|
|
|
│ ├── middleware/ # 中间件接口
|
|
|
│ ├── interceptor/ # 拦截器接口
|
|
|
│ ├── connection/ # 连接接口
|
|
|
│ ├── session/ # Session接口
|
|
|
│ ├── codec/ # 编解码接口
|
|
|
│ └── context/ # Context接口
|
|
|
├── examples/ # 示例代码
|
|
|
├── test/ # 测试代码
|
|
|
├── docs/ # 文档
|
|
|
├── go.mod
|
|
|
├── go.sum
|
|
|
└── README.md
|
|
|
```
|
|
|
|
|
|
## 三、关键技术设计
|
|
|
|
|
|
### 3.1 协议版本识别策略
|
|
|
|
|
|
#### 3.1.1 识别时机
|
|
|
1. **连接建立时**:通过握手消息识别
|
|
|
2. **首次消息时**:通过第一个消息识别
|
|
|
3. **特定消息时**:通过包含版本信息的特定消息识别
|
|
|
|
|
|
#### 3.1.2 识别方式
|
|
|
```go
|
|
|
type VersionIdentifier interface {
|
|
|
// 通过协议头识别(适用于有帧头的协议)
|
|
|
IdentifyByHeader(data []byte) (Version, bool)
|
|
|
|
|
|
// 通过消息头识别(适用于有消息头的协议)
|
|
|
IdentifyByMessageHeader(msg Message) (Version, bool)
|
|
|
|
|
|
// 通过消息体识别(如设备注册消息中的硬件版本号)
|
|
|
IdentifyByMessageBody(msg Message) (Version, bool)
|
|
|
|
|
|
// 用户自定义识别(适用于无帧头/帧内容区分的协议)
|
|
|
IdentifyCustom(data []byte, ctx Context) (Version, bool)
|
|
|
}
|
|
|
|
|
|
// 对于无帧头/帧内容区分的协议
|
|
|
// 可以通过以下方式识别:
|
|
|
// 1. 通过消息内容的特征识别(如:特定字段的位置、值)
|
|
|
// 2. 通过消息长度识别
|
|
|
// 3. 通过消息格式识别(如:JSON结构、字段名等)
|
|
|
// 4. 通过用户自定义的识别逻辑
|
|
|
```
|
|
|
|
|
|
#### 3.1.3 版本持久化
|
|
|
- 版本信息与连接ID绑定
|
|
|
- 存储在连接上下文中
|
|
|
- 支持通过Session持久化(跨重连)
|
|
|
|
|
|
#### 3.1.4 无帧头协议的特殊处理
|
|
|
- **识别策略**:
|
|
|
- 对于没有帧头、帧内容区分的协议,版本识别需要基于:
|
|
|
- 消息内容的特征(字段位置、值、格式等)
|
|
|
- 消息长度
|
|
|
- 消息结构(JSON结构、字段名等)
|
|
|
- 用户自定义识别逻辑
|
|
|
- **实现方式**:
|
|
|
- 提供灵活的版本识别接口
|
|
|
- 支持基于消息内容的版本识别
|
|
|
- 支持延迟识别(等待足够信息后再识别)
|
|
|
|
|
|
### 3.2 粘包拆包解决方案
|
|
|
|
|
|
#### 3.2.1 内置协议支持
|
|
|
```go
|
|
|
type Unpacker interface {
|
|
|
// 从缓冲区中提取完整消息
|
|
|
Unpack(buffer []byte) ([]Message, []byte, error)
|
|
|
}
|
|
|
|
|
|
// 内置实现
|
|
|
type FixedLengthUnpacker struct { length int }
|
|
|
type LengthFieldUnpacker struct {
|
|
|
offset int
|
|
|
length int
|
|
|
endian Endian
|
|
|
}
|
|
|
type DelimiterUnpacker struct { delimiter []byte }
|
|
|
type FrameHeaderUnpacker struct {
|
|
|
headerSize int
|
|
|
lengthOffset int
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### 3.2.2 协议识别与粘包拆包
|
|
|
- 每个协议版本可配置独立的Unpacker
|
|
|
- 支持协议级别的Unpacker选择
|
|
|
- 支持动态Unpacker切换(协议升级场景)
|
|
|
|
|
|
### 3.3 中间件与拦截器区别
|
|
|
|
|
|
- **中间件(Middleware)**:
|
|
|
- 作用在请求-响应层面
|
|
|
- 可以修改请求和响应
|
|
|
- 可以中断请求处理
|
|
|
- 主要用于:认证、限流、日志、错误处理等
|
|
|
|
|
|
- **拦截器(Interceptor)**:
|
|
|
- 作用在数据报文层面
|
|
|
- 可以修改原始数据
|
|
|
- 可以用于:数据验证、数据转换、数据加密等
|
|
|
- 更底层,在编解码前后执行
|
|
|
|
|
|
### 3.4 插件系统应用场景
|
|
|
|
|
|
1. **协议转换插件**:
|
|
|
- 将HTTP请求转换为内部协议
|
|
|
- 将MQTT消息转换为内部协议
|
|
|
|
|
|
2. **数据统计插件**:
|
|
|
- 统计业务指标(如:用户在线时长、消息发送量)
|
|
|
- 将统计数据推送到监控系统
|
|
|
|
|
|
3. **消息队列插件**:
|
|
|
- 将消息异步推送到Kafka、RabbitMQ等
|
|
|
- 实现消息的持久化和异步处理
|
|
|
|
|
|
4. **缓存插件**:
|
|
|
- 提供分布式缓存功能
|
|
|
- 缓存热点数据,提升性能
|
|
|
|
|
|
5. **限流插件**:
|
|
|
- 实现多种限流算法(令牌桶、漏桶等)
|
|
|
- 支持分布式限流
|
|
|
|
|
|
6. **数据同步插件**:
|
|
|
- 将数据同步到数据库
|
|
|
- 实现数据的持久化
|
|
|
|
|
|
### 3.5 生命周期钩子设计
|
|
|
|
|
|
```go
|
|
|
// Server生命周期钩子
|
|
|
type ServerLifecycleHook interface {
|
|
|
OnInit(server *Server) error
|
|
|
OnBeforeStart(server *Server) error
|
|
|
OnStart(server *Server) error
|
|
|
OnRunning(server *Server) error
|
|
|
OnBeforeStop(server *Server) error
|
|
|
OnStop(server *Server) error
|
|
|
OnDestroy(server *Server) error
|
|
|
}
|
|
|
|
|
|
// Connection生命周期钩子
|
|
|
type ConnectionLifecycleHook interface {
|
|
|
OnOpen(conn Connection) error
|
|
|
OnTraffic(conn Connection, data []byte) error
|
|
|
OnClose(conn Connection) error
|
|
|
OnError(conn Connection, err error) error
|
|
|
}
|
|
|
|
|
|
// 使用示例
|
|
|
server.AddServerLifecycleHook(&MyServerHook{})
|
|
|
server.AddConnectionLifecycleHook(&MyConnectionHook{})
|
|
|
```
|
|
|
|
|
|
### 3.6 gnet集成设计
|
|
|
|
|
|
- **充分利用gnet的事件循环**:
|
|
|
- 使用gnet的OnOpen、OnClose、OnTraffic事件
|
|
|
- 在OnTraffic中处理数据接收
|
|
|
- 使用gnet的Write方法发送数据
|
|
|
|
|
|
- **连接封装**:
|
|
|
- 将gnet的连接封装为nnet的Connection接口
|
|
|
- 保持gnet的高性能特性
|
|
|
|
|
|
- **多协议支持**:
|
|
|
- 通过gnet的Engine支持TCP/UDP
|
|
|
- WebSocket通过HTTP升级实现
|
|
|
- Unix Domain Socket通过gnet支持
|
|
|
- 串口等通过独立实现,统一接口
|
|
|
|
|
|
## 四、实现优先级建议
|
|
|
|
|
|
### Phase 1: 核心功能(MVP)
|
|
|
1. TCP协议支持
|
|
|
2. 基础路由系统(支持字符串匹配)
|
|
|
3. 基础中间件系统
|
|
|
4. 连接管理(基础功能)
|
|
|
5. 基础配置管理
|
|
|
6. 基础日志系统
|
|
|
7. 健康检查接口
|
|
|
|
|
|
### Phase 2: 协议与数据处理
|
|
|
1. 协议版本管理(包括无帧头协议支持)
|
|
|
2. 编解码系统
|
|
|
3. 粘包拆包处理
|
|
|
4. 内置nnet协议
|
|
|
5. UDP、WebSocket协议支持
|
|
|
6. 路由系统扩展(帧头匹配、帧数据匹配)
|
|
|
|
|
|
### Phase 3: 高级功能
|
|
|
1. Session管理(默认内存存储)
|
|
|
2. 拦截器系统
|
|
|
3. 连接分组
|
|
|
4. TLS支持
|
|
|
5. Unix Domain Socket支持
|
|
|
6. 内置nnet客户端
|
|
|
7. 生命周期管理(Server + Connection)
|
|
|
|
|
|
### Phase 4: 扩展功能
|
|
|
1. 插件系统
|
|
|
2. Metrics监控(Prometheus格式)
|
|
|
3. 串口等扩展协议
|
|
|
4. 高级配置功能
|
|
|
5. 测试完善(覆盖率80%+)
|
|
|
|
|
|
### Phase 5: 优化与完善
|
|
|
1. 性能优化
|
|
|
2. 文档完善
|
|
|
3. 示例代码
|
|
|
4. 最佳实践
|
|
|
5. Shell连接支持(低优先级)
|
|
|
|
|
|
## 五、设计原则
|
|
|
|
|
|
1. **接口驱动设计**:核心功能通过接口定义,便于扩展和测试
|
|
|
2. **依赖倒置**:高层模块不依赖低层模块,都依赖抽象
|
|
|
3. **单一职责**:每个模块只负责一个功能
|
|
|
4. **开闭原则**:对扩展开放,对修改关闭
|
|
|
5. **最小依赖**:核心功能不依赖第三方库
|
|
|
6. **高性能优先**:充分利用gnet的性能特性
|
|
|
7. **易用性**:提供简洁的API,降低使用门槛
|
|
|
|
|
|
## 六、客户端设计
|
|
|
|
|
|
### 6.1 客户端架构
|
|
|
|
|
|
```
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
│ 客户端应用层 │
|
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
|
│ │ 请求发送 │ │ 响应接收 │ │ 消息推送 │ │
|
|
|
│ └──────────┘ └──────────┘ └──────────┘ │
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
│
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
│ 客户端核心层 │
|
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
|
│ │连接管理 │ │协议管理 │ │编解码 │ │重连管理 │ │
|
|
|
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
│
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
│ 传输层 │
|
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
|
│ │ TCP │ │ UDP │ │WebSocket │ │
|
|
|
│ └──────────┘ └──────────┘ └──────────┘ │
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
```
|
|
|
|
|
|
### 6.2 客户端接口设计
|
|
|
|
|
|
```go
|
|
|
// 客户端接口
|
|
|
type Client interface {
|
|
|
// 连接服务器
|
|
|
Connect(addr string) error
|
|
|
|
|
|
// 断开连接
|
|
|
Disconnect() error
|
|
|
|
|
|
// 发送请求(同步)
|
|
|
Request(data []byte, timeout time.Duration) ([]byte, error)
|
|
|
|
|
|
// 发送请求(异步)
|
|
|
RequestAsync(data []byte, callback func([]byte, error)) error
|
|
|
|
|
|
// 发送消息(无需响应)
|
|
|
Send(data []byte) error
|
|
|
|
|
|
// 注册消息处理器
|
|
|
OnMessage(handler func([]byte))
|
|
|
|
|
|
// 注册连接状态变化处理器
|
|
|
OnConnect(handler func())
|
|
|
OnDisconnect(handler func())
|
|
|
OnError(handler func(error))
|
|
|
|
|
|
// 获取连接状态
|
|
|
IsConnected() bool
|
|
|
|
|
|
// 关闭客户端
|
|
|
Close() error
|
|
|
}
|
|
|
|
|
|
// 客户端配置
|
|
|
type ClientConfig struct {
|
|
|
// 服务器地址
|
|
|
Addr string
|
|
|
|
|
|
// 协议类型
|
|
|
Protocol string
|
|
|
|
|
|
// TLS配置
|
|
|
TLS *TLSConfig
|
|
|
|
|
|
// 重连配置
|
|
|
Reconnect *ReconnectConfig
|
|
|
|
|
|
// 超时配置
|
|
|
Timeout time.Duration
|
|
|
|
|
|
// 连接池配置
|
|
|
Pool *PoolConfig
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 6.3 客户端使用示例
|
|
|
|
|
|
```go
|
|
|
// 创建客户端
|
|
|
client := nnet.NewClient(&nnet.ClientConfig{
|
|
|
Addr: "tcp://127.0.0.1:8080",
|
|
|
Protocol: "nnet",
|
|
|
Timeout: 5 * time.Second,
|
|
|
})
|
|
|
|
|
|
// 注册消息处理器
|
|
|
client.OnMessage(func(data []byte) {
|
|
|
fmt.Println("收到消息:", string(data))
|
|
|
})
|
|
|
|
|
|
// 连接服务器
|
|
|
err := client.Connect("tcp://127.0.0.1:8080")
|
|
|
if err != nil {
|
|
|
log.Fatal(err)
|
|
|
}
|
|
|
|
|
|
// 发送请求
|
|
|
response, err := client.Request([]byte("hello"), 5*time.Second)
|
|
|
if err != nil {
|
|
|
log.Fatal(err)
|
|
|
}
|
|
|
|
|
|
// 关闭客户端
|
|
|
client.Close()
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
**设计文档版本**: v1.1
|
|
|
**设计日期**: 2024
|
|
|
**设计者**: AI Assistant
|
|
|
**状态**: 已根据用户反馈更新
|
|
|
|