设为首页 收藏本站
查看: 3607|回复: 0

[经验分享] 快速了解和使用Photon Server

[复制链接]

尚未签到

发表于 2017-12-7 17:48:47 | 显示全部楼层 |阅读模式
Photon Server的使用

  又要过去一个寒假了,然而在家什么事都没干成,在一个偶然的机会下,跟着网上的教程学习了一下Photon Server,然后又觉得无聊,所以就顺便写篇博客,介绍一下Photon Server和总结一下如何使用。
  一、Photon Server是什么?
  Photon Server是一套套装的游戏服务器,以往开发线上游戏都必需自行花费大笔的研发资金和人力先从研发游戏引擎和伺服器开始,後来慢慢的游戏引擎开始走向套装化,研发人员有许多现成的游戏引擎可以选择,像是unreal或是unity等等,接著,游戏服务器也开始朝套装发展,市面上常见的套装Game Server有 smart fox server 、 electro server 5 、 Photon等等,这几个都是非常优秀的套装伺服器,市面上非常多的FB游戏都是利用这些套装伺服器作为通讯用平台,都是经过市场验证过的产品。
  Photon Server的核心是用C++开发,不同 於其他伺服器采用的java,因此在效能上凌驾於其他server不少,在 Server 端 Script 采用C#语言,算是一种很容易学习的语言,Photon的Client端支援C++、.net、java、html5 、flash、Unity、mamalade、iOS、android、winphone、cocos等,市面上常见的平台全部都有支援,使用容易、效能高、支援平台多,这些优点让photon成为一个优越的套装socket server。
  二、如何下载Photon Server?
  废话少说,直接来说一下如何下载Photon Server搭建的游戏服务器,首先需要下载Photon Server 在                                                                                  https://www.photonengine.com/en/OnPremise/Download 中下载。(第一个就是,可能需要官网账号才能下载,所以注册一个吧) DSC0000.png
  下载之后选个目录点击安装就可以了,完全是傻瓜式安装,没有什么需要注意的地方。
  三、Photon Server的安装目录
  安装好了之后,找到安装目录。会有四个文件夹
DSC0001.png

  deploy主要存放photon的服务器控制程序和服务端Demo
  doc顾名思义就是存放相关文档的
  Lib存放开发服务端所需要的类库
  src-server存放服务端Demo的源代码
  然后点击deploy进去之后
DSC0002.png

  启动服务器的程序在bin_Win32和bin_win64,看自己的电脑用的是32位还是64位
  启动的程序为
DSC0003.png

  四、Photon Server的第一个程序的配置
  首先打开visual studio新建一个C#的类库,特别注意是类库,笔者第一次时建的是C#应用程序,结果导致需要一个Main函数作为程序的入口,而Photon Server的程序入口不是Main函数。
  建好项目之后,需要指定一下我们项目所需要Photon所需要的类库,需要引用一下这些类库,首先找到Photon的安装目录的lib,在里面找到ExitGamesLibs.dll、Photon.SocketServer.dll、PhotonHostRuntimeInterfaces.dll、这三个程序集,引用一下
DSC0004.png

