// ProudNet을 include 합니다.#include “include\ProudNetServer.h”// ProudNet은 모든 객체가 Proud라는 namespace로 묶여 있습니다.usingnamespace Proud;// port 정의int g_ServerPort =33334;
// Proud를 사용하도록 추가usingNettention.Proud;// 미리 사용할 port 정의int serverPort =33334;
3. 서버 시작
먼저 서버 객체를 생성한 후 SetEventSink 함수를 호출합니다. 서버에서 일어나는 이벤트를 콜백받기 위한 객체를 등록하는 과정입니다. INetServerEvent 객체를 상속받아 생성한 객체의 포인터를 넘겨주게 되면 서버는 이 객체를 통하여 이벤트를 콜백합니다.
c++ 11 이후부터는 SetEventSink 대신 람다를 사용한 이벤트 등록이 가능합니다.
// c++ 11 이전 버전만 참고해 주세요.// g_eventSink는 INetServerEvent를 상속받은 객체입니다.CNetServer* srv = Proud::CNetServer::Create();srv->SetEventSink(&g_eventSink);// 서버 시작에 필요한 파라미터 설정합니다.CStartServerParameter p1;// Client 의 Connection을 받을 Portp1.m_tcpPort =33334; srv->Start(p1);
// 특정 이벤트에 람다로 실행할 로직 등록해서 사용이 가능힙니다.srv->OnClientJoin = [...](CNetClientInfo* clientInfo) { // my event handler ...};
usingnamespaceNettention.Proud;// NetServer, StartServerParameter 네임스페이스 생략NetServer netServer =newNetServer();netServer.ClientJoinHandler= (clientInfo) => { // 클라이언트가 서버에 접속했을 때};// 추가 이벤트 등록...StartServerParameter p1 =newStartServerParameter();// protocolVersion을 설정하지 않아도 사용이 가능합니다.p1.protocolVersion="클라이언트와 동일한 protocolVersion";// 위에서 등록한 port 번호 or 직접 입력합니다.p1.tcpPorts.Add(serverPort);netServer.Start(p1);
💡위 코드 예시에서 g_eventSink 가 아래 구조로 생성된 객체입니다.
// CNetServer로부터 이벤트를 받을 객체 생성 방법Class CServerEventSink : public INetServerEvent { // Client의 접속이 완료되면 // Callback됩니다. // CNetClientInfo 객체를 인자로 받습니다. Virtual voidOnClientJoin( CNetClientInfo *info) OVERRIDE { // Client의 정보를 받아 // 처리합니다. } // Client의 접속이 해제되면 // Callback됩니다. Virtual voidOnClientLeave( CNetClientInfo *info) OVERRIDE { // Client의 정보를 받아 // 처리합니다. } // 나머지 Event는 생략}
// C#의 경우 별도의 이벤트 객체 생성없이 이벤트 핸들러를 사용하시면 됩니다.// 클라이언트가 서버에 접속했을 때 실행됩니다.netServer.ClientJoinHandler= (clientInfo) =>{Console.Write("Client {0} connected.\n",clientInfo.hostID);};// 클라이언트 서버 접속이 끊어졌을 때 실행됩니다.netServer.ClientLeaveHandler= (clientInfo, errorInfo, comment) =>{Console.Write("Client {0} disconnected.\n",clientInfo.hostID);};
CNetClientInfo 객체는 접속된 클라이언트 정보를 포함하며, CNetClientInfo의 멤버 m_HostID는 각 호스트를 구분할 수 있는 ID값이 됩니다.
💡C#에 NetClientInfo가 C++의 CNetClientInfo와 같은 역할을 합니다.
4. 연결 해제
함수
설명
Stop
서버 정지. 모든 Connection을 끊습니다.
CloseConnection(Client의 HostID)
해당하는 클라이언트와의 접속을 끊습니다.
5. 클라이언트 연결받기 시작
서버에서 클라이언트 연결을 받기 위해서는 서버 측 리스닝 포트(Listening Port)와 스레드 풀을 준비합니다. 그러기 위해, Server 객체를 생성한 후, Start 메서드를 호출해야 합니다.
// 서버 연결에 필요한 parameter 설정Proud::CNetConnectionParam cp;// 서버와 같은 protocol 버전을 입력해야 한다. 아예 입력하지 않을 수도 있음.cp.m_protocolVersion = g_version;cp.m_closeNoPingPongTcpConnections=false;cp.m_serverIP =_PNT("localhost");cp.m_serverPort =33334;
usingNettention.Proud;// NetConnectionParam 네임스페이스 생략// 서버 연결에 필요한 parameter 설정NetConnectionParam cp =newNetConnectionParam();// 서버와 동일한 protocol version, 입력하지 않아도 됨cp.protocolVersion.Set(version);// server addresscp.serverIP="localhost";// server portcp.serverPort=33334;
3. 시작
// 위 준비 예시에서 만들어 둔 parameter를 사용m_netClinet->Connect(cp);
// 위 준비 예시에서 만들어 둔 parameter를 사용netClient.Connect(cp);
클라이언트에서 서버에 연결하는 동안 발생하는 이벤트
Connect 가 실행되면 서버에는 OnConnectionRequest 가 도착하는데 여기서 연결을 시도하는 클라이언트를 거부할 수 있습니다.
OnConnectionRequest 에서 클라이언트 연결을 수용하면 모든 연결 과정을 마치게 되며, 클라이언트와 서버에서는 아래 코드 예시처럼 이벤트를 받게 됩니다.
// 서버에서m_netServer->OnClientJoin = [](CNetClientInfo*clientInfo){ // Client Join 시 실행할 로직};// 클라이언트에서m_netClient->OnJoinServerComplete = [&](ErrorInfo*info,constByteArray&replyFromServer) { // Server 연결 완료 시 실행할 로직}
// 서버에서netServer.ClientJoinHandler= (clientInfo) => { // Client Join 시 실행할 로직};// 클라이언트에서netClient.JoinServerCompleteHandler= (info, replyFromServer) => { // Server 연결 완료 시 실행할 로직}