天天看點

Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分

前言

上篇我們學習了Unity用戶端如何和Photon伺服器建立連接配接,這篇是如何與伺服器進行資料的互動。

慣例,基于上篇的伺服器項目MyGameServer,Unity用戶端項目進行進一步的學習。

用戶端與伺服器互動流程圖解

前面我們有談到,當用戶端請求連接配接Photon伺服器時,伺服器會為每個用戶端建立一個PeerBase對象用于處理各種請求以及相應,如圖

Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分

 一個ClientPeer對應一個PeerBase,這個PhotonServer對這些用戶端Peer和伺服器端Peer進行管理。

這裡分伺服器端和用戶端進行學習。

用戶端

上節課我們定義了一個PhotonEngine.cs來進行和伺服器的互動,實作了Photon.Client.IPhotonPeerListener的接口。也就是ClientPeer。這裡有幾個重要的方法。

  • OnStatusChanged——當連接配接狀态改變時調用,peer對象中有個成員屬性PeerState用于标志目前連接配接狀态,peer.PeerState連接配接狀态有以下幾種
    • PeerStateValue.Connecting——正在連接配接伺服器中
    • PeerStateValue.Connected——已連接配接伺服器
    • PeerStateValue.Disconnecting——斷開伺服器中
    • PeerStateValue.Disconnected——已斷開伺服器連接配接
    • PeerStateValue.InitializingApplication——伺服器初始化中
  • OnOperationResponse——伺服器成功響應後執行,方法參數OperationResponse operationResponse封裝了響應的資訊,這裡講解兩個比較重要的資訊
    • operationResponse.OperationCode——響應碼,用于區分響應資訊,既然會有區分響應的響應碼,當然一定會有區分請求的請求碼,在講解伺服器端時會進一步展開
    • operationResponse.Parameters——響應的參數,是一個Dictionary<byte, System.Object>,學過javaweb或者後端開發的童鞋,會比較熟悉這種類型的資料。這個資料便是伺服器傳回的遊戲資料串。
    • 注意:隻有發送請求給伺服器後,伺服器端調用SendOperationResponse方法才會調用
  • OnEvent——伺服器主動發送消息給用戶端時調用,方法參數EventData eventData和OperationResponse有異曲同工之妙
    • 注意:無需發送請求給伺服器,當伺服器調用SendEvent方法時調用
  • DebugReturn——當伺服器傳回一個Debug資訊時調用。

以上四個IPhotonPeerListener接口中的方法用于監聽用戶端與伺服器互動的各種操作,主要的遊戲資料同步都需要使用以上的方法。

伺服器端

打開伺服器項目MyGameServer,我們之前建立了一個ClientPeer的類,繼承自Photon.SocketServer.ClientPeer,實作了兩個方法進行用戶端請求的處理。

  • OnOperationRequest——當成功接收到請求時調用
    • OperationRequest operationRequest——封裝了請求的參數資訊,這個對象有兩個屬性需要關注,分别是
      • operationRequest.OperationCode——區分請求
      • operationRequest.Parameters——請求的參數,同樣是Dictionary<byte, System.Object>類型
    • SendParameters sendParameters
  • OnDisconnect——當斷開連接配接時調用

用戶端與伺服器互動流程

各位看官請看圖:

Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分

當用戶端Peer 調用OpCustom方法請求伺服器時,伺服器的PeerBase對象會接收到這個請求,OnOperationRequest便會執行,當伺服器處理資料後,可以對用戶端Peer進行響應,也可以不響應。如果需要響應用戶端Peer的話,需要在OnOperationRequest處理資料後調用SendOperationResponse方法進行響應。需要注意的是,用戶端Peer的OnOperationResponse隻用在Peer請求伺服器端後,伺服器在OnOperationRequest調用SendOperationResponse方法才會響應。可能會有點亂,簡單來說就是用戶端Peer需要得到響應的話就必須請求伺服器,并且伺服器在處理該條請求後響應用戶端OnOperationResponse才會被調用。

伺服器可以主動發送事件到用戶端,也就是通過SendEvent方法通知用戶端,這是用戶端的OnEvent便會被調用。

基礎原理就基本講完了,接下來就是寫代碼了。

程式設計部分

Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分

首先我們伺服器項目MyGameServer

在ClientPeer.cs的OnOperationRequest方法中進行log,判斷是否能進行送出請求到伺服器中

