Article directory
Unity Advanced – Using PhotonServer to implement server and client communication
Server installation and configuration
Photon’s address: https://www.photonengine.com/zh-cn/sdks
- Download the corresponding sdk:
- Create a new class library in Visual studio:
Add the corresponding dll file reference to the project:
Find in this folder:
These five plugins:
Write server side
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Photon.SocketServer;
namespace PhotonServerFirst
{
public class PSTest : ApplicationBase
{
protected override PeerBase CreatePeer(InitRequest initRequest)
{
return new PSpeer(initRequest);
}
protected override void Setup()
{
}
protected override void TearDown()
{
}
}
}
Write client template
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
namespace PhotonServerFirst
{
public class PSpeer : ClientPeer
{
public PSpeer(InitRequest initRequest) : base(initRequest)
{
}
protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
{
throw new NotImplementedException();
}
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
throw new NotImplementedException();
}
}
}
Create server file
- Modify the build directory:
Put it in the bin created before.
Then generate.
- Modify PhotonServer configuration file
Looking for
-
Configuration file:
<!-- DisplayName:显示名称 --> <PhotonServerFirst MaxMessageSize="512000" MaxQueuedDataPerPeer="512000" PerPeerMaxReliableDataInTransit="51200" PerPeerTransmitRateLimitKBSec="256" PerPeerTransmitRatePeriodMilliseconds="200" MinimumTimeout="5000" MaximumTimeout="30000" DisplayName="PhotonServerFirst" > <!-- 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="PhotonServerFirst"> </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="PhotonServerFirst" > </TCPListener> </TCPListeners> <!-- Defines the Photon Runtime Assembly to use. --> <Runtime Assembly="PhotonHostRuntime, Culture=neutral" Type="PhotonHostRuntime.PhotonDomainManager" UnhandledExceptionPolicy="Ignore"> </Runtime> <Applications Default="PhotonServerFirst"> <!-- Name:要注意和上面填写的应用名字相同 --> <!--BaseDirectory:编译好的dll所在文件夹名--> <!--Assembly:dll名--> <!--Type:命名空间.类名--> <Application Name="PhotonServerFirst" BaseDirectory="PhotonServerFirst" Assembly="PhotonServerFirst" Type="PhotonServerFirst.PSTest" ForceAutoRestart="true" WatchFiles="dll;config" ExcludeFiles="log4net.config"> </Application> </Applications> </PhotonServerFirst>
In this way, the server we created will be available under photonServer.
add log
-
Look under andlog4net.config
copy it into the project. -
Then change the attribute to always copy
-
Change the name of the output log
<file type="log4net.Util.PatternString" value="%property{Photon:ApplicationLogPath}\\PhotonServerFirst.Server.log" />
-
Configure server program
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Photon.SocketServer; using ExitGames.Logging; using ExitGames.Logging.Log4Net; using log4net.Config; using System.IO; namespace PhotonServerFirst { public class PSTest : ApplicationBase { //日志需要的 private static readonly ILogger log = LogManager.GetCurrentClassLogger(); protected override PeerBase CreatePeer(InitRequest initRequest) { return new PSpeer(initRequest); } //初始化 protected override void Setup() { InitLog(); } //server端关闭的时候 protected override void TearDown() { } #region 日志 /// <summary> /// 初始化日志以及配置 /// </summary> private void InitLog() { //日志的初始化 log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = this.ApplicationRootPath + @"\bin_Win64\log"; //设置日志的路径 FileInfo configFileInfo = new FileInfo(this.BinaryPath + @"\log4net.config"); //获取配置文件 if (configFileInfo.Exists) { //对photonserver设置日志为log4net LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance); XmlConfigurator.ConfigureAndWatch(configFileInfo); log.Info("初始化成功"); } } #endregion } }
-
Open photonserver to run the application, and the log output is configured successfully.
Client configuration
Photon-OnPremise-Server-SDK_v4-0-29-11263 > lib >
Find it belowPhoton3Unity3D.dll
and put it in the plug-in folder (Pluigins) of unity3d.- Write client scripts to bind to a singleton component that will not be destroyed. (code show as below)
Communication between client and server
-
client
using System.Collections; using System.Collections.Generic; using UnityEngine; using ExitGames.Client.Photon; public class PhotonManager : MyrSingletonBase<PhotonManager>, IPhotonPeerListener { private PhotonPeer peer; void Awake() { DontDestroyOnLoad(this); } // Start is called before the first frame update void Start() { peer = new PhotonPeer(this, ConnectionProtocol.Tcp); peer.Connect("127.0.0.1:4530", "PhotonServerFirst"); } void Update() { peer.Service(); if (Input.GetKeyDown(KeyCode.Space)) { Dictionary<byte, object> dic = new Dictionary<byte, object>(); dic.Add(1,"你好,我是王小虎"); peer.OpCustom(1, dic, true); } } private void OnDestroy() { //断开连接 peer.Disconnect(); } public void DebugReturn(DebugLevel level, string message) { } /// <summary> /// 接收服务器事件 /// </summary> /// <param name="eventData"></param> public void OnEvent(EventData eventData) { if(eventData.Code == 1) { Debug.Log("事件" + eventData.Parameters[1]); } } /// <summary> /// 接收服务器响应 /// </summary> /// <param name="operationResponse"></param> public void OnOperationResponse(OperationResponse operationResponse) { if (operationResponse.OperationCode == 1){ Debug.Log(operationResponse.Parameters[1]); } } /// <summary> /// 状态改变 /// </summary> /// <param name="statusCode"></param> public void OnStatusChanged(StatusCode statusCode) { Debug.Log(statusCode); } }
-
server
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Photon.SocketServer; using PhotonHostRuntimeInterfaces; namespace PhotonServerFirst { public class PSpeer : ClientPeer { public PSpeer(InitRequest initRequest) : base(initRequest) { } //处理客户端断开的后续工作 protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail) { throw new NotImplementedException(); } //处理客户端的请求 protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters) { switch (operationRequest.OperationCode) { case 1: //收到 Dictionary<byte, object> data = operationRequest.Parameters; PSTest.log.Info("收到客户端消息:" + data[1].ToString()); //返回 Dictionary<byte, object> data2 = new Dictionary<byte, object>(); data2.Add(1, "你好,我是服务器"); // OperationResponse operationResponse = new OperationResponse(); // operationResponse.OperationCode = 1; // operationResponse.Parameters = data2; //创建一个响应 OperationResponse operationResponse = new OperationResponse(1, data2); SendOperationResponse(operationResponse, sendParameters); //创建一个事件 EventData Edata = new EventData(1, data2); SendEvent(Edata, sendParameters); break; default: break; } } } }
Dlc appears when vscode reference does not work
Check this out.