/// <summary> /// 发送在线可靠协议,如果不在线等,仍然不会发送哦。 /// </summary> /// <param name="roleId"></param> /// <param name="listenerName"></param> /// <param name="fullEncodedProtocol">协议必须先编码,因为会跨事务。</param> public void SendReliableNotify(long roleId, string listenerName, int typeId, Binary fullEncodedProtocol) { Game.App.Instance.Zeze.TaskOneByOneByKey.Execute( listenerName, Game.App.Instance.Zeze.NewProcedure(() => { BOnline online = table.Get(roleId); if (null == online || online.State == BOnline.StateOffline) { return Procedure.Success; } if (false == online.ReliableNotifyMark.Contains(listenerName)) { return Procedure.Success; // 相关数据装载的时候要同步设置这个。 } // 先保存在再发送,然后客户端还会确认。 // see Game.Login.Module: CLogin CReLogin CReliableNotifyConfirm 的实现。 online.ReliableNotifyQueue.Add(fullEncodedProtocol); if (online.State == BOnline.StateOnline) { var notify = new SReliableNotify(); // 不直接发送协议,是因为客户端需要识别ReliableNotify并进行处理(计数)。 notify.Argument.ReliableNotifyTotalCountStart = online.ReliableNotifyTotalCount; notify.Argument.Notifies.Add(fullEncodedProtocol); SendInProcedure(new List<long>() { roleId }, notify.TypeId, new Zeze.Net.Binary(notify.Encode())); } online.ReliableNotifyTotalCount += 1; // 后加,start 是 Queue.Add 之前的。 return Procedure.Success; }, "SendReliableNotify." + listenerName )); }
private int ReliableNotifySync(Session session, long ReliableNotifyConfirmCount, BOnline online, bool sync = true) { if (ReliableNotifyConfirmCount < online.ReliableNotifyConfirmCount || ReliableNotifyConfirmCount > online.ReliableNotifyTotalCount || ReliableNotifyConfirmCount - online.ReliableNotifyConfirmCount > online.ReliableNotifyQueue.Count) { return(ResultCodeReliableNotifyConfirmCountOutOfRange); } int confirmCount = (int)(ReliableNotifyConfirmCount - online.ReliableNotifyConfirmCount); if (sync) { var notify = new SReliableNotify(); notify.Argument.ReliableNotifyTotalCountStart = ReliableNotifyConfirmCount; for (int i = confirmCount; i < online.ReliableNotifyQueue.Count; ++i) { notify.Argument.Notifies.Add(online.ReliableNotifyQueue[i]); } session.SendResponseWhileCommit(notify); } online.ReliableNotifyQueue.RemoveRange(0, confirmCount); online.ReliableNotifyConfirmCount = ReliableNotifyConfirmCount; return(ResultCodeSuccess); }
public override int ProcessSReliableNotify(SReliableNotify protocol) { // TODO ReliableNotifyTotalCount += protocol.Argument.Notifies.Count; foreach (var notify in protocol.Argument.Notifies) { try { var bb = Zeze.Serialize.ByteBuffer.Wrap(notify); int typeId = bb.ReadInt4(); if (ReliableNotifyMap.TryGetValue(typeId, out var handle)) { int size = bb.ReadInt4(); // 所有的notify必须定义了客户端处理。 var factoryHandle = Game.App.Instance.Client.FindProtocolFactoryHandle(typeId); var pNotify = factoryHandle.Factory(); pNotify.Decode(bb); handle.OnReliableNotify(pNotify); } } catch (System.Exception ex) { // TODO handle error here. } } // 马上确认。可以考虑达到一定数量或者定时。 var confirm = new ReliableNotifyConfirm(); confirm.Argument.ReliableNotifyConfirmCount = ReliableNotifyTotalCount; protocol.Sender.Send(confirm); // process rpc result // TODO 同步队列确认失败,应该重新开始一次完成的登录流程。 return(Zeze.Transaction.Procedure.Success); }