protected override void OnOperationRequest(Photon.SocketServer.OperationRequest operationRequest, Photon.SocketServer.SendParameters sendParameters) {
            
            //使用operationRequest.OperationCode區分請求
            switch (operationRequest.OperationCode) {
                case 1:
                    Main.log.Info("用戶端1請求伺服器");
                    
                    //響應用戶端
                    //傳回用戶端的資料串
                    Dictionary<byte, object> response = new Dictionary<byte, object>();
                    
                    //1為響應碼,這裡先使用123之類的作為辨別,後續将使用枚舉,使得其代表的含義清晰,易于解讀
                    OperationResponse op = new OperationResponse(1,response);

                    SendOperationResponse(op,sendParameters);
                    
                    break;
                default:
                    break;
            }
        }
           

打開Unity用戶端項目

建立Test.cs,請求伺服器

Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour {

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}

    void OnGUI() {
        if (GUI.Button(new Rect(20, 40, 100, 60), "向伺服器發送請求")) {
            //請求參數
            Dictionary<byte,System.Object> request = new Dictionary<byte,object>();
            
            /**
             * 第一個參數是請求操作碼
             * 第二個參數是請求參數
             * 第三個參數是否為穩定請求
             * */
            PhotonEngine.Peer.OpCustom(1, request, true);

        }
    }
}
           

PhotonEngine.cs中的OnOperationResponse方法進行log,檢視是否成功響應

public void OnOperationResponse(OperationResponse operationResponse) {
        switch (operationResponse.OperationCode) {
            case 1:
                Dictionary<byte, System.Object> response = operationResponse.Parameters;
                
                Debug.Log("從伺服器端傳回的資料是:");
                break;
            default:
                break;
        }
        
    }
           

檢視結果

重新生成伺服器項目MyGameServer,重新啟動伺服器

Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分
Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分
Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分

用戶端成功請求伺服器,并且伺服器成功響應!

進行參數的傳遞

用戶端:

PhotonEngine.cs

public void OnOperationResponse(OperationResponse operationResponse) {
        switch (operationResponse.OperationCode) {
            case 1:
                //使用operationResponse.Parameters獲得伺服器響應的資料串
                Dictionary<byte, System.Object> response = operationResponse.Parameters;
                object request ;
                response.TryGetValue(1, out request);
                Debug.Log("從伺服器端傳回的資料是:"+request);
                break;
            default:
                break;
        }
        
    }
           

Test.cs

void OnGUI() {
        if (GUI.Button(new Rect(20, 40, 100, 60), "向伺服器發送請求")) {
            //請求參數
            Dictionary<byte,System.Object> request = new Dictionary<byte,object>();
            request.Add(1,100);
            request.Add(2,"dfsajei短短釜底抽薪的23214");
            /**
             * 第一個參數是請求操作碼
             * 第二個參數是請求參數
             * 第三個參數是否為穩定請求
             * */
            PhotonEngine.Peer.OpCustom(1, request, true);

        }
    }
           

伺服器端:

Client.cs

//當用戶端成功連接配接伺服器時調用

        protected override void OnOperationRequest(Photon.SocketServer.OperationRequest operationRequest, Photon.SocketServer.SendParameters sendParameters) {
            
            //使用operationRequest.OperationCode區分請求
            switch (operationRequest.OperationCode) {
                case 1:
                    Main.log.Info("用戶端1請求伺服器");

                    Dictionary<byte,object> request = operationRequest.Parameters;
                    //解析參數
                    object intValue;
                    request.TryGetValue(1,out intValue);

                    object strValue;
                    request.TryGetValue(2,out strValue);
                    Main.log.Info("從用戶端1接收到的資料是:"+intValue+","+strValue);
                    //響應用戶端

                    Dictionary<byte, object> response = new Dictionary<byte, object>();
                    response.Add(1,"Success");
                    
                    OperationResponse op = new OperationResponse(1,response);

                    SendOperationResponse(op,sendParameters);
                    break;
                default:
                    break;
            }
        }
           

檢視結果

重新生成伺服器項目MyGameServer,重新啟動伺服器

Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分
Unity網絡程式設計之Photon Server(四)前言用戶端與伺服器互動流程圖解程式設計部分

用戶端成功發送資料到伺服器,并且伺服器成功響應!

好了,第四篇也結束了。這篇我們學習了如何請求伺服器并且響應用戶端。下篇我們将結合一個小的Demo進行更加詳細的學習如何開發一個Unity網絡遊戲。

ps:下篇預告,由于下篇用到了Mysql資料庫和NHibernate,請大家提前學習MySQL和NHibernate,至于NHibernate,學習過Hibernate的童鞋可以很快的上手,基本内容和Hibernate差不多,隻是配置檔案有些地方需要進行和.Net項目适應。關于NHibernate,大家可以參考

https://www.cnblogs.com/wanghaibin/p/5344320.html

感謝大家的支援。