Photon游戏通用服务器

作者:追风剑情 发布于:2019-4-25 16:42 分类:Unity3d

Photon SDK https://www.photonengine.com/zh-CN/PUN
Photon Server https://vibrantlink.com/
光子资源下载
https://vibrantlink.com/resource-links/
如何在PUN中设置中国区域
光子云与光子服务器差异

三类服务器
1111.png
Master Server
此服务器是进行配对的地方,客户端可以在这里获得大厅中的房间列表。
Game Server
此服务器负责管理多个房间,以及处理房间中玩家的消息同步。
Name Server
此服务器用于获取特定区域的主服务器地址(IP)。

Photon Cloud后台管理
https://dashboard.photonengine.com

一、PhotonView

这是实现GameObject位置、旋转、缩放同步的关键类,需要挂在需要同步的GameObject上。PhotonView会在它的Awake()方法中注册自己PhotonNetwork.RegisterPhotonView(this);

二、消息驱动

PhotonNetwork类的静态构造方法中创建了一个隐藏的挂有PhotonHandler组件的GameObject,利用PhotonHandler组件的LateUpdate()方法实现消息驱动。

internal class PhotonHandler
{
     // line 127
     protected void LateUpdate() {
         // line 132
         // 驱动所有的PhotonView执行序列化
         PhotonNetwork.RunViewUpdate(); 
         //... 
     }
}


三、序列化与数据同步

11111.png

拖到Observed Components下的组件会被序列化,并进行数据同步。这些组件必须实现IPunObservable接口。
参见PhotonView类中的下面两个方法:
public void SerializeView(PhotonStream stream, PhotonMessageInfo info)
public void DeserializeView(PhotonStream stream, PhotonMessageInfo info)
Controlled locally: (master) = true(代表玩家自己),对应PhotonView的IsMine属性。
PhotonNetwork.IsMasterClient: 判断是否为主客户端
photonView.ViewID: 物体在房间里的唯一ID
当ViewID<PhotonNetwork.MAX_VIEW_IDS时,认为是场景对象,可通过CreatorActorNr==0或者IsSceneView属性判断。
photonView.OwnerActorNr: 对应玩家在房间里的ID
关系OwnerActorNr=ViewID/PhotonNetwork.MAX_VIEW_IDS
player.ActorNumber: 玩家在房间里的ID
如果photonView.OwnerActorNr==player.ActorNumber说明这个photoView是玩家自己的(即,本地客户端的)。
PhotonNetwork.SerializationRate=30;//设置数据同步频率为1000/30≈33ms同步一次数据。
PhotonNetwork.ServerTimestamp;//服务器时间(单位:毫秒)
PhotonNetwork.Time;//服务器时间(单位:秒)

四、监听所有网络事件回调

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Realtime;
using Photon.Pun;

/// <summary>
/// 监听所有网络事件回调
/// </summary>
public class ConnectAndJoinRoom : MonoBehaviour, IInRoomCallbacks, IConnectionCallbacks, IMatchmakingCallbacks, ILobbyCallbacks, IOnEventCallback, IWebRpcCallback
{
    void Awake()
    {
        PhotonNetwork.AddCallbackTarget(this);
    }

    void Start()
    {
        if (!PhotonNetwork.IsConnected)
            PhotonNetwork.ConnectUsingSettings();
    }

    void Update()
    {
        if (PhotonNetwork.NetworkingClient != null)
            PhotonNetwork.NetworkingClient.Service();
    }

    #region IInRoomCallbacks
    public void OnPlayerEnteredRoom(Player newPlayer) { }
    public void OnPlayerLeftRoom(Player otherPlayer) { }
    public void OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged) { }
    public void OnPlayerPropertiesUpdate(Player targetPlayer, ExitGames.Client.Photon.Hashtable changedProps) { }
    public void OnMasterClientSwitched(Player newMasterClient) { }
    #endregion

    #region IConnectionCallbacks
    public void OnConnected() { }
    public void OnConnectedToMaster() { }
    public void OnDisconnected(DisconnectCause cause) { }
    public void OnRegionListReceived(RegionHandler regionHandler) { }
    public void OnCustomAuthenticationResponse(Dictionary<string, object> data) { }
    public void OnCustomAuthenticationFailed(string debugMessage) { }
    #endregion

    #region IMatchmakingCallbacks
    public void OnFriendListUpdate(List<FriendInfo> friendList) { }
    public void OnCreatedRoom() { }
    public void OnCreateRoomFailed(short returnCode, string message) { }
    public void OnJoinedRoom() { }
    public void OnJoinRoomFailed(short returnCode, string message) { }
    public void OnJoinRandomFailed(short returnCode, string message) { }
    public void OnLeftRoom() { }
    #endregion

    #region ILobbyCallbacks
    public void OnJoinedLobby() { }
    public void OnLeftLobby() { }
    public void OnRoomListUpdate(List<RoomInfo> roomList) { }
    public void OnLobbyStatisticsUpdate(List<TypedLobbyInfo> lobbyStatistics) { }
    #endregion

    #region IOnEventCallback
    public void OnEvent(ExitGames.Client.Photon.EventData photonEvent) { }
    #endregion

    #region IWebRpcCallback
    public void OnWebRpcResponse(ExitGames.Client.Photon.OperationResponse response) { }
    #endregion
}


