Photon服务器进阶&一个新游戏的出产(二)

时间:2021-08-23 12:25:50

继续上个文章说~

接收其他人发过来的广播,在OnEvent中进行响应

比如说接收过来加入的消息

    public void OnEvent(EventData eventData)
{
Debug.Log("触发了事件:" + eventData.ToStringFull());
//处理服务器转发回来的事件
switch (eventData.Code)
{
case LiteEventCode.Join:
int actorNr = (int)eventData.Parameters[LiteEventKey.ActorNr];
Debug.Log("玩家的编号为:" + actorNr);
break;
}
}

这个消息是系统给的所以能用在LiteEventKey中的Code,而我们要传自定义的数据要怎么弄呢

case (byte)OpCodeEnum.getTag:
Hashtable Message = (Hashtable)eventData.Parameters[LiteEventKey.Data];
int tag = (int)Message[(byte)OpKeyEnum.tag];
break;

OpCodeEnum和OpKeyEnum都是我自定义的枚举,而我们自定义的数据就存在LiteEventKey.Data中,这还没玩,这只是我们传输的哈希表,而真正的数据放在这个哈希表里。

而OnOperationResponse中的数据处理,和以前的还是一样的。这里就不进行讲解了。

说一下一个比较困扰的问题吧,对于指定群发。这回我们不用Lite方式,自己写一个指定群发。

博主这里有两种方法供参考,如有更牛逼的方法请多多指教。同时也是第二种Peer的进阶使用

先说第一种比较容易理解的。

当一个玩家连入服务器的时候就会在Application中新建一个Peer,这样看来,Application是掌管全局的。这样我们就可以用一个字典将每个Peer记录,来进行简单的群发操作。代码如下加在Application中

        public Dictionary<int, MyPeer> Peer = new Dictionary<int, MyPeer>();

        protected override PeerBase CreatePeer(InitRequest initRequest)
{
//建立连线并回传给Photon Server MyPeer mypeer = new MyPeer(initRequest.Protocol, initRequest.PhotonPeer);
Peer.Add(mypeer.ConnectionId, mypeer);
return mypeer;
} public void radioEvent()
{
OperationResponse or = new OperationResponse();
foreach (MyPeer mypeer in Peer.Values)
{
or.ReturnCode = ;
or.DebugMessage = ""; //返回消息
or.OperationCode = (byte)OpCodeEnum.Login; //编码
mypeer.SendOperationResponse(or, new SendParameters());
}
}

现在我们来看看第二种方法,在用第一种方法的时候会发现一个问题,我们怎么向Lite一样,分房间。指定广播(如果有人能解决这个问题谢谢分享),还有怎客户端发送消息给服务器的时候是在Peer端进行处理的,然而怎么调用Application端的群发也是个问题。

我用下面的方法来解决:

namespace Chat
{
public class ChatPeer : PeerBase
{
private static readonly object syncRoot = new object(); public ChatPeer(IRpcProtocol protocol,IPhotonPeer unmanagedPeer) : base(protocol, unmanagedPeer)
{
lock (syncRoot)
{
BroadcastMessage += this.OnBroadcastMessage;
}
} private static event Action<ChatPeer, EventData, SendParameters> BroadcastMessage; protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
{
lock (syncRoot)
{
BroadcastMessage -= this.OnBroadcastMessage;
}
} protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
var @event = new EventData() { Parameters = operationRequest.Parameters };
lock (syncRoot)
{
BroadcastMessage(this, @event, sendParameters);
} var response = new OperationResponse(operationRequest.OperationCode);
this.SendOperationResponse(response, sendParameters); } private void OnBroadcastMessage(ChatPeer peer, EventData @event, SendParameters sendParameters)
{
if (peer != this)
{
this.SendEvent(@event, sendParameters);
}
} }
}

首先是一个Action委托(不知道委托是什么意思的可以百度一下)

private static event Action<ChatPeer, EventData, SendParameters> BroadcastMessage; // 静态让他常驻内存

Peer被创建的同时将一个OnBriadcastMessage的委托给BrioadcastMessage

当服务器收到客户端发来的群发消息时,启用委托

BroadcastMessage(this, @event, sendParameters);

将在BroadcastMessage中的委托都执行一遍,通过

if (peer != this) { this.SendEvent(@event, sendParameters); }

来控制给谁群发。很强大的方法。貌似是官方的Demo。