8.분산로비시스템 예제 프로그램

분산로비시스템 예제 프로그램은 예제 온라인 게임 프로그램입니다..

특징

분산로비시스템 예제 프로그램은

분산로비시스템 예제 프로그램 의 실행 방법은 캐주얼 게임 샘플2 사용법 에 설명되어 있습니다.

분산로비시스템 예제 프로그램 의 서버 구성에 대해서는 캐주얼 게임 샘플2 프로그램의 서버 분산 를 참고하십시오.

분산로비시스템 예제 프로그램은 소스 코드의 양이 많은 편입니다. (주석 포함해서 약 8000라인) 그렇기 때문에 이해를 돕기 위해 샘플 소스 코드에 대한 API 리퍼런스를 참고하시는 것이 좋습니다.

• 본 샘플 프로그램의 API 리퍼런스는 Casual Game Sample 도움말을 참조 부탁드립니다.

• 물론, 분산로비시스템 예제 프로그램 이해에 필요한 것이 있으면 Part XIV. Nettention 기술 지원에 문의하셔도 됩니다.

분산로비시스템 예제 프로그램 에서의 캐주얼 게임 시스템이 개발하려는 게임에서의 시스템과 비슷하지 않을 경우를 대비해서, 분산로비시스템 예제 프로그램 는 참고 용도로만 사용하고 실제 캐주얼 게임 개발에서는

분산로비시스템 예제 프로그램 와 별개로 새로 제작하는 것이 괜찮은 선택입니다.

물론, 분산로비시스템 예제 프로그램 을 수정해서 캐주얼 게임 개발에 사용하는 것도 가능합니다. 하지만 이렇게 될 경우 ProudNet의 지속적 업데이트를 받을 때마다 업데이트 내역을 매번 찾아야 하는 번거로운 일이 발생할 것입니다. 따라서 Source Control의 Branch 기능을 활용하는 것을 권장합니다.

분산로비시스템 예제 프로그램 에서 보여주는 기능 구현은 다음과 같습니다.

8.1캐주얼 게임 샘플2 사용법

먼저, 샘플 데이터베이스 구축하기를 하십시오.

그 다음, 서버 프로그램을 실행해야 합니다.

m_dbmsConnectionString = L"Data Source=localhost;Database=ProudDB2-Test;Trusted_Connection=yes";

참고로 Mysql을 사용하시는 분들은 Sample에 SimpleAdoMysql예제를 참조하시면 됩니다.

이제, 클라이언트 프로그램을 실행하도록 합시다.

실행 후에는 새 플레이어 캐릭터를 만들거나 구 플레이어 캐릭터를 제거할 수 있으며, 캐릭터를 선택한 후 [확인]을 누르면 로비 채널을 선택하는 화면이 나옵니다.

로비 채널을 선택한 후에는 로비 화면이 나타납니다. 로비 화면에서는 전체 채팅과 방 만들기, 방 들어가기 혹은 전 화면으로 돌아가기를 할 수 있습니다.

방을 만든 후에는 게임방 대기실에 들어가게 되며, 게임방 대기실에서는 다른 게이머의 진입을 기다리거나 게임 시작을 결정할 수 있습니다. 게임 시작을 위해서는 게임방에 들어온 다른 게이머(방돌이) 들이 전원 [준비!] 버튼을 눌러서 게임 시작에 동의함을 체크해야 합니다.

본 샘플 프로그램의 조작법은 간단합니다. 방향키와 스페이스키로 자신의 캐릭을 조절할수 있으며 화면에 움직이는 총알들을 피하면서 Item을 먹는 단순 게임입니다. 파란색bullet은 아래서 빨간색 bulletd은 위로 지나 다닙니다. 스페이스 키를 이용해 적절히 피해주시면 됩니다. 캐릭의 점수가 0이되면 로비로 추방되며 점수는 10점으로 다시 초기화됩니다.

각 플레이어 캐릭터가 가진 점수는 실제 게이머 데이터베이스에 저장이 됩니다. 그리고 그 점수는 게임 화면에 나타나는 플레이어 캐릭터 이름 옆의 [ ] 칸 안에 표시됩니다.

8.2캐주얼 게임 샘플2 프로그램의 서버 분산

분산로비시스템 예제 프로그램 의 서버는 실제 상용화하는 캐주얼 게임의 scalability를 고려해서 신중하게 설계되어 있습니다. 그 결과 다음과 같이 분산되어 있습니다.