通常在OnConnectedToMaster回调中创建并加入房间,加入房间成功后会收到OnJoinedRoom回调。

RoomOptions options = new RoomOptions();
PhotonNetwork.JoinOrCreateRoom("MyRoomName", options, TypedLobby.Default);


向房间中的其他玩家发送事件,其他玩家通过OnEvent回调接收事件。

byte code = 199;//自定义事件类型[0-199]
//发送的内容存放到Hashtable,用byte作key
ExitGames.Client.Photon.Hashtable table = new ExitGames.Client.Photon.Hashtable();
table[(byte)0] = 100;
table[(byte)1] = 200;
RaiseEventOptions eventOptions = RaiseEventOptions.Default;
SendOptions sendOptions = SendOptions.SendReliable;
PhotonNetwork.RaiseEvent(code, table, eventOptions, sendOptions);


五、PunRPC特性

[Photon.Pun.PunRPC]
private void RPCFun()
{
}
调用方式photonView.RPC("RPCFun", RpcTarget.All);


光子服务器(Photon Server)

https://vibrantlink.com/photonserver/

下载 https://www.photonengine.com/zh-CN/sdks#serverserver

下载时记着先选标签

1111.png

1111.png

1111.png

双击安装后

1111.png

参见 5分钟启动PhotonServer

运行deploy\bin_Win64\PhotonControl.exe

1111.png

运行测试客户端 Run Testclient (LoadBalancing)
1111.png

在您应用许可证文件之前,Photon Server将限制为20个并发连接

1111.png

Photon Server配置文件deploy\bin_Win64\PhotonServer.config
配置Photon Server的IP和Port
1111.png

Unity工程中配置PhotonServerSettings
1111.png
当使用自己部署的Photon Server时,不要勾选Use Name Server,填好Master Server的IP和Port。

读取配置PhotonNetwork.PhotonServerSettings

运行Unity工程测试

1111.png

Windows 10启动Photon Server报错

9600: 09:59:47.940 - CounterPublisher:4 - PhotonRunning() failed. Exception:
System.TypeInitializationException: “Photon.CounterPublisher.SystemCounter”的类型初始值设定项引发异常。 ---> System.InvalidOperationException: 无法加载计数器名称数据,因为从注册表读取的索引“”无效。
   在 System.Diagnostics.PerformanceCounterLib.GetStringTable(Boolean isHelp)
   在 System.Diagnostics.PerformanceCounterLib.get_NameTable()
   在 System.Diagnostics.PerformanceCounterLib.get_CategoryTable()
   在 System.Diagnostics.PerformanceCounterLib.CategoryExists(String machine, String category)
   在 System.Diagnostics.PerformanceCounterCategory.Exists(String categoryName, String machineName)
   在 ExitGames.Diagnostics.Counter.PerformanceCounterReader.Initialize() 位置 c:\(Work)\(EG)\exitgames-libs\src\Core\Diagnostics\Counter\PerformanceCounterReader.cs:行号 134
   在 Photon.CounterPublisher.SystemCounter..cctor() 位置 d:\dev\photon-socketserver-sdk_cloud\src-server\CounterPublisher\SystemCounter.cs:行号 36
   --- 内部异常堆栈跟踪的结尾 ---

分析原因:Photon Server的计数器被Windows禁用了
解决方案
参见 http://www.cnblogs.com/xiezunxu/articles/7797880.html
在cmd中输入perfmon,可查看windows禁用了哪些计数器。
1111.png
在cmd中输入LODCTR/R,从系统备份存储中重建性能计数器设置。

22222.png

为了让局域网内的其他玩家能够访问服务器,需要设置成Set Local IP

1111.png

注意:如果没显示本机的局域网IP,检查下电脑有没连上局域网。连上局域网后重启电脑和Photon Server


Photon Voice

如果需要语音功能,需从Unity Asset Store下载语音插件

1111.png

数字信号处理(Digital Signal Processing, DSP)
回声消除器(Acoustic Echo Canceller,AEC),可以消除各种延迟的回声。
背景噪音抑制(Automatic Noise Suppression, ANS),自动消除杂音。
自动增益补偿(Automatic Gain Control, AGC),自动调节麦克风收音量,避免发言者与麦克风的距离改变时,声音忽大忽小。
语音活动检测(Voice Activity Detection, VAD),在噪声环境中检测语音存在与否。

11111.png

每个进入房间的玩家会实例化一个RemoteSpeakerPrefab对象

1111.png


标签: Unity3d

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号