继续上个文章说~
接收其他人发过来的广播,在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方式,自己写一个指定群发。
博主这里有两种方法供参考,如有更牛逼的方法请多多指教。
先说第一种比较容易理解的。
当一个玩家连入服务器的时候就会在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 = 0; 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(1) { 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。