// Session 내부에서 OnRecv, OnSend를 받게해보자
class GameSession : public Session
{
public:
virtual int32 OnRecv(BYTE* buffer, int32 len) override
{
// Echo
cout << "OnRecv Len = " << len << endl;
Send(buffer, len);
return len;
}
virtual void OnSend(int32 len) override
{
cout << "OnSend Len = " << len << endl;
}
};
// 이건 간단하게 처리되고
void Session::ProcessRecv(int32 numOfBytes)
{
_recvEvent.owner = nullptr; // RELEASE_REF
if (numOfBytes == 0)
{
Disconnect(L"Recv 0");
return;
}
// 컨텐츠 코드에서 오버로딩
OnRecv(_recvBuffer, numOfBytes);
// 수신 등록
RegisterRecv();
}
void Session::ProcessSend(SendEvent* sendEvent, int32 numOfBytes)
{
sendEvent->owner = nullptr; // RELEASE_REF
xdelete(sendEvent);
if (numOfBytes == 0)
{
Disconnect(L"Send 0");
return;
}
// 컨텐츠 코드에서 오버로딩
OnSend(numOfBytes);
}
Send처리를 어떻게 할 것인가
class GameSession : public Session
{
public:
virtual int32 OnRecv(BYTE* buffer, int32 len) override
{
// Echo
cout << "OnRecv Len = " << len << endl;
// 받은 데이터를 그대로 Send
Send(buffer, len);
return len;
}
// ...
void Session::Send(BYTE* buffer, int32 len)
{
// 생각할 문제
// 1) 버퍼 관리?
// 2) sendEvent 관리? 단일? 여러개? WSASend 중첩?
// TEMP
SendEvent* sendEvent = xnew<SendEvent>();
sendEvent->owner = shared_from_this(); // ADD_REF
sendEvent->buffer.resize(len);
::memcpy(sendEvent->buffer.data(), buffer, len);
WRITE_LOCK;
RegisterSend(sendEvent);
}
void Session::RegisterSend(SendEvent* sendEvent)
{
if (IsConnected() == false)
return;
WSABUF wsaBuf;
wsaBuf.buf = (char*)sendEvent->buffer.data();
wsaBuf.len = (ULONG)sendEvent->buffer.size();
DWORD numOfBytes = 0;
if (SOCKET_ERROR == ::WSASend(_socket, &wsaBuf, 1, OUT &numOfBytes, 0, sendEvent, nullptr))
{
int32 errorCode = ::WSAGetLastError();
if (errorCode != WSA_IO_PENDING)
{
HandleError(errorCode);
sendEvent->owner = nullptr; // RELEASE_REF
xdelete(sendEvent);
}
}
}
void Session::ProcessSend(SendEvent* sendEvent, int32 numOfBytes)
{
sendEvent->owner = nullptr; // RELEASE_REF
xdelete(sendEvent);
if (numOfBytes == 0)
{
Disconnect(L"Send 0");
return;
}
// 컨텐츠 코드에서 오버로딩
OnSend(numOfBytes);
}