DSC0005.png

  原理上只需要上面的三个程序集,但是为了开发时方便需要将调试信息和错误输出到日志上,所以也在lib中将log4net.dll、ExitGames.Logging.Log4Net.dll引用一下,写一个日志输出的函数需要,在此也引用一下。日志输出需要一个输出文件,在此也特别说明一下在安装目录下E:\Photon\Photon-OnPremise-Server-SDK_v4-0-29-11263\src-server\Loadbalancing\LoadBalancing,找到log4net.config文件,将它拷贝到工程目录下和代码放到一块,需要修改一下内容为:
  <?xml version="1.0" encoding="utf-8" ?>
  <log4net debug="false">
  <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
  <layout type="log4net.Layout.PatternLayout">
  <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %-30.30c{2} %m% [%t]%n" />
  </layout>
  </appender>
  <!-- "normal" log file appender -->
  <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
  <file type="log4net.Util.PatternString" value="%property{Photon:ApplicationLogPath}\\%property{LogFileName}.log" />
  <encoding value="utf-8" />
  <param name="AppendToFile" value="true" />
  <param name="MaxSizeRollBackups" value="1" />
  <param name="MaximumFileSize" value="250MB" />
  <param name="RollingStyle" value="Size" />
  <param name="LockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
  <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
  </layout>
  </appender>
  <!-- logger -->
  <root>
  <level value="INFO" />
  <appender-ref ref="LogFileAppender" />
  <appender-ref ref="ConsoleAppender" />
  </root>
  <!-- operation data logger -->
  <!-- set level to DEBUG to enable operation data logging-->
  <logger name="OperationData">
  <level value="INFO" />
  </logger>
  <!-- override log level for certain classes / namespaces -->
  <!-- set to DEBUG to enable logging for the Photon.SocketServer namespace -->
  <logger name="ExitGames">
  <level value="INFO" />
  </logger>
  <!-- set to DEBUG to enable logging for the Photon.SocketServer namespace -->
  <logger name="Photon.SocketServer">
  <level value="INFO" />
  </logger>
  </log4net>
  五、Photon Server的第一个程序
  完成上面的配置之后,就可以开始编写代码了,新建一个类,
  MyServer,继承一个抽象类ApplicationBase然后实现抽象类中的方法,特别注意这个抽象类,它是整个服务端的入口
  class MyServer : ApplicationBase
  {
  private static ILogger log =  
  ExitGames.Logging.LogManager.GetCurrentClassLogger();
  //日志输出
  public static void Log(string str)
  {
  log.Info(str.ToString());
  }
  protected virtual void InitLogging()
  {
  ExitGames.Logging.LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);
  GlobalContext.Properties["Photon:ApplicationLogPath"] =  
  Path.Combine(this.ApplicationRootPath, "log");
  GlobalContext.Properties["LogFileName"] = "My" + this.ApplicationName;
  XmlConfigurator.ConfigureAndWatch(new  
  FileInfo(Path.Combine(this.BinaryPath, "log4net.config")));
  }
  //创建连接
  protected override PeerBase CreatePeer(InitRequest initRequest)
  {
  return new MyClient(initRequest);
  }
  //服务器启动时调用
  protected override void Setup()
  {
  InitLogging();
  Log("Setup ok.");
  }
  //服务器停止时调用
  protected override void TearDown()
  {
  Log("TearDown ok.");
  }
  }
  接下来新建一个MyClient类,作为管理连接到服务器的每一个客户端,每连接进来一个客户端就会创建一个MyClient的对象用来管理客户端,MyClient实现ClientPeer抽象类,这个类是用来与客户端通信使用的,然后客户端的状态发生改变时就会调用相应的方法
  public class MyClient : ClientPeer
  {
  public MyClient(InitRequest initRequest) : base(initRequest)
  {
  MyServer.Log("客户端上线");
  }
  //客户端断开连接
  protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
  {
  MyServer.Log("客户端下线");
  }
  //客户端发起请求
  protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
  {
  MyServer.Log("客户端发送请求");
  }
  }
  六、配置启动Photon Server
  写完最基本的两个类之后就可以配置启动服务器了,首先找到安装photon的目录E:\Photon\Photon-OnPremise-Server-SDK_v4-0-29-11263\deploy\bin_Win64
  我用的是64位系统,所以找到bin_win64,如果是32位就找bin_win32,找到里面的PhotonServer.config,编辑它,在文件的后面加上(和此文件前面的内容差不多,可以复制过来修改)
  <ChatServer  <!-- 这里的名称为服务器名称,可随意取-->
  MaxMessageSize="512000"
  MaxQueuedDataPerPeer="512000"
  PerPeerMaxReliableDataInTransit="51200"
  PerPeerTransmitRateLimitKBSec="256"
  PerPeerTransmitRatePeriodMilliseconds="200"
  MinimumTimeout="5000"
  MaximumTimeout="30000"
  DisplayName="ChatServer">
  <!-- 0.0.0.0 opens listeners on all available IPs. Machines with multiple IPs should define the correct one here. -->
  <!-- Port 5055 is Photon's default for UDP connections. -->
  <UDPListeners>
  <UDPListener
  IPAddress="0.0.0.0"
  Port="5055"
  OverrideApplication="ChatRoom"><!-- 这里的名称为项目名称-->
  </UDPListener>
  </UDPListeners>
  <!-- 0.0.0.0 opens listeners on all available IPs. Machines with multiple IPs should define the correct one here. -->
  <TCPListeners>
  <!-- TCP listener for Game clients on Master application -->
  <TCPListener
  IPAddress="0.0.0.0"
  Port="4530"
  OverrideApplication="ChatRoom"<!-- 这里的名称为项目名称-->
  PolicyFile="Policy\assets\socket-policy.xml"
  InactivityTimeout="10000"
  >
  </TCPListener>
  <!-- DON'T EDIT THIS. TCP listener for GameServers on Master application -->
  <TCPListener
  IPAddress="0.0.0.0"
  Port="4520">
  </TCPListener>
  </TCPListeners>
  <!-- Policy request listener for Unity and Flash (port 843) and Silverlight (port 943)  -->
  <PolicyFileListeners>
  <!-- multiple Listeners allowed for different ports -->
  <PolicyFileListener
  IPAddress="0.0.0.0"
  Port="843"
  PolicyFile="Policy\assets\socket-policy.xml">
  </PolicyFileListener>
  <PolicyFileListener
  IPAddress="0.0.0.0"
  Port="943"
  PolicyFile="Policy\assets\socket-policy-silverlight.xml">
  </PolicyFileListener>
  </PolicyFileListeners>
  <!-- Defines the Photon Runtime Assembly to use. -->
  <Runtime
  Assembly="PhotonHostRuntime, Culture=neutral"
  Type="PhotonHostRuntime.PhotonDomainManager"
  UnhandledExceptionPolicy="Ignore">
  </Runtime>
  <!-- Defines which applications are loaded on start and which of them is used by default. Make sure the default application is defined. -->
  <!-- Application-folders must be located in the same folder as the bin_win32 folders. The BaseDirectory must include a "bin" folder. -->
  <Applications Default="ChatRoom"> <!-- 这里的名称为项目名称-->
  <Application
  Name="ChatRoom" <!-- 这里的名称为项目名称-->
  BaseDirectory="ChatRoom"<!-- 这里的名称为deploy文件夹下的启动服务器的
  文件夹名称 -->
  Assembly="ChatRoom"
  Type="ChatRoom.MyServer"<!-- 这里的名称为程序入口的类-->
  ForceAutoRestart="true"
  WatchFiles="dll;config"
  ExcludeFiles="log4net.config"
  >
  </Application>
  <!-- CounterPublisher Application -->
  <Application
  Name="CounterPublisher"
  BaseDirectory="CounterPublisher"
  Assembly="CounterPublisher"
  Type="Photon.CounterPublisher.Application"
  ForceAutoRestart="true"
  WatchFiles="dll;config"
  ExcludeFiles="log4net.config">
  </Application>
  </Applications>
  </ChatServer>
  写好配置文件之后在deploy文件夹中新建一个文件夹,最后取和项目名称一样,再在里面新建一个bin文件夹存放项目生成的程序集
