周末两天又捡起了以前粗略接触过的Photon服务器,当时只是学会了怎么用PUN插件现学现卖一个远程共享操作,对原理什么的都不求甚解。这次又重新从头开始打算用Photon实现Chatroom和一个多人MMO Demo。下面是学习后用XMind做的一个总结图。
Photon简介
Photon是Exit Games公司推出的服务端网络游戏引擎,也是一款实时的Socket服务器和开发框架。Photon使用起来非常方便,也容易扩展。Photon包含两个部分,一部分是一个socket服务器,另一部分是其针对各个平台编写的SDK。服务端架构在windows系统平台上,采用C#语言编写。客户端SDK提供了多种平台的开发API,其中就包括Unity 3D客户端。Photon服务器底层内核采用C++编写,上层用C#进行了一层封装,为开发者提供接口进行业务逻辑的编写,提高了服务器框架的开发效率。
Photon引擎的特点如下:1. 架构于Windows平台下原生态性能高度优化的系统。2. 经过实践证明适用于众多的商业游戏,常在手机网游服务器框架中使用。典型案例包括Glu公司的Indestructible、Eternity Warriors 3和Innogames公司的Kartuga等游戏的服务器。3. 服务器端游戏逻辑采用C#语言实现。4. 采用纤程处理消息机制以避免采用线程导致的问题(资源竞争、占用冲突、多线程通讯)。5. 部署简单,支持云端服务(Photon Cloud)。6. 采用小尺寸的二进制协议,可根据需要使用有序可靠的UDP协议。UDP协议不需要验证数据传输的准确性。Photon也支持TCP、UDP、Websocket。7. 封装了跨平台(Unity 3D、Cocos2d-x、Android、iOS、Html5、Flash)的网络层模块。
配置Photon服务器
- 安装Photon SDK
前往Photon官网下载v3.1版本的SDK。下载完毕后解压可得到deploy、doc、lib和src-server共4个文件目录。deploy是各个平台下的photon服务器可执行文件。doc是帮助文件。lib是已经编译好的dll文件,部署服务器时使用。src-server里面是游戏demo源码。
运行PhotonControl.exe文件
运行PhotonControl.exe,在工具栏中找到photon服务器的图标,右键选择Default->Start as application(不同版本Photon可能不一样,有的是Default)运行Photon服务器。成功后photon服务器图标是蓝色的,否则就是运行异常。 - 设置Photon配置文件
我们可以通过deploy中不同平台目录下的PhotonServer.config配置文件来修改Photon服务器的配置。在配置文件中,default节点里可以设置传输的最大消息尺寸、最大/最小超时时限。在UDPListener和TCPListener节点中可以设置监听UDP和TCP连接的ip地址和通信端口。在Websocket节点中可以进行Websocket通信的一些设置。Application节点比较重要,每个Application的name在通讯接口方法调用时要用到。 - 检查Windows系统里的端口和防火墙设置
启动Default->Run TestClient ,运行客户端测试程序,如果在运行过程中弹出Windows防火墙提示,就需要在Windows防火墙里开放了Photon配置文件中设定的协议端口。如果没有弹出提示,必要时需要在Windows防火墙高级设置中手动创建入站规则。因为在这种情况下有可能防火墙是针对Photon服务器程序创建的入站规则,不限制使用端口。而我们可以手动创建针对UDP和TCP通信的特定端口的入站规则。 - Photon异常排查
当我们启动PhotonControl.exe后,点击图标中的Default->Start as application,运行一段时间服务器停止,图标变为灰色,说明Photon服务器运行异常。我们需要先检查一下Photon服务器的端口设置。如果排除了端口和防火墙设置的影响,我们可以通过日志文件Photon-Default查看是否是启动Photon服务器过程中发生了异常。如果排除了Photon服务器启动异常,就需要打开各个游戏服务端程序的日志文件查看是哪个游戏服务器程序异常。
Photon客户端开发
- Unity 3D连接Photon服务器
导入Photon3Unity3D.dll到U3D工程的Assets/Plugins目录下。编写客户端脚本文件与Photon服务器通信,继承IPhotonPeerListener接口并实现OnStatusChanged接口方法。在Update方法中调用PhotonPeer对象的Service方法就可以与Photon服务器通信了。只有调用Service方法,我们才能正常与服务器进行连接和通信。 - 向Photon服务器发送请求
首先需要编写一个SendMessage函数,从客户端向服务器发送请求,使用PhotonPeer对象的OpCustom方法来发送请求。同时需要实现OnOperationResponse和OnEvent接口方法来处理服务器返回的结果。 - 处理Photon服务器返回的响应
- 实现OnOperationResponse函数
- 可以通过OperationCode分析服务器返回响应的类型。
- 编写函数处理Photon服务器返回的消息
- 自定义事件
- 实现OnEvent函数
- 设定游戏操作枚举
- 传输自定义数据参数
Photon服务器和Unity 3D客户端的通信机制
- 发送请求到Photon服务器
- 处理Photon服务器返回的响应
- 完成游戏房间的操作
- 实现自定义事件
Photon 服务端编写
在编写自己的Photon服务器的时候,需要使用到Photon SDk提供的ExitGamesLibs.dll、Photon.SocketServer.dll、PhotonHostRuntimeInterfaces.dll这三个dll文件。复制dll到自己创建的类库项目,并在C#工程中添加引用。确认添加的引用的“复制本地”属性为True,如果不为True,将“嵌入互操作类型”由True改为False。在Photon服务器目录的deploy目录下创建自己相关项目的服务器目录,修改类库项目的输出路径为这个目录。还需要修改PhotonServer.config文件,添加自定义服务器的Application节点。实现ApplicationBase接口(解析引入Photon.SocketServer、实现抽象类自动导入抽象方法)
-
创建Application类
- 创建一个Photon游戏服务器项目
- 创建Application类
- 实现LiteApplication接口:需要引入Lite.dll文件。实现CreatePeer接口
-
创建Peer类
Peer类负责创建和每个客户端的会话并处理每一个客户端的请求。- 接收和处理客户端的请求
- 自定义枚举,实现OnOperationResponse函数
除了LitePeer父类里定义的基于房间的操作类型,还可以自定义操作类型。 - 广播自定义事件
Photon通信协议
- Photon传输数据类型的限制
在Photon的官方文档中给出了Photon通讯协议支持的数据类型,Photon只能传输基本的数据类型,并不支持传输自定义的对象类型,但是可以通过序列化和反序列化的方式来实现对象传输。客户端和服务端要保持相同的序列化和反序列化方法,服务端要注册自定义对象。 - 序列化和反序列化方法
面对多类型多成员的对象的序列化工作,可以使用第三方的序列化工具,就可以不必对每一类对象都编写一套序列化和反序列化方法。可以采用的第三方组件包括NewtonSoft.Json.dll和protobuf-net.dll。两者的区别是:NewtonSoft是将自定义类型转化为JSON字符串,Protobuf将自定义类型直接转化为byte数组。对于同样大小的自定义类型来说,protobuf转化后数据量更小,传输效率也更高,因此也更加常用。 - Protobuf插件
Protobuf的优点:1)性能好,效率高 2)代码生成机制,数据解析类自动生成 3)支持向后兼容和向前兼容。4)支持java、C++、C#等多种编程语言。- 在Photon服务端使用Protobuf
- 在Unity 3D客户端使用Protobuf
Photon MMO
- PhotonView
当场景中的任何一个组件被加上PhotonView时,会动态地在多个客户端之间同步组件的数据和状态。 - 多场景公用Photon对象
在多个场景如果都通过实例化Peer对象,并建立与Photon服务器的连接,及其消耗资源,可以采用共享静态Photon连接对象的方式,或者把连接功能提取出来做成一个组件,采用DontDestroy方法在加载时保留原有连接,类似连接池的思想。
其他
PUN VS. Photon服务器原生插件
PUN是更接近Unity Networking组件的一种对Photon原生功能的封装。如果对于UN熟悉,可以使用PUN插件,如果没接触UN,直接使用Photon服务器原生插件进行开发。