Session——会话管理有什么
Session 回答的问题是:「每个连接自己的状态放哪?」 它被逼出来的原因是「每个连接的状态散落在 EventLoop 回调里」。这一篇讲它有什么——职责、内部结构、边界、异常、形态,重点是「协议状态属于 Session,不属于 Protocol」。
一、它解决什么问题
每个客户端连接都需要维护自己的状态:
1 2 3
| 缓冲区 已收到但还没处理完的字节 协议状态 握手 / 正常 / 关闭 活跃时间 多久没动了(心跳判断)
|
在没有 Session 的阶段,这些状态散落在 EventLoop 回调里——靠全局数组、靠 fd 索引到处查。连接一多,状态管理就乱。
Session 被逼出来的原因:把「每个连接的状态」集中到一个结构里,从事件分发中抽离。
二、它有什么(内部结构)
1 2 3 4 5 6 7
| struct Session { int fd; Buffer recv_buf; Buffer send_buf; ProtocolState state; time_t last_active; };
|
1 2 3
| 数据:fd + 接收/发送缓冲 + 协议状态 + 活跃时间 算法:状态机(协议状态流转)+ 心跳判断 接口:on_connect / on_message / on_disconnect / tick(心跳)
|
Session 的核心是「状态」:
1 2 3 4
| 每个客户端一个 Session 生命周期从连接建立到连接断开 连接建立 → 创建 Session 连接断开 → 销毁 Session
|
三、协议状态属于 Session,不属于 Protocol
这是上一轮澄清过的一个关键点,这里再强调:
1 2 3 4 5 6 7
| Protocol(数据结构): → struct Message 的定义,是「死的」 → 消息长什么样:length + command + payload
协议状态(活的): → 握手、正常、关闭,是「活的」 → 属于某个具体的会话
|
1 2 3
| Session.state = HANDSHAKING ← 这个会话正在握手 Session.state = NORMAL ← 这个会话正常通信中 Session.state = CLOSING ← 这个会话正在关闭
|
协议格式是死的定义,协议状态是活的、属于某个 Session。 所以「协议状态」不该挂在 Protocol(数据结构)上,而该挂在 Session 上。
四、它的边界:管「状态」,不管「事件」和「生死」
1 2 3
| ✅ 管:每个连接的缓冲、协议状态、活跃时间 ❌ 不管:什么时候有数据(EventLoop 的事) ❌ 不管:连接怎么建立/关闭(Connection 的事)
|
1 2 3
| EventLoop 说「fd 3 可读」 ← 什么时候 Connection 管「fd 3 还活着」 ← 生死 Session 管「fd 3 收到多少字节、协议走到哪一步」 ← 状态
|
三层分工清晰:
1 2 3
| EventLoop 什么时候有事 Connection 连接的生死 Session 连接的状态
|
五、它的形态:有状态组件,类封装
1 2
| 有状态:缓冲、协议状态、活跃时间,每个会话一份 有生命周期:连接建立时创建,断开时销毁
|
所以用类封装,每个连接一个 Session 对象,和 Connection 一一配对。
1 2 3 4
| Session* s = new Session(client_fd); s->on_connect(); s->on_data(bytes, len); s->on_disconnect();
|
六、它的异常
1 2 3 4 5 6 7 8 9 10 11
| 会话过期: 长时间没有活跃(超过心跳阈值) → 处理:清理会话、关闭连接、通知上层
协议版本不匹配: 握手时对方版本不一致 → 处理:握手失败、关闭连接、返回错误
协议状态机异常: 状态流转非法(如 NORMAL 状态收到握手请求) → 处理:记录、重置或关闭会话
|
Session 的异常都是「会话状态」层面的——它处理「状态怎么出问题了」,不处理「连接怎么断了」(Connection)或「字节格式对不对」(解析层)。
七、它和其他组件的关系
1 2 3 4
| Session ← 被 EventLoop 驱动(连接建立 → 创建;断开 → 销毁) Session ← 挂载在 Connection 上(一连接一会话) Session → 用 Buffer(recv_buf / send_buf 就是它的字段) Session → 持有 ProtocolState(协议状态字段)
|
1 2 3 4 5 6
| EventLoop ──驱动──→ Connection ──挂载──→ Session │ ┌─────────────┼─────────────┐ ↓ ↓ ↓ recv_buf send_buf state (Buffer) (Buffer) (ProtocolState)
|
八、小结
1 2 3 4 5 6 7 8 9 10
| Session 有什么: 职责:每个连接的缓冲、协议状态、活跃时间 结构:fd + recv_buf + send_buf + ProtocolState + last_active 边界:管「状态」,不管「事件」(EventLoop)和「生死」(Connection) 形态:有状态组件,类封装,一连接一会话 异常:会话过期 / 协议版本不匹配 / 状态机异常
关键:协议状态属于 Session,不属于 Protocol(数据结构)。
一句话:Session 是「每个连接此刻是什么状态」的容器。
|