그림 8-1캐주얼 게임 샘플2의 서버 구성도

8.3게임 서버간의 서버-클라이언트 관계

분산로비시스템 예제 프로그램 에서는 각 게임 서버들끼리 기능별로 분산되어 서버간 통신을 수행합니다. 자세한 것은 캐주얼 게임 샘플2 프로그램의 서버 분산을 참고하십시오.

팜 클라이언트는 시작하면 팜 서버에 접속을 시도합니다.

•CFarmClient.Connect

•CFarmServer.OnClientJoin

•CFarmClient.OnJoinServerComplete

팜 서버로의 접속이 성공하면 팜 클라이언트는 팜 서버로의 인증 절차를 시작합니다.

•CFarmServer.RequestFarmLogon

•CFarmClient.NotifyFarmLogonSuccess

팜 서버와의 인증 절차가 성공적으로 끝나면 팜 클라이언트는 팜 서버와의 연결이 종료할 때까지 기다립니다.

•CFarmClient.OnLeaveServer

•CFarmServer.OnClientLeave

팜 클라이언트끼리는 서로가 P2P 통신이 엮여 있습니다. 따라서 팜 클라이언트끼리의 통신, 예를 들어 로비 서버와 배틀 서버간의 통신은 지속적으로 일어날 수 있습니다.

8.4Entry 서버와 클라이언트

분산로비시스템 예제 프로그램 의 게임 클라이언트가 처음 실행되면 entry client를 생성합니다. 그리고 entry client는 entry server에 접속합니다.

•CEntryClient::Connect

•CEntryClient::OnJoinServerComplete

접속 과정이 완료되면 entry client는 entry server에게 회원가입을 요청하거나 기존에 가입한 게이머ID와Password를 암호화된 메시지로 전송하여 로그인을 할수 있습니다. entry server는 받은 정보를 기반으로 ProudDB cache server에 보내서 정보로딩 및 게이머 인증을 요청합니다.

회원가입후 로그인하는 경우

•CEntryServer::RequestLoadNewGamer

•CEntryClient::NotifyLoadNewGamerSuccess

•CEntryServer::RequestFirstLogon

•CEntryClient::NotifyFirstLogonSuccess

기존에 가입한 아이디로 로그인하는 경우

•CEntryServer::RequestFirstLogon

•CEntryClient::NotifyFirstLogonSuccess

게이머 인증 및 정보 로딩이 성공하면 게임 클라이언트는 캐릭터 선택 폼으로 전환합니다. 그리고 entry server에게 로컬 플레이어 캐릭터 리스트를 요청 후 받습니다.

•CEntryServer::RequestHeroSlots

•CEntryClient::Hero_Begin

•CEntryClient::Hero_Add

•CEntryClient::Hero_End

게이머는 여기에서 로컬 플레이어 캐릭터를 생성하거나, 제거할 수 있습니다. 그리고 사용할

플레이어 캐릭터를 선택합니다. 그러면 entry server는 선택한 캐릭터 정보를 받아서 게이머 데이터베이스에 저장합니다.

•CEntryServer::RequestAddHero

•CEntryClient::NotifyAddHeroSuccess

•CEntryServer::RequestRemoveHero

•CEntryServer::NotifyRemoveHeroSuccess

•CEntryServer::RequestSelectHero

•CEntryServer::NotifySelectHeroSuccess

그리고 entry client는 서버에 요청해서 로비 채널 목록을 받습니다. entry server부터 받은 로비 채널 목록에는 각 로비 서버의 이름, 동시접속자수 및 로비 서버의 인터넷 주소를 받습니다. 게임 클라이언트는 게이머에게 목록을 보여주고, 게이머는 목록 중 하나를 선택할 수 있습니다.

•CEntryServer::RequestLobbyList

•CEntryClient::LobbyList_Begin

•CEntryClient::LobbyList_Add

•CEntryClient::LobbyList_End

이 과정에서 팜클라이언트(여기서는 로비서버)가 팜서버로 독점권을 요청하게 됩니다. entry client는 서버와의 연결을 끊고 제거됩니다. 게임 클라이언트는 로비 클라이언트를 준비한 후 로비서버로의 연결을 시작합니다. 로비 서버와 클라이언트 을 참고하십시오. 타 클라이언트에서 독점권 요청시 발생할수 있는 문제점 하나는 동일한 ID와 Password로 접속시 다른 entry client의 DBCache Client가 독점권을 요청하게 될때입니다. 이때는 이후 과정은 OnDataUnloadRequested 콜백시 넘어오는 파라미터내의 customfield로 구분하여 동시접속을 방지하게 됩니다. casual game sample2에서는 이러한 상황시 기존접속되어있던 팜클라이언트의 연결을 끊고 새로 독점권을 요청한 팜클라이언트에게 독점권을 넘겨주도록 구현 되어 있습니다.

