持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
3、使用 Photon Server
【先链接到官方网址】www.photonengine.com/
photon server可以用户自定义开发内容,底层框架为C++,不过此服务器貌似只能在Windows操作系统上部署。
【Photon Server-sdk版本下载】www.photonengine.com/zh-CN/sdks#… ,下载后解压即可,最好放在英文的文件夹下。解压后的版本文件如下图所示,在deploy中是一些部署,doc中为帮助文档,lib是对应编辑器的一些链接lib,在src-server中是Photon针对不同编辑器的服务器源码。
【服务器启动位置】deploy->bin_Win64->PhotonControl.exe。(可以认为Photon Server是一个容器,可以在上面部署许多需要使用服务器的应用),服务器启动后,在下图的Photon instances中可以启动对应的服务器应用。
自定义应用配置的话,是在deploy->bin_win64->PhotonServer.config文件中,配置格式如下:
<MyGameInstance
MaxMessageSize="512000"
MaxQueuedDataPerPeer="512000"
PerPeerMaxReliableDataInTransit="51200"
PerPeerTransmitRateLimitKBSec="256"
PerPeerTransmitRatePeriodMilliseconds="200"
MinimumTimeout="5000"
MaximumTimeout="30000"
DisplayName="My Game"
>
<!-- 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="MyGame1">
</UDPListener>
</UDPListeners>
<!-- 0.0.0.0 opens listeners on all available IPs. Machines with multiple IPs should define the correct one here. -->
<!-- Port 4530 is Photon's default for TCP connecttions. -->
<!-- A Policy application is defined in case that policy requests are sent to this listener (known bug of some some flash clients) -->
<TCPListeners>
<TCPListener
IPAddress="0.0.0.0"
Port="4530"
PolicyFile="Policy\assets\socket-policy.xml"
InactivityTimeout="10000"
OverrideApplication="MyGame1"
>
</TCPListener>
</TCPListeners>
<!-- 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="MyGame1">
<!-- MMO Demo Application -->
<Application
Name="MyGame1"
BaseDirectory="MyGameServer"
Assembly="MyGameServer"
Type="MyGameServer.MyGameServer"
ForceAutoRestart="true"
WatchFiles="dll;config"
ExcludeFiles="log4net.config">
</Application>
</Applications>
</MyGameInstance>
【生成文件位置配置】新建项目为类库,然后在新建后的项目属性配置“生成”,输出路径配置为deploy->(新建MyGameServer)->bin,diy的服务器应用就放在这里啦。 在开发的一开始需要先添加引用,在编辑器中需要添加的引用有ExitGamesLibs.dll,Photon.SocketServer.dll,PhotonHostRuntimeInterfaces.dll,
在服务器端有MyGameServer.cs和ClientPeer.cs代码
【MyGameServer中的详细代码】
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ExitGames.Logging;
using Photon.SocketServer;
using System.IO;
using ExitGames.Logging.Log4Net;
using log4net.Config;
namespace MyGameServer
{
//所有的server端,主类都要集成自applicationbase
public class MyGameServer : ApplicationBase
{
private static readonly ILogger log = LogManager.GetCurrentClassLogger();
//当一个客户端请求连接
protected override PeerBase CreatePeer(InitRequest initRequest)
{
log.Info("一个客户端连接过来了");
return new ClientPeer(initRequest);
}
//初始化
protected override void Setup()
{
//日志的初始化
//配置日志存放的位置目录
log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(this.ApplicationRootPath,"log");
//下面配置的是log4net.config所在的目录
FileInfo configFileInfo = new FileInfo(Path.Combine(this.BinaryPath,"log4net.config"));
if(configFileInfo.Exists)
{
LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);//让photon知道是哪个插件
XmlConfigurator.ConfigureAndWatch(configFileInfo);//让log4net插件读取配置文件
}
log.Info("初始化完成!");
}
//server端关闭的时候
protected override void TearDown()
{
}
}
}
【ClientPeer.cs中的详细代码】
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyGameServer
{
public class ClientPeer : Photon.SocketServer.ClientPeer
{
public ClientPeer(InitRequest initRequest):base(initRequest)
{
}
//处理客户端断开连接的后序操作
protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
{
}
//处理客户端的请求,连接成功后的请求
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
switch(operationRequest.OperationCode)//通过OpCode区分请求
{
case 1:
MyGameServer.log.Info("收到一个客户端的请求");
break;
case 2:
break;
default:
break;
}
}
}
}