Photon Server Plugin — WebHooks(2)
이곳에서 소개하는 WebHooks는 Photon Plugins를 통한 방식을 가리키며, 외부나 제3자와의 서버 플랫폼은 WebServices 유형의 서비스처럼 Http Post 방식을 이용해 연결 소통합니다. 주요 목적은 사용자의 재가입 허용 및 사용자/게임 데이터 기록 등과 같은 게임/룸 기능을 쉽게 확장하는 데 있습니다.
이전 파트 부분은 Photon Server 및 Http 서버 간의 모든 설정에 속합니다. 계속해서 클라이언트 내 구현 부분의 연결 작동 방법에 대해 알아보겠습니다!
클라이언트 코드 — WebRPC
Unity PUN / Photon Realtime에서 직접 WebRPC로 Photon Server 상의 WebHook 기능을 호출할 수 있습니다. 매개 변수 설정 내 method 명칭을 자체적으로 가져올 수 있어 호출할 서비스 경로를 지정하는 것과 같습니다.
매번 PhotonNetwork.WebRpc를 실행할 때마다, Photon Server에서 수신한 후, method를 상응하는 경로로 전환해주고, Photon Server 설정 파일에 미리 정의해둔 BaseURL에 맞춰 외부에 일회성 웹서버 Http POST 조건을 생성합니다.
using System.Collections.Generic;
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add ("name", "Steven Hu");
parameters.Add ("age", "28");
PhotonNetwork.WebRpc ("webhook", parameters);
위와 같이, 우리는 string:object Dictionary 유형의 객체를 매개 변수로 삼아 Photon Server로 전달해 Photon Server에서 해당 자체 보유 데이터를 함께 다시 HTTP 서버로 전달해 처리하게 할 수 있습니다.
클라이언트 코드 — Unity PUN
앞장의 시리즈 문서와 같이, 우리 Unity 에는 두 개 장면이 있는데, 하나는 마스터 서버 연결 용이고, 또 다른 하나는 게임 내 점수 송출용 입니다. 첫 장면은 우리에게도 동일한 PUN 관리 PhotonManager가 있고, 게임 서버 와의 연결 성공 후 제2 장면이 로딩되니, 우선 LeaderboardRoom 부터 호출하면 됩니다.프로그램 코드 프로세스는 다음과 같습니다:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PhotonManager : Photon.PunBehaviour {
public static PhotonManager instance;
//로컬 사용자
public static GameObject localPlayer;
// 캐릭터 진입 지점
GameObject defaultSpawnPoint;
void Awake()
{
if (instance ! = null)
{
DestroyImmediate(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
instance = this;
//PUN의 맵 로딩 자동 동기화를 사용할 수 있고, 맵 로딩 초기화 시 발생할 수 있는 네트워크 문제를 피할 수 있습니다.
PhotonNetwork.automaticallySyncScene = true;
}
void Start () {
Connect();
// InvokeRepeating("UpdateStatus", 2, 1);
}
void Connect() {
//Photon Cloud/Server와의 연결 시작 시 게임 버전은 문자열 모드로 설정
PhotonNetwork.ConnectUsingSettings("PUN_PhotonWebhook_1.2");
}
void UpdateStatus() {
string status = PhotonNetwork.connectionStateDetailed.ToString();
Debug.Log(status);
}
public void JoinGameRoom()
{
//게임룸과 명칭 설정 시 사용자 인원수 최대 2명
RoomOptions options = new RoomOptions();
options.MaxPlayers = 2;
PhotonNetwork.JoinOrCreateRoom("RoomPlugins", options, TypedLobby.Default);
}
public override void OnConnectedToMaster ()
{
//마스터 서버에 연결 후, 버튼(UI)으로 기타 후속 동작을 표시하거나 실행할 수 있습니다.
Debug.Log("Master Server에 접속했습니다");
}
public override void OnJoinedRoom()
{
Debug.Log("룸에 진입했습니다");
//마스터 클라이언트일 경우, 즉시 구축 및 초기화하고 게임 화면 로딩 가능
if (PhotonNetwork.isMasterClient)
{
PhotonNetwork.LoadLevel("LeaderboardRoom");
}
}
//게임 화면 로딩
void OnLevelWasLoaded(int levelNumber)
{
if (!PhotonNetwork.inRoom) return;
Debug.Log("게임 화면 로딩/게임룸내")
}
public override void OnPhotonPlayerConnected(PhotonPlayer newPlayer)
{
Debug.Log("Other Player Entered." );
}
}
LeaderboardRoom.scene에서 바로 간단하게 버튼을 통해 WebRPC를 송출하면 되기 때문에 DoSubmitScore 기록으로 사용자 이름과 점수를 획득하고 우리가 기록해 넣은 버튼(랭킹 작성)과 함께 사용합니다. 화면은 다음과 같습니다.
SubmitButton 에서 Name&Score을 WebRPC 방식으로 송출
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using ExitGames.Client.Photon;
public class SubmitObject : Photon.PunBehaviour {
public void DoSubmitScore() {
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add ("name", "Steven Hu");
parameters.Add ("score", "100");
PhotonNetwork.WebRpc ("webhook1", parameters);
}
void OnWebRpcResponse(OperationResponse operationResponse) {
if (operationResponse.ReturnCode ! = 0) {
Debug.Log("WebRPC 작동실패. Response: " + operationResponse.ToStringFull());
return;
}
WebRpcResponse webRpcResponse = new WebRpcResponse (operationResponse);
if (webRpcResponse.ReturnCode ! = 0)
{
Debug.Log("WebRPC '" + webRpcResponse.Name + "문제발생. Error: " + webRpcResponse.ReturnCode + " Message: " + webRpcResponse.DebugMessage);
return;
}
Dictionary<string, object> parameters = webRpcResponse.Parameters;
//랭킹, 정보 등 같은 매개 변수값 나열
foreach (KeyValuePair<string, object> pair in parameters) {
Debug.Log(string.Format("KEY {0} / VALUE: {1}", pair.Key, pair.Value));
}
}
}
우리가 PhotonNetwork.WebRpc 호출 시, 첫 번째 매개 변수 webhook가 바로 우리가 설정한 webservice 내 한 경로이며, 두 번째 매개 변수는 JSON 객체 형식으로 내보낼 수 있습니다. 따라서 우리는 획득한 이름과 점수를 두 번째 매개 변수로 송출하는 것이 좋습니다.
WebRPC 호출 후, Photon Server에서 일부 데이터 및 정보를 우리 클라이언트로 리턴해주고, PUN 에서는 OnWebRpcResponse를 호출하기 시작합니다. 우리가 내부에서 ReturnCode가 0인지를 조회해 봤을 때 아니라면 문제가 있다는 것으로… WebHook 설정 파일을 정확하게 설정하지 못했거나, enable로 설정하지 않았거나, WebService 자체 경로 사이트 오류 등등의 원인이 있을 수도 있습니다. 따라서 이러한 절차에 유의해야 합니다!
ReturnCode가 0이라면 좋습니다! 그다음 우리는 다른 데이터 반환 문제를 처리할 수 있습니다. 랭킹, 사용자 이름, 기타 자체 지정 정보 등 모두 JSON 객체로 반환됩니다!
운용
마찬가지로, 우리 서버에서 Photon Control을 실행시켜 Photon Server를 작동시키고 LoadBalancing은 애플리케이션 방식으로 실행합니다. 잘 이해가 되지 않는 곳이 있으면 이전 문서를 참고해주세요!
정상적인 설정 후 실행을 하고 나면 게임 서버 로그를 호출해 보면 우리의 webhook도 초기화되었음을 확인할 수 있습니다.
보여지는 화면:
WebHooks 플러그인의 초기화된 화면
우리 클라이언트를 Photon Server / 마스터 서버에 연결하면, 게임 서버에 생성한 게임 룸으로 진입할 수 있기 때문에, LeaderboardRoom 화면이 로딩되고 나면, 이름과 점수를 자체적으로 입력 후, "랭킹 입력하기" 버튼을 클릭할 수 있습니다. 이렇게 클라이언트 - Photon Server - WebServices - Photon Server - 클라이언트 까지 전송 프로세스가 만들어집니다.
이 과정에서 어쩌면 적지 않은 문제가 발생할 수도 있습니다. 이때 우리는 각각의 연결 부분에서 문제 발생 지점을 찾아볼 수 있습니다. webscript.io에서 수신한 HTTP Post Request를 조회할 수 있는 것과 같아 아래 그림처럼 보여야 합니다:
webscript.io에 기록한 랭킹 루프백은 아래 데이터처럼 우리 Photon Server로 반환하게 됩니다:
만약 모든 조작과 설정이 제대로 적용되었다면, 아래와 같은 로그가 송출됩니다. 여러 번 입력하고 나면, 서버에서 반환해 온 데이터에서, 랭킹 10위 내 정보를 확인할 수 있습니다. 이는 바로 우리 조작이 성공했음을 의미합니다! 😃
클라이언트의 점수 송출 후, 랭킹 10위 내 사용자 이름과 점수를 포함한 데이터 반환을 수신하게 됩니다.
요약
우리는 제2장 강의에서 Webhook의 플러그인 방식을 제대로 이해하도록 돕기 위해 간단하게 webservice 랭킹 데이터만 액세스했으나, 그것은 이러한 플러그인 방식에서 Photon Server 내부 데이터 엑세스는 물론, 서버 외부의 데이터베이스, 클라우드 컴퓨팅, WebService와 통신할 수 있다는 것을 의미하기도 합니다. 🎯
현재 제3자 Google Cloud Platform, AWS, Microsoft Azure 등과 같은 강력한 서버 플랫폼이 존재합니다. 이러한 대형 플랫폼을 통해 신속하게 대량의 데이터를 처리한 후 다시 반환해 표시한다면, 게임 구조를 쉽게 설계할 수 있고 기계 처리 비용을 절약할 수 있습니다. 그리고, 무엇보다도 클라이언트 쪽에서 우리의 처리 방법을 알 필요도 없기 때문에 우리가 데이터를 신속하고 안전하게 처리할 수 있습니다!
여러분, 어때요? 좋은 아이디어가 구상되지 않나요?
모든 궁금한 문제나 의견이 있을 경우, https://www.facebook.com/photoncloudkr/ 으로 메시지를 주시거나,
developer@photonengine.kr로 메일 주세요!
댓글
댓글 0개
댓글을 남기려면 로그인하세요.