PhotonServer入门(二)

13 篇文章 1 订阅
2 篇文章 0 订阅

1.Unity客户端与PhotonServer交互流程

       本文主要针对Unity创建的客户端与基于PhotonServer创建的服务端交互进行进行简单示例说明。首先看一下二者发生交互的图解。
PhotonServer与客户端交互图解

       首先,当一个客户端向服务端发起请求,即通过PhotonPeer对象的OpCustom方法进行请求。此时,服务端的主类中CreatePeer函数被激活,告知服务端有一个客户端请求连接。然后,服务端的Photon.SocketServer.ClientPeer子类(即ClientPeer)中的函数OnOperationRequest开始处理客户端请求。此时,Server通过SendOperationResponse方法响应客户端,将反馈的结果发送给服务端。然后,客户端在IPhotonPeerListener实现类PhotonEngine的OnOperationResponse()方法中接收服务端反馈的结果。至此,一个请求响应操作完成。当客户端未请求时,服务端则在需要的方法通过PeerBase对象的SendEvent()方法,发送事件给客户端;客户端则通过IPhotonPeerListener实现类PhotonEngine的OnEvent()方法中接收服务端发过来的事件。了解流程之后下面看下一个基础示例。

2.Unity客户端与PhotonServer交互基础示例

       首先,创建一个Unity客户端。项目名称为:PhotonServerClient.
       (1)引入客户端的PhotonServer插件
       创建一个Plugins文件夹,并将PhotonServerSDK文件下的lib文件中的Photon3Unity3D.dll拖拽到Plugins文件夹中。
       (2)创建PhotonServer客户端实例类
       主要实现IPhotonPeerListener接口。
       PhotonEngine.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ExitGames.Client.Photon;//引入命名空间

public class PhotonEngine : MonoBehaviour,IPhotonPeerListener {

    private static PhotonEngine Instance;

    private static PhotonPeer peer = null;
    //客户端发消息给服务端 需要使用该属性
    public static PhotonPeer Peer {
        get {
            return peer;
        }
    }

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(this.gameObject);
        }
        //跳转到第二个场景时,第一个场景的PhotonEngine Instance,
        //需要将其删除掉,场景中只保留一个PhotonEngine Instance
        //删除多余的PhotonEngine Instance
        else if (Instance != null)
        {
            Destroy(this.gameObject);
            return;
        }

    }

    // Use this for initialization
    void Start () {
        //通过IPhotonPeerListener接收服务端反馈的结果
        //peer需要定义Listener和协议
        peer = new PhotonPeer(this,ConnectionProtocol.Udp);

        //传入服务端的IP地址和端口号以及AppicationName
        //要与PhotonServer.config,也就是服务端配置信息保持一致
        peer.Connect("127.0.0.1:5055", "MyGame1");//连接服务端
    }

    // Update is called once per frame
    void Update () {
        //if (peer.PeerState == PeerStateValue.Connected)
        //{
        //    peer.Service();//需要在Update里面一直调用该方法
        //}
        //不需要判断peer的状态
        peer.Service();//需要在Update里面一直调用该方法
    }

    private void OnDestroy()
    {
        if (peer != null && peer.PeerState == PeerStateValue.Connected)
        {
            peer.Disconnect();//断开连接
        }
    }

    public void DebugReturn(DebugLevel level, string message)
    {
        throw new System.NotImplementedException();
    }

    //客户端没有请求,服务端通知客户端时执行该函数
    public void OnEvent(EventData eventData)
    {
      //eventData服务端传过来的数据
      switch (eventData.Code)
      {
        case 1:
            Debug.Log("Receive server response by OnEvent! opCode : 1");
            //处理服务端传送过来的数据
            Dictionary<byte, object> data = eventData.Parameters;
            object intValue1, intValue2;
            data.TryGetValue(1, out intValue1);
            data.TryGetValue(2, out intValue2);
            Debug.Log(intValue1.ToString() + intValue2.ToString());
            break;
        default:
            break;
      }
    }

    //客户端向服务端发起请求,服务端相应并返回结果时执行该函数
    public void OnOperationResponse(OperationResponse operationResponse)
    {
        throw new System.NotImplementedException();
    }

    //peer有五种状态,一旦状态变化就会执行该函数
    public void OnStatusChanged(StatusCode statusCode)
    {
        Debug.Log(statusCode);
    }
}

       客户端与服务端建立连接主要采用:PhotonPeer对象下的OpCustom方法来传输数据。以下用Test.cs来测试客户端向服务器发起请求,服务器作出反馈。客户端测试类:
