Sample 예제
아래 예제는 git 샘플 프로젝트를 기반으로 만들어졌습니다. 자세한 내용은 아래의 링크를 참고해 주세요.
클라이언트
- Proxy & Stub
// 클라이언트 -> 서버 RMI Proxy 인스턴스
Simple::Proxy g_SimpleProxy;
// RMI proxy와는 다르게 함수 오버라이딩 후 사용한다.
class SimpleStub : public Simple::Stub
{
public:
DECRMI_Simple_ShowChat;
DECRMI_Simple_SystemChat;
DECRMI_Simple_P2PChat;
};
// 메세지를 받기 위한 RMI stub 인스턴스
SimpleStub g_SimpleStub;
- RMI 함수 정의
RMI 함수는 쉬운 네이밍을 위해 다음과 같은 규칙을 사용합니다.
=> DEFRMI_GlobalName_FunctionName
DEFRMI_Simple_P2PChat(SimpleStub)
{
...
// 따로 의미는 없으나 반드시 true를 리턴해주어야 함.
return true;
}
DEFRMI_Simple_ShowChat(SimpleStub)
{
...
return true;
}
DEFRMI_Simple_SystemChat(SimpleStub)
{
...
return true;
}
- NetClient 객체 생성
std::shared_ptr<Proud::CNetClient> netClient(Proud::CNetClient::Create());
- 이벤트 연결
서버 연결 이벤트에서 필요한 로직을 설계하신 후 사용하시면 됩니다.
// 서버 연결이 완료된 후 호출되는 이벤트
netClient->OnJoinServerComplete =
[&](ErrorInfo *info, const ByteArray &replyFromServer)
{
...
}
// 서버 연결이 끊어졌을 때 실행할 이벤트
netClient->OnLeaveServer = [&](ErrorInfo *errorInfo)
{
...
}
// 새로운 p2p 연결이 들어왔을 때 실행될 이벤트
// memberHostID : p2p 연결된 클라이언트 아이디
// groupHostID : p2p 연결된 그룹 아이디
netClient->OnP2PMemberJoin =
[&](HostID memberHostID, HostID groupHostID,int memberCount, const ByteArray &customField)
{
...
}
// p2p 연결이 끊겼을 때 실행될 이벤트
netClient->OnP2PMemberLeave =
[](HostID memberHostID, HostID groupHostID,int memberCount)
{
...
}
- Proxy & Stub 등록
// CNetClient에 유저가 만든 Proxy와 Stub을 등록한다
netClient->AttachProxy(&g_SimpleProxy);
netClient->AttachStub(&g_SimpleStub);
- 서버 연결
// 서버 시작에 필요한 Parameter 설정하기
Proud::CNetConnectionParam cp;
// 서버와 같은 protocol 버전을 입력해야 한다. 아예 입력하지 않을 수도 있음.
cp.m_protocolVersion = g_Version;
cp.m_closeNoPingPongTcpConnections = false;
cp.m_serverPort = g_ServerPort;
// 서버와 연결 시작
// 이 함수는 즉시 return 됩니다.
// 그동안 백그라운드에서 연결을 시도하고,
// 결과는 OnJoinServerComplete 이벤트에 의해서 알려집니다.
netClient->Connect(cp);
이후 매 프레임 호출이 되는 함수에서 netClient -> FrameMove()를 호출합니다.
// 예시
while (true)
{
netClient->FrameMove();
}
기본적으로 FrameMove를 진행해주셔야 이벤트가 발생합니다.
서버
- Proxy & Stub
// 서버에서 클라이언트로 전송을 위한 RMI Proxy
Simple::Proxy g_SimpleProxy;
// RMI proxy와는 다르게 함수 오버라이딩 후 사용한다.
class SimpleStub : public Simple::Stub
{
public:
DECRMI_Simple_Chat;
};
// 서버 -> 클라이언트 RMI Stub 인스턴스
SimpleStub g_SimpleStub;
- RMI 함수 정의
DEFRMI_Simple_Chat(SimpleStub)
{
...
return true;
}
- NetServer 객체 생성
std::shared_ptr<Proud::CNetServer> srv(Proud::CNetServer::Create());
- 이벤트 연결
// 클라이언트가 서버에 접속했을 때 실행할 로직을 설정한다.
srv->OnClientJoin =
[](CNetClientInfo* clientInfo, ErrorInfo* errorInfo, const ByteArray& comment)
{
...
};
// 클라이언트 서버 접속이 끊어졌을 때 실행할 로직을 설정한다.
srv->OnClientLeave =
[](CNetClientInfo *clientInfo, ErrorInfo *errorInfo, const ByteArray& comment)
{
...
};
- Proxy & Stub 등록
// 생성된 CNetServer 인스턴스에 proxy와 stub을 등록한다.
srv->AttachStub(&g_SimpleStub);
srv->AttachProxy(&g_SimpleProxy);
서버 시작
Proud::CStartServerParameter p1;
// This must be the same to the client. => 클라이언트와 같아야 함.
p1.m_protocolVersion = g_Version;
// TCP listening endpoint => tcp 연결 들어오는 port
p1.m_tcpPorts.Add(g_ServerPort);
/* 서버 시작
이 함수는 실패시 exception을 발생시킨다.
특별히 threading model을 구체화하지 않는다면
메시지 송신에 의한 RMI 함수와 이벤트 콜백은 나눠진 thread pool에서 호출된다.
thread model을 따로 지정할 수 있는데 해당 부분은 도움말을 참고하면 된다. https://guide.nettention.com/cpp_ko#thread_pool_sharing
*/
srv->Start(p1);
공통
- vars.h
extern Proud::Guid g_Version;
extern int g_ServerPort;
- vars.cpp, vars.cs
// 정의한 프로토콜 버전
// 서버와 클라이언트가 모두 동일한 값을 가져야 한다.
PNGUID guid = { 0x3ae33249, 0xecc6, 0x4980, { 0xbc, 0x5d, 0x7b, 0xa, 0x99, 0x9c, 0x7, 0x39 } };
Guid g_Version = Guid(guid);
// TCP listening port number.
int g_ServerPort = 33334;
Last updated
Was this helpful?