8.5로비 서버와 클라이언트

Entry 서버와 클라이언트 에 의해 로비 클라이언트가 로비 서버와의 연결을 시작한 후 연결이 성공하면 게임 클라이언트는 로비 폼을 보여줍니다.

•CLobbyClient.Connect

•CLobbyServer.OnClientJoin

•CLobbyClient.OnJoinServerComplete

•CLobbyServer.RequestNextLogon

•CLobbyClient.NotifyNextLogonSuccess

로비폼을 위한 데이터 로딩이 완료된 후 로비 폼을 화면이 성공적으로 전환되면, 로비 내의 모든 플레이어 리스트와, 전체 채팅 창, 그리고 게임방 리스트가 나타납니다.

•CLobbyServer.NotifyChannelFormReady

로비 내의 모든 플레이어 리스트는 수시로 증가,수정,제거될 수 있습니다. 이러한 변경 정보는 지속적으로 로비 서버로부터 받게 됩니다.

•CLobbyClient.HeroSlot_Appear

•CLobbyClient.HeroSlot_Disappear

로비 내의 게임방 리스트는 수시로 증가, 수정, 제거될 수 있습니다. 이러한 변경 정보는 지속적으로 로비 서버로부터 받게 됩니다.

•CLobbyClient.GameRoom_Appear

•CLobbyClient.GameRoom_ShowState

•CLobbyClient.GameRoom_Disappear

실제 게임방은 배틀 서버에 존재합니다. 로비 서버는 배틀 서버로부터 동기화받은 게임방 리스트를 로비 클라이언트들에게 보내줄 뿐입니다.

•CFarmClient.GameRoom_Appear

•CLobbyServer.OnGameRoomAppear

•CFarmClient.GameRoom_ShowState

•CLobbyServer.OnGameRoomShowState

•CFarmClient.GameRoom_Disappear

•CLobbyServer.OnGameRoomDisappear

로비 클라이언트에서 채팅 메시지를 로비 서버에 보내면 로비 서버는 접속되어 있는 로비 클라이언트들에게 채팅 메시지를 멀티캐스트 합니다. 그리고 각 로비 클라이언트가 받은 채팅 메시지는 전체 채팅 창에 표시됩니다.

•CLobbyServer.Chat

•CLobbyClient.ShowChat

게임방 만들기

그림 8-2게임방 만들기 Sequence Diagram

게이머가 게임방 만들기를 요청하면 로비 서버에 요청이 전달됩니다. 그러면 로비 서버는 로비 서버에 종속되어 있는 각 배틀 서버의 리스트 중 가장 접속자가 적은 배틀 서버를 찾은 후 그 배틀 서버에게 게임방 생성을 요청합니다.

•CLobbyServer.RequestCreateGameRoom

•CFarmClient.RequestCreateGameRoom

•CBattleServer.CreateGameRoomByLobbyServer

배틀 서버는 게임방 생성 요청을 받아 처리한 후 결과를 로비 서버에게 보내줍니다. 로비서버는 이 정보를 받아 로비 클라이언트에게 보내줍니다.

•CFarmClient.NotifyCreateGameRoomResult

•CLobbyServer.OnCreateGameRoomResult

•CLobbyClient.NotifyCreateRoomSuccess

게임방 들어가기

그림 8-3게임방 들어가기 Sequence Diagram

이미 개설된 게임방 중 하나를 선택해서 들어가기를 요청하는 경우 로비 클라이언트는 요청 메시지를 로비 서버에 전송합니다. 로비 서버는 이를 받아 그 게임방을 관장하는 배틀 서버에게 진입 허가 요청을 보냅니다.

•CLobbyServer.RequestJoinGameRoom

•CFarmClient.RequestJoinGameRoom

배틀 서버는 진입 허가 요청을 받아 게임방의 진입 조건의 허락을 판단한 후 로비 서버에게 그 결과를 보냅니다. 로비 서버는 결과를 받은 후 로비 클라이언트에게 성공 또는 실패 여부를 전달합니다.

•CBattleServer.JoinGameRoomByLobbyServer