Test.cs

using System;
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 () {
        if (Input.GetMouseButton(0))
        {
            SendRequest();
        }
    }

    private void SendRequest()
    {
        //OpCustom(byte customOpCode, Dictionary<byte, object> customOpParameters, bool sendReliable);
        //customOpCode 为操作代码用于服务端区分这些请求 customOpParameters 传递给服务端的参数 sendReliable 是否建立可靠连接
        Dictionary<byte, object> data = new Dictionary<byte, object>();
        //数据通过字典的方式传输 一般在项目里面key不会单纯的用int类型来表示而是通过枚举类型
        data.Add(1,100);
        data.Add(2,"qweq数");
        PhotonEngine.Peer.OpCustom(1,data,true);//发消息给客户端

      }
}

       服务器端处理客户端请求的代码应当在ClientPeer.OnOperationRequest()方法中实现。服务端具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;

namespace MyGameServer
{
    //管理每个客户端的连接(类似客服)
    public class ClientPeer : Photon.SocketServer.ClientPeer
    {
        /*ClientPeer方法实现*/
        /*OnDisconnect方法实现*/  //处理客户端断开连接的后续工作

        //处理客户端的请求
        protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
        {
            //通过客户端传过来的customOpCode区分请求
            switch (operationRequest.OperationCode)
            {
                case 1:
                    //应当在MyGameServer.cs中,将log修改为public属性
                    MyGameServer.log.Info("Receive a client Request!");
                    //获取客户端传过来的参数
                    Dictionary<byte, object> data = operationRequest.Parameters;
                    object intValue;
                    data.TryGetValue(1,out intValue);
                    object stringValue;
                    data.TryGetValue(2,out stringValue);
                    MyGameServer.log.Info("Getting Parameters is " + intValue.ToString() + " " + stringValue);//输出在日志上

                    //与请求对应的,反馈给客户端也需要区分 与请求保持一致
                    OperationResponse opResponse = new OperationResponse(1);
                    //发送数据给客户端  opResponse.SetParameters()方法
                    Dictionary<byte, object> serverData = new Dictionary<byte, object>();
                    serverData.Add(1,111111);
                    serverData.Add(2,222222);
                    opResponse.SetParameters(serverData); //将服务端的数据发送给客户端
                    //响应客户端
                    SendOperationResponse(opResponse, sendParameters);

                    //客户端未请求时,服务端通知客户端 向客户端发送事件 通过SendEvent方式实现
                    EventData ed = new EventData(1);
                    ed.Parameters = serverData;
                    //SendEvent方法可以在服务器端的任何地方进行调用
                    SendEvent(ed,new SendParameters());
                    break;
                case 2:
                    break;
                default:
                    break;
            }
        }
    }
}

       与此对应的,客户端也需要处理服务端反馈的结果。此时,处理方法应当在PhotonEngine.OnOperationResponse()函数中实现,具体代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ExitGames.Client.Photon;//引入命名空间

public class PhotonEngine : MonoBehaviour,IPhotonPeerListener {

    /*中间代码,同上*/

    //客户端向服务端发起请求,服务端相应并返回结果时执行该函数
    public void OnOperationResponse(OperationResponse operationResponse)
    {
        //通过服务端的OperationResponse对象的OperationCode区分服务端的反馈
        switch (operationResponse.OperationCode)
        {
            case 1:
                Debug.Log("Receive server response! opCode : 1");
                //处理服务端传送过来的数据
                Dictionary<byte, object> data = operationResponse.Parameters;
                object intValue1, intValue2;
                data.TryGetValue(1,out intValue1);
                data.TryGetValue(2, out intValue2);
                Debug.Log(intValue1.ToString() + intValue2.ToString());
                break;
            case 2:
                break;
            default:
                break;
        }
    }
}

3.程序运行截图

客户端运行截图:

服务端日志截图:

4.小结

       本次示例主要讲解了基于PhotonServer与基于Unity客户端通信的基本操作。具体包括:客户端向服务端请求,服务端反馈客户端;以及,客户端未向服务端请求时,服务端通过发生事件的方式告知客户端。
       另附:
       Unity客户端源代码:https://github.com/ZSCXI/Unity/tree/master/PhotonServerClient_01
       PhotonServer服务端源代码:https://github.com/ZSCXI/Visual_Studio_Projects/tree/master/PhotonServer

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值