Asio19-CoroutineServer

Asio19-CoroutineServer

书接上节,我们要利用协程重构之前的服务器代码.

实际上改动并不大,对于写而言,比较简单,即使回调也比较少,没有改用协程.我们主要在读的时候使用了协程.

void Session::Start()
{
    boost::asio::co_spawn(_io_context, [self = shared_from_this(), this]() -> boost::asio::awaitable<void> {
        for(;!_close;){
            _recv_head_node->Clear();
            // 读
            co_await boost::asio::async_read(_socket,boost::asio::buffer(_recv_head_node->_data,HEADER_LENGTH),boost::asio::use_awaitable);
            // id
            uint16_t msg_id;
            std::memcpy(&msg_id,_recv_head_node->_data,HEADER_ID_LENGTH);
            msg_id = ntohs(msg_id);
            // len
            uint16_t data_len;
            std::memcpy(&data_len,_recv_head_node->_data+HEADER_ID_LENGTH,HEADER_DATA_LENGTH);
            data_len = ntohs(data_len);
            if(data_len > MAX_LENGTH){
                Close();
                co_return;
            }
            // std::cout << "Id:"<<msg_id<<"\tlen:" << data_len <<":\n";
            // msg
            _recv_msg_node = std::make_shared<RecvNode>(data_len,msg_id);
            int n = co_await boost::asio::async_read(_socket,boost::asio::buffer(_recv_msg_node->_data,data_len),boost::asio::use_awaitable);
            _recv_msg_node->_data[_recv_msg_node->_max_len] = '\0';
            // std::cout << _recv_msg_node->_data << "\n";
            
            if(n == 0){
                std::cout << "Connection closed by peer\n";
                Close();
                co_return;
            }
            LogicSystem::GetInstance().PostToLogicQueue(std::make_shared<LogicNode>(shared_from_this(),_recv_msg_node));

        } }, boost::asio::detached);
}

从这里也能看出来,使用协程将原本需要拆分成解析头部,消息体的回调直接以线性的方式编写,更加的简单便捷.

posted @ 2025-12-24 23:13  大胖熊哈  阅读(17)  评论(0)    收藏  举报