6-7 Sending Request And Response And Event With Parameters
本章要來向大家介紹如何在發送請求的時候,將資料也一併傳給Server,Server回應時又該如何回傳資料。另外,除了Request與Response以外,Server還有傳送Event的功能,亦即直接由Server推送消息給Client。
在觀看之前,如果還不知道怎麼跟Photon Server建立連接,請先看以前的文章唷:
6-1 Photon Server By Self-Hosted
再來修改Server的MyClientPeer的OnOperationRequest,藉由operationRequest.Parameters可以取得Client傳來的參數。
重點說明一下,SendEvent是由Server主動推送,所以只要在ClientPeer類別內的任何範圍,都可以直接呼叫並傳送內容給Client。SendOperationResponse,則只能在OnOperationRequest內使用才會有反應。下列範例為了方便才在Response後就呼叫Event,實際上Event是任何時候都可以呼叫,達成主動推送的功能。
傳來的參數亦是一個Dictionary物件,這邊使用TryGetValue方法取得值,因為TryGetValue內部已經實作了判斷Key是否為空的方法,並回傳boolean值,不用自己寫條件式判斷,所以非常方便。
接著在Server端傳回Response時,同樣是用Dictionary。
回到Client端,在OnOperationResponse中取得Parameters即可取得Response資料。
接著在Server實作SendEvent,寫法同樣差不多。
在Client則由OnEvent方法負責接收。
綜合以上所述,在Photon傳送參數皆統一使用Dictionary物件。想起過去自己實作Server的時候,還要自行決定資料傳送的格式如XML、JSON,然後還要將之封裝成方便的方法,想想光前置步驟就耗費不少時間了。Photon提供給我們的方法就非常簡單易用唷!
以下提供Client端原始碼:
PhotonEngine.cs:
PhotonTest.cs:
以下提供Server端原始碼:
NoliahFantasyServer.cs:
MyClientPeer.cs:
撰寫完程式碼以後,來測試看看吧。從Server的Log看見接收到Client的資料了。
Client也接收到Server的Response跟Event。
在觀看之前,如果還不知道怎麼跟Photon Server建立連接,請先看以前的文章唷:
6-1 Photon Server By Self-Hosted
6-2 Create A Photon Server Project And Import Library
6-5 Sending Request And Response
首先,讓我們來修改Client的PhotonTest.cs,使用Dictionary傳遞資料。
再來修改Server的MyClientPeer的OnOperationRequest,藉由operationRequest.Parameters可以取得Client傳來的參數。
重點說明一下,SendEvent是由Server主動推送,所以只要在ClientPeer類別內的任何範圍,都可以直接呼叫並傳送內容給Client。SendOperationResponse,則只能在OnOperationRequest內使用才會有反應。下列範例為了方便才在Response後就呼叫Event,實際上Event是任何時候都可以呼叫,達成主動推送的功能。
傳來的參數亦是一個Dictionary物件,這邊使用TryGetValue方法取得值,因為TryGetValue內部已經實作了判斷Key是否為空的方法,並回傳boolean值,不用自己寫條件式判斷,所以非常方便。
接著在Server端傳回Response時,同樣是用Dictionary。
回到Client端,在OnOperationResponse中取得Parameters即可取得Response資料。
接著在Server實作SendEvent,寫法同樣差不多。
在Client則由OnEvent方法負責接收。
綜合以上所述,在Photon傳送參數皆統一使用Dictionary物件。想起過去自己實作Server的時候,還要自行決定資料傳送的格式如XML、JSON,然後還要將之封裝成方便的方法,想想光前置步驟就耗費不少時間了。Photon提供給我們的方法就非常簡單易用唷!
以下提供Client端原始碼:
PhotonEngine.cs:
using System.Collections; using System.Collections.Generic; using UnityEngine; using ExitGames.Client.Photon; public class PhotonEngine : MonoBehaviour, IPhotonPeerListener { const int SIGNUP = 1; const int BROADCAST = 2; PhotonPeer peer; public static PhotonEngine Instance; void Awake() { if (Instance == null) { Instance = this; } else if (Instance != this) { Destroy (gameObject); return; } } void Start () { // 透過Listener回應伺服器的Response peer = new PhotonPeer (this, ConnectionProtocol.Udp); peer.Connect ("anoneko.cloudapp.net:5055", "NoliahFantasyServer"); } void Update () { // 必須在Update一直呼叫Service方法才能持續連線到Photon peer.Service (); } void OnDestroy(){ if (peer != null && peer.PeerState == PeerStateValue.Connected) { peer.Disconnect (); } } public PhotonPeer GetPeer(){ return peer; } #region IPhotonPeerListener implementation public void DebugReturn (DebugLevel level, string message) { } // 接收由Server端傳回的Response public void OnOperationResponse (OperationResponse operationResponse) { switch (operationResponse.OperationCode) { case SIGNUP: Debug.Log ("收到Server端的Response"); // 收到Server的資料 DictionaryserverData = operationResponse.Parameters; object intValue; serverData.TryGetValue(1, out intValue); object stringValue; serverData.TryGetValue(2, out stringValue); print("Server端資料:" + intValue + "," + stringValue); break; } } public void OnStatusChanged (StatusCode statusCode) { } // 接收由Server端發送的Event事件 public void OnEvent (EventData eventData) { switch (eventData.Code) { case BROADCAST: Debug.Log ("收到Server端的Event"); // 收到Server的資料 Dictionary serverData = eventData.Parameters; object intValue; serverData.TryGetValue(1, out intValue); object stringValue; serverData.TryGetValue(2, out stringValue); print("Server端資料:" + intValue + "," + stringValue); break; } } #endregion }
PhotonTest.cs:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PhotonTest : MonoBehaviour { const int SIGHUP = 1; void Update () { if (Input.GetMouseButtonDown (0)) { SendRequest (); } } void SendRequest(){ Dictionarydata = new Dictionary (); data.Add(1, 654321); data.Add(2, "Client的Request資料"); // 向Server發出Request,SIGNUP為整數型態的操作代碼,data為傳送的資料,true代表建立可靠連接 PhotonEngine.Instance.GetPeer().OpCustom(SIGHUP, data, true); } }
以下提供Server端原始碼:
NoliahFantasyServer.cs:
using System; using System.IO; using Photon.SocketServer; using ExitGames.Logging; using ExitGames.Logging.Log4Net; using log4net.Config; namespace NoliahFantasyServer { public class NoliahFantasyServer : ApplicationBase { public static readonly ILogger logger = LogManager.GetCurrentClassLogger(); public NoliahFantasyServer() { } // 當Client端發出Request的時候 protected override PeerBase CreatePeer(InitRequest initRequest) { return new MyClientPeer(initRequest); } // Server端啟動的時候初始化 protected override void Setup() { LoggerInit(); } // Server端關閉的時候 protected override void TearDown() { } void LoggerInit() { // 日誌初始化 log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(this.ApplicationRootPath, "bin_Win64", "log"); FileInfo loggerConfig = new FileInfo(Path.Combine(this.BinaryPath, "log4net.config")); if (loggerConfig.Exists) { // 設置使用log4net的Log功能 LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance); // 讓log4net讀取config XmlConfigurator.ConfigureAndWatch(loggerConfig); } logger.Info("Setup Log4Net Compeleted!"); } } }
MyClientPeer.cs:
using System; using System.Collections; using System.Collections.Generic; using Photon.SocketServer; using PhotonHostRuntimeInterfaces; namespace NoliahFantasyServer { public class MyClientPeer : ClientPeer { const int SIGNUP = 1; const int BROADCAST = 2; public MyClientPeer(InitRequest initRequest) : base(initRequest) { } // Client端斷開連結的時候 protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail) { } // 處理Client的Request請求 protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters) { switch (operationRequest.OperationCode){ case SIGNUP: NoliahFantasyServer.logger.Info("收到Client端的Request"); // 取得Client端的資料 ProcessData(operationRequest.Parameters); // 發送Response SendResponse(sendParameters); // 發送Event SendMyEvent(sendParameters); break; } } void ProcessData(DictionaryclientData){ object intValue; clientData.TryGetValue(1, out intValue); object stringValue; clientData.TryGetValue(2, out stringValue); NoliahFantasyServer.logger.Info("Client端資料:" + intValue + "," + stringValue); } void SendResponse(SendParameters sendParameters){ // Response物件包含OpercationCode與資料 Dictionary data = new Dictionary (); data.Add(1, 123456); data.Add(2, "Server的Response資料"); OperationResponse response = new OperationResponse(SIGNUP, data); // 發送Response,並沿用Client端的sendParameters屬性 SendOperationResponse(response, sendParameters); } void SendMyEvent(SendParameters sendParameters){ Dictionary data = new Dictionary (); data.Add(1, 333333); data.Add(2, "Server的Event資料"); EventData eventData = new EventData(BROADCAST, data); SendEvent(eventData, sendParameters); } } }
撰寫完程式碼以後,來測試看看吧。從Server的Log看見接收到Client的資料了。
Client也接收到Server的Response跟Event。
留言
張貼留言