•CFarmClient.NotifyJoinGameRoomResult

•CLobbyClient.NotifyJoinRoomSuccess

로비 클라이언트가 게임방 생성 결과 혹은 게임방 진입 결과를 받되, 그것이 성공했음을 의미할 경우 게임방이 존재하는 배틀 서버의 주소 및 게임방의 guid를 받게 됩니다. 이 때 로비 클라이언트는 종료하며 배틀 클라이언트가 만들어진 후 배틀 서버로 접속하기 시작합니다. 이 과정은 battle_session2에 설명되어 있습니다. 이 과정에서도 타 팜클라이언트의 DBcache client의 독점권 요청시 문제가 될수 있는 상황이 있습니다. 동일한 ID와 password로 로그인할 때 새로운 entry client의 DBcache client가 독점권 요청이 발생하게 됩니다. 이때도 entry server에서 lobby server로 이동할 때 발생할 때 독점권 요청 루틴 처리 과정처럼 전의 연결을 끊고 새로운 연결을 시도한 팜 클라이언트에게 독점권을 넘겨줌으로써 중복접속을 방지합니다.

8.6배틀 서버와 클라이언트

로비 서버와 클라이언트 과정이 끝나고 배틀 서버로 접속을 시작한 배틀 클라이언트는 배틀 서버와의 연결이 성공할 때까지 기다립니다.

•CBattleClient.Connect

•CBattleServer.OnClientJoin

•CBattleClient.OnJoinServerComplete

연결이 성공하면 배틀 서버로의 로그온 절차를 진행합니다. 이때 진입할 게임방 정보를 같이 입력합니다. 즉, 로그온 과정에서 이미 생성된 게임방으로의 진입 절차도 같이 시행됩니다.

•CBattleServer.RequestNextLogon

•CBattleClient.NotifyNextLogonSuccess

배틀 서버로의 로그온(그리고 게임방 진입)이 성공하면 게임 클라이언트는 게임방 대기실 폼을 표시합니다. 게임방 대기실 폼을 위해 게임방 내의 게이머 리스트와 게임방 정보를 받습니다.

•CBattleClient.NotifyGameRoomInfo

•CBattleClient.HeroSlot_Appear

•CBattleClient.HeroSlot_Disappear

•CBattleClient.HeroSlot_ShowState

만약 로컬 플레이어가 방장이라면 게임 시작을 요청할 수 있습니다.

•CBattleServer.RequestStartPlayMode

방장이 아닌 경우(즉 방돌이)에는 게임 플레이를 시작할 수 있음에 동의하는 표시, 즉 'READY를 찍기'를 할 수 있습니다.

•CBattleServer.RequestToggleBattleReady

방돌이들이 전원 READY를 찍은 상태에서 방장이 게임 시작을 요청하면 게임이 본격적으로 시작될 수 있습니다. 하지만 게임 시작을 위해서는 각 게임 클라이언트가 플레이를 위한 데이터 파일 로딩이 모두 끝나야지만 시작할 수 있으며, 그때까지는 각 게이머들은 게임 플레이 시작을 대기하고 있어야 합니다.

•CBattleClient.GotoLoadingMode

•CBattleServer.NotifyLoadFinished

•CBattleClient.GotoPlayMode

게임 플레이를 하는 동안 플레이어 캐릭터의 점수 등이 변경되며, 이들은 DB 서버에 저장될 필요가 있을 것입니다. 본 샘플에서는 게임 플레이를 하는 동안 게이머가 자기의 점수를 쉽게 획득할 수 있게 만들어져 있습니다. 획득한 점수는 DB에 저장됩니다.

•CBattleServer.RequestGainScore

실제 게임 플레이를 하다가 중도 이탈하는 게이머는 접속을 끊고 로비 서버로 접속하는 과정으로 복귀하면 됩니다. 한편, 게임 플레이가 끝나면(예: 미션 클리어) 게임방은 대기실 모드로 전환하고, 각 게이머들은 게임방 대기실 화면으로 전환해야 합니다. 본 샘플 프로그램에서는 학습의 이해를 위해 게이머가 임의로 무조건 미션 클리어를 수행할 수 있도록 만들어져 있습니다. 여기서도 마찬가지로 다른 entry client의 DBcache client가 독점권 요청시 기존의 연결을 끊고 독점권을 넘겨주게 됩니다.

•CBattleServer.RequestMissionClear

•CBattleServer.GameRoom_GotoWaitingMode

•CBattleClient.GotoWaitingMode