[Network] 7. FlatBuffers + Boost Asio 콘솔 서버 예제 (3)
프로그래밍 언어/Flatbuffers2021. 7. 7. 14:33
		
		
이번에는 서버 세션 객체를 작성하였습니다. 패킷 읽기 부분에 대한것은 내부적으로 사용되므로 private 하였습니다.
핵심 부분은 handle_read_body() 함수에서 패킷 데이터를 읽어서 ProcessPacket으로 패킷을 넘겨주는 부분이 있겠습니다.
특별히 어려운 부분은 없으므로 코드를 보시면 쉽게 이해 가능하실거라 생각됩니다. 람다코드와 shared_ptr 부분은 기초적인 것이므로 해설을 생략하였습니다.
어려운 부분이 있거나 궁금한 내용이 있으시면 댓글 부탁합니다.
Session.h
#pragma once
#include "Message.h"
class CChatServer;
class CSession : public std::enable_shared_from_this<CSession>
{
public:
	CSession(boost::asio::ip::tcp::socket socket, CChatServer* pServer);
	~CSession();
public:
	boost::asio::ip::tcp::socket& Socket() { return m_Socket; }
	void Start();
	void Write(const CMessage& msg);
	void SetName(const char* pszName) { m_Name = pszName; }
	const char* GetName() { return m_Name.c_str(); }
private:
	void handle_write();
	void handle_read_header();
	void handle_read_body();
private:
	boost::asio::ip::tcp::socket m_Socket;
	std::string m_Name;
	CChatServer* m_pServer;
	CMessage m_ReadMessage;
	std::deque<CMessage> m_WriteMessage;
};
Session.cpp
#include "stdafx.h"
#include "Session.h"
#include "ChatServer.h"
CSession::CSession(boost::asio::ip::tcp::socket socket, CChatServer* pServer)
	: m_Socket(std::move(socket))
	, m_pServer(pServer)
{
}
CSession::~CSession()
{
}
void CSession::Start()
{
	handle_read_header();
}
void CSession::Write(const CMessage& msg)
{
    m_WriteMessage.push_back(msg);
    if (!m_WriteMessage.empty())
    {
        handle_write();
    }
}
void CSession::handle_write()
{
    auto self(shared_from_this());
    boost::asio::async_write(m_Socket,
        boost::asio::buffer(m_WriteMessage.front().data(), m_WriteMessage.front().length()),
        [this, self](boost::system::error_code error, std::size_t /*length*/)
        {
            if (!error)
            {
                m_WriteMessage.pop_front();
                if (!m_WriteMessage.empty())
                {
                    handle_write();
                }
            }
            else
            {
                m_pServer->EndSession(shared_from_this());
            }
        });
}
void CSession::handle_read_header()
{
    auto self(shared_from_this());
    boost::asio::async_read(m_Socket,
        boost::asio::buffer(m_ReadMessage.data(), CMessage::header_length),
        [this, self](boost::system::error_code error, std::size_t /*length*/)
        {
            if (!error && m_ReadMessage.decode_header())
            {
                handle_read_body();
            }
            else
            {
                m_pServer->EndSession(shared_from_this());
            }
        });
}
void CSession::handle_read_body()
{
    auto self(shared_from_this());
    boost::asio::async_read(m_Socket,
        boost::asio::buffer(m_ReadMessage.body(), m_ReadMessage.body_length()),
        [this, self](boost::system::error_code error, std::size_t /*length*/)
        {
            if (!error)
            {
                m_pServer->ProcessPacket(shared_from_this(), m_ReadMessage.body(), m_ReadMessage.body_length());
                handle_read_header();
            }
            else
            {
                if (error == boost::asio::error::eof)
                {
                    std::cout << "클라이언트와 연결이 끊어졌습니다" << std::endl;
                }
                else
                {
                    std::cout << "error No: " << error.value() << " error Message: " << error.message() << std::endl;
                }
                m_pServer->EndSession(shared_from_this());
            }
        });
}
'프로그래밍 언어 > Flatbuffers' 카테고리의 다른 글
| [Network] 9. FlatBuffers + Boost Asio 콘솔 클라이언트 예제 (1) (0) | 2021.07.09 | 
|---|---|
| [Network] 8. FlatBuffers + Boost Asio 콘솔 서버 예제 (4) (0) | 2021.07.08 | 
| [Network] 6. FlatBuffers + Boost Asio 콘솔 서버 예제 (2) (0) | 2021.07.05 | 
| [Network] 5. FlatBuffers + Boost Asio 콘솔 서버 예제 (1) (0) | 2021.07.04 | 
| [Network] 4. Flatbuffers + Boost Asio 콘솔 채팅 서버 클라이언트 예제 (0) | 2021.07.03 |