DSC0006.png

DSC0007.png

  搞定这些工作之后就开始生成程序集,回到vs,找到写好的项目,右键点击项目名选择属性
DSC0008.png

  选择生成,选择新建好的bin文件夹
  最后点击生成解决方案
DSC0009.png

  然后回到安装目录下的bin_win64,找到PhotonControl.exe,双击运行,然后会发现电脑右下角会出多了一个图标,右键就会发现刚刚配置文件中的服务器,点击启动
DSC00010.png

DSC00011.png

  然后发现将鼠标停在图标上会有提示Photon running,这时服务器就成功启动了
DSC00012.png

客户端的编写(unity)

  一、客户端的配置
  首先客户端笔者使用unity编写,其他平台的大同小异,读者可自行研究一下,首先客户端需要一些特定的类库,所以先找到安装目录的lib目录下找到Photon3Unity3D.dll这个程序集,将它复制一份到unity的项目目录下(事先在unity中新建一个工程,在工程Assets目录下新建一个Plugins目录用来存放程序集)。这样就配置好客户端所需的程序集了。
  二、客户端脚本的编写
  在工程里新建一个脚本PhotonManager,将脚本挂载到主摄像机上,双击脚本开始编辑,首先引入命名空间using ExitGames.Client.Photon; 客户端和服务器需要用到IPhotonPeerListener这个接口,所以实现这个接口
  using System.Collections;
  using System.Collections.Generic;
  using UnityEngine;
  using ExitGames.Client.Photon;
  using System;
  using Common.Code;
  public class PhotonManager : MonoBehaviour,IPhotonPeerListener {
  private static PhotonManager instance = null;
  public static PhotonManager Instance { get { return instance; } }
  //用来和服务器连接
  private PhotonPeer peer;
  private ConnectionProtocol protocol = ConnectionProtocol.Udp;//默认使用udp协议
  private string serverAddress = "127.0.0.1:5055";//连接本机ip,端口5055
  private string applicationName = "ChatRoom";//连接名称
  private bool connected = false;
  void Awake()
  {
  instance = this;
  peer = new PhotonPeer(this, protocol);
  peer.Connect(serverAddress, applicationName);//与服务器做连接
  }
  void Update () {
  if(!connected) //如果与服务器断开了,就需要再连接一下
  peer.Connect(serverAddress, applicationName);
  peer.Service();//获取服务器的响应,需要每时每刻都获取,保持连接状态
  //这里为调试代码,当客户端按下空格是,想服务器发起请求,内容为"wowowowow"
  if (Input.GetKeyDown(KeyCode.Space))
  {
  var parameter = new Dictionary<byte, object>();
  parameter.Add(0, "wowowowow");
  peer.OpCustom(1, parameter, true);
  }
  }
  //停止客户端时,与服务器断开连接
  void OnDestroy()
  {
  peer.Disconnect();
  }
  public void DebugReturn(DebugLevel level, string message)
  {
  }
  public void OnEvent(EventData eventData)
  {
  }
  //服务器给客户端的响应
  public void OnOperationResponse(OperationResponse operationResponse)
  {
  }
  //状态改变时调用
  public void OnStatusChanged(StatusCode statusCode)
  {
  Debug.Log(statusCode.ToString());
  switch (statusCode)
  {
  case StatusCode.Connect:
  connected = true;
  break;
  case StatusCode.Disconnect:
  connected = false;
  break;
  }
  }
  }
  三、连接服务器
  写好客户端,就可以启动服务器,调试了,按照上面的方法启动搭建好的服务器,然后运行客户端,然后就会发现unity的控制台中的输出信息,如果是connected,表示连接成功了!
DSC00013.png

  回到服务器中,打开写好的输出日志
DSC00014.png

DSC00015.png

DSC00016.png

  就会看到输出的调试信息 Setup ok
  客户端上线
  然后在客户端敲下空格,就会看到有,客户端发起请求的消息出现。
  四、总结
  好久没有写技术博客了,这次写发现写的并不是那么顺手,写好有点像教程一样,希望这篇博客可以帮助读者快速上手photon Server。如果有什么写得不好的地方希望可以和我探讨一下,文中有很多基本的方法没有解释到,有兴趣的也可以到官方中去查找一些文档,里面有很详细的介绍哦。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-421859-1-1.html 上篇帖子: json-server模拟REST API 下篇帖子: Windows平台下PHP7添加Sqlserver扩展
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表