ChatServer
一个TCP服务器必然会有连接的接收,维持,收发数据等逻辑。那我们就要基于asio完成这个服务的搭建。主服务是这个样子的
1  | 
  | 
CServer类的声明
1  | 
  | 
构造函数中监听对方连接
1  | CServer::CServer(boost::asio::io_context& io_context, short port):_io_context(io_context), _port(port),  | 
接受连接的函数
1  | void CServer::StartAccept() {  | 
AsioIOServicePool
从AsioIOServicePool中返回一个可用的iocontext构造Session,然后将接受的新链接的socket写入这个Session保管。
AsioIOServicePool已经在前面讲解很多次了,它的声明如下
1  | 
  | 
AsioIOServicePool具体实现
1  | 
  | 
CServer的处理连接逻辑
1  | void CServer::HandleAccept(shared_ptr<CSession> new_session, const boost::system::error_code& error){  | 
Session层
上面的逻辑接受新链接后执行Start函数,新链接接受数据,然后Server继续监听新的连接
1  | void CSession::Start(){  | 
先读取头部数据
1  | void CSession::AsyncReadHead(int total_len)  | 
上面的逻辑里调用asyncReadFull读取整个长度,然后解析收到的数据,前两个字节为id,之后两个字节为长度,最后n个长度字节为消息内容。
1  | //读取完整长度  | 
读取指定长度
1  | //读取指定字节数  | 
读取头部成功后,其回调函数内部调用了读包体的逻辑
1  | void CSession::AsyncReadBody(int total_len)  | 
读取包体完成后,在回调中继续读包头。以此循环往复直到读完所有数据。如果对方不发送数据,则回调函数就不会触发。不影响程序执行其他工作,因为我们采用的是asio异步的读写操作。
当然我们解析完包体后会调用LogicSystem单例将解析好的消息封装为逻辑节点传递给逻辑层进行处理。
LogicSystem
我们在逻辑层处理
1  | void LogicSystem::RegisterCallBacks() {  | 
并在构造函数中注册这些处理流程
1  | LogicSystem::LogicSystem():_b_stop(false){  | 
总结
到此,完成了ChatServer收到QT客户端发送过来的长链接请求,并解析读取的数据,将收到的数据通过tcp发送给对端。接下来还要做ChatServer到GateServer的token验证,判断是否合理,这个教给之后的文章处理。