Esempio n. 1
0
        /// <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
                ));
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }