Пример #1
0
    /// <summary>
    /// 通用解包方法 需保证bytes数组完整性
    /// </summary>
    public object StartUnPack(ref byte[] bytes, ref ProtocolEventType type)
    {
        if (bytes.Length <= 12)
        {
            return(null);
        }
        int dataCount = ProtocolUtility.UnPackInt(ref bytes);                         //数据长度

        type = (ProtocolEventType)ProtocolUtility.UnPackInt(ref bytes);               //事件类型
        ProtocolNo protoNo        = (ProtocolNo)ProtocolUtility.UnPackInt(ref bytes); //协议号
        object     protocolObject = null;

        protocolObjectDict.TryGetValue(protoNo, out protocolObject);
        if (protocolObject != null)
        {
            List <object> list             = GetProtocolUnPackMemberListByProtocolNo(protoNo); //协议解包类结构如:{int,string,class}
            List <object> unPackObjectList = new List <object>();
            CommonUnPack(ref bytes, list, ref unPackObjectList);                               //开始递归解包
            ((ProtocolData)protocolObject).SetData(unPackObjectList);
            return(((ProtocolData)protocolObject).Clone());
        }
        else
        {
            Debug.LogError("protocolNo" + protoNo + ",not exist protocolObject in protocolObjectDict!");
            return(null);
        }
    }
Пример #2
0
    private void HandleTempList()
    {
        //现有缓存数据长度
        int curLength = tempList.Count - 4;
        //总数据长度 = 保存于缓存[0,3]字节
        int sumLength = BitConverter.ToInt32(tempList.ToArray(), 0);
        //所需数据长度
        int needLength = sumLength - curLength;
        //可取长度
        int canGetLength = Math.Min(this.startIndex, needLength);//其实这里可能肯定就是startIndex,不然就是协议异常了..

        for (int i = 0; i < canGetLength; i++)
        {
            tempList.Add(data[i]);
        }
        //去除已取出部分字节
        CommonToolUtility.ByteSub(ref data, canGetLength);
        this.startIndex -= canGetLength;
        curLength        = tempList.Count - 4;
        //获取到完整数据开始解析(正常情况下,肯定是完整了)
        if (sumLength - curLength <= 0)
        {
            ProtocolEventType type     = ProtocolEventType.Null;
            byte[]            bytesArr = tempList.ToArray();
            object            o        = ProtocolManager.Instance.StartUnPack(ref bytesArr, ref type);
            if (type != ProtocolEventType.Null)
            {
                EventSystem.Instance.Dispatch(type, (ProtocolData)o);
            }
            //清空缓存
            tempList.Clear();
        }
    }
Пример #3
0
        private void HandleTempList()
        {
            //现有缓存数据长度
            int curLength = tempList.Count - 4;
            //总数据长度 = 保存于缓存[0,3]字节
            int sumLength = BitConverter.ToInt32(tempList.ToArray(), 0);
            //所需数据长度
            int needLength = sumLength - curLength;
            //可取长度,若当前网络对象缓存字节数量 小于 所需数据长度,那就拿当前网络对象的所有数据,
            //如果当前网络对象缓存字节数量 大于等级 所需数据长度,那就拿所需数据长度
            int canGetLength = Math.Min(this.startIndex, needLength);

            for (int i = 0; i < canGetLength; i++)
            {
                tempList.Add(data[i]);
            }
            //去除已取出部分字节
            Tool.ByteSub(ref data, canGetLength);
            this.startIndex -= canGetLength;
            curLength        = tempList.Count - 4;
            //获取到完整数据开始解析(正常情况下,肯定是完整了)
            if (sumLength - curLength <= 0)
            {
                ProtocolEventType type     = ProtocolEventType.Null;
                byte[]            bytesArr = tempList.ToArray();
                object            o        = ProtocolMgr.Instance.StartUnPack(ref bytesArr, ref type);
                if (type != ProtocolEventType.Null)
                {
                    EventSystem.Instance.Dispatch(type, o, client);
                }
                //清空缓存
                tempList.Clear();
            }
        }
 //通用发包方法
 public void SendRequest(ProtocolNo protocolNo, ProtocolEventType type, Client client, params object[] objectArr)
 {
     try
     {
         if (objectArr.Length <= 0)
         {
             throw new Exception("参数列表为空!");
         }
         //根据协议号获取发包成员列表
         List <object> packMemberList = GetProtocolPackMemberListByProtocolNo(protocolNo);
         if (packMemberList.Count != objectArr.Length)
         {
             throw new Exception(protocolNo + "协议发包成员个数与规定个数不符合!");
         }
         //查看是否满足协议发包成员列表的顺序
         for (int i = 0; i < packMemberList.Count; i++)
         {
             if (packMemberList[i].GetType() != objectArr[i].GetType() && packMemberList[i].GetType() != objectArr[i].GetType().BaseType)
             {
                 throw new Exception(protocolNo + "协议发包成员有误!具体为第" + i + 1 + "个成员类型应为" + packMemberList[i].GetType() + ",而不是" + objectArr[i].GetType());
             }
         }
         byte[] bytes = null;
         CommonPack(ref bytes, objectArr.ToList());
         //协议号字节数组
         byte[] dataBytes = BitConverter.GetBytes((int)protocolNo);
         //事件ID字节数组
         byte[] eventIDBytes = BitConverter.GetBytes((int)type);
         client.SendResponse(eventIDBytes.Concat(dataBytes.Concat(bytes).ToArray()).ToArray());
     }
     catch (Exception e)
     {
         throw new Exception(e.ToString());
     }
 }
        /// <summary>
        /// 通用解包方法 需保证bytes数组完整性
        /// </summary>
        public object StartUnPack(ref byte[] bytes, ref ProtocolEventType type)
        {
            if (bytes.Length <= 12)
            {
                return(null);
            }
            int dataCount = ProtocolUtility.UnPackInt(ref bytes);                         //数据长度

            type = (ProtocolEventType)ProtocolUtility.UnPackInt(ref bytes);               //事件类型
            ProtocolNo protoNo        = (ProtocolNo)ProtocolUtility.UnPackInt(ref bytes); //协议号
            object     protocolObject = null;

            protocolObjectDict.TryGetValue(protoNo, out protocolObject);
            if (protocolObject != null)
            {
                List <object> list             = GetProtocolUnPackMemberListByProtocolNo(protoNo);
                List <object> unPackObjectList = new List <object>();
                //递归通用解析(即遇到是类结构的成员会继续解析该类成员),所有的数据会被会解析出来并放入List<object>第三个参数
                CommonUnPack(ref bytes, list, ref unPackObjectList);
                //多线程时要加锁!这个缓存的protocolObject协议对象仅仅是为了拷贝 only for copy!when multiple thread, it must be locked!
                ((ProtocolData)protocolObject).SetData(unPackObjectList);
                //深拷贝方式 deepCopy method(way)
                return(((ProtocolData)protocolObject).Clone());
            }
            else
            {
                throw new Exception("protocolNo" + protoNo + ",not exist protocolObject in protocolObjectDict!");
            }
        }
Пример #6
0
 /// <summary>
 /// 处理服务器接收客户端数据的解包
 /// </summary>
 /// <param name="count"></param>
 public void ReadMessage(int count)
 {
     startIndex += count;
     while (true)
     {
         //通用解包和发包
         if (startIndex > 12)
         {
             //仅有没有缓存情况才考虑完整数据
             if (tempList.Count <= 0)
             {
                 int dataCount = BitConverter.ToInt32(data, 0);
                 //1.数据完整情况
                 if (startIndex - 4 >= dataCount)
                 {
                     ProtocolEventType type = ProtocolEventType.Null;
                     object            o    = ProtocolMgr.Instance.StartUnPack(ref data, ref type);
                     if (type != ProtocolEventType.Null)
                     {
                         EventSystem.Instance.Dispatch(type, o, client);
                     }
                     startIndex -= (4 + dataCount);
                 }
                 else//2.数据不完整情况,存[0,startIndex-1]字节缓存list
                 {
                     for (int i = 0; i < startIndex; i++)
                     {
                         tempList.Add(data[i]);
                     }
                     //出现数据不完整情况,就必定是数据不完整是最后面的一组协议,故后面应该是没有任何字节的了
                     Array.Clear(data, 0, data.Length);//全清(可能会引发bug)
                     startIndex = 0;
                 }
             }
             else//3.肯定是缓存的数据后续部分(一个协议后续部分数据)到来的情况,要继续获取那一部分数据
             {
                 HandleTempList();
             }
         }
         else
         {
             //1.协议异常
             //2.有缓存的情况下,可能是缓存的相关数据到来                    (目前仅考虑)
             if (tempList.Count > 0)
             {
                 HandleTempList();
             }
             else
             {
                 //协议异常直接退出
                 return;
             }
         }
     }
 }
 public void RemoveListener(ProtocolEventType eventType, Action <object, Client> action)
 {
     if (eventDict.ContainsKey(eventType))
     {
         eventDict[eventType] -= action;
     }
     else
     {
         throw new Exception("事件系统没有该事件\nEventType=[" + eventType + "],Action<ProtocolData>=[" + action + "]");
     }
 }
Пример #8
0
 public void RemoveListener(ProtocolEventType eventType, Action <ProtocolData> action)
 {
     if (eventDict.ContainsKey(eventType))
     {
         eventDict[eventType] -= action;
     }
     else
     {
         Debug.LogError("事件系统没有该事件\nEventType=[" + eventType + "],Action<ProtocolData>=[" + action + "]");
     }
 }
 public void AddListener(ProtocolEventType eventType, Action <object, Client> action)
 {
     //***注意:这里有个小坑,用TryGetValue取出的Action<>其实是全新的,你对它进行添加action,并不会对字典里面的那个Acition<>进行改动
     //所以一定要用这种方式来进行追加,或者是你用TryGetValue拿出Action<>后,对它进行添加后,将这个Action<>放回到字典对应的key内容中
     if (eventDict.ContainsKey(eventType))
     {
         //Debug.Log("追加订阅事件,名为:" + eventType);
         eventDict[eventType] += action;
     }
     else
     {
         //Debug.Log("添加第一个订阅事件,名为:" + eventType);
         eventDict.Add(eventType, action);
     }
 }
Пример #10
0
    public void Dispatch(ProtocolEventType eventType, object data, Client client)
    {
        Action <object, Client> protoEvent;

        eventDict.TryGetValue(eventType, out protoEvent);
        if (protoEvent != null)
        {
            protoEvent(data, client);
            //Debug.Log("派发事件:" + eventType + "成功!");
        }
        else
        {
            //Debug.LogWarning("Event Dispatch失败, 事件系统没人监听该事件\nEventType=[" + eventType + "]");
        }
    }
Пример #11
0
    public void Dispatch(ProtocolEventType eventType, ProtocolData data)
    {
        Action <ProtocolData> protoEvent;

        eventDict.TryGetValue(eventType, out protoEvent);
        if (protoEvent != null)
        {
            Debug.Log("派发事件:" + eventType + "成功!");
            protoEvent(data);
        }
        else
        {
            Debug.LogWarning("Event Dispatch失败, 事件系统没人监听该事件\nEventType=[" + eventType + "]");
        }
    }
Пример #12
0
        private void registerDcManyToManyChange(object linkObject, XPMemberInfo propMember, object element, ProtocolEventType protocolEventType, bool recurse)
        {
            var oppositeProp =
                (from p in propMember.Owner.ObjectProperties.Cast <XPMemberInfo>()
                 where p.Name.EndsWith(SpecificWords.LinkedPostfix) && p != propMember
                 select p).FirstOrDefault();

            if (oppositeProp != null)
            {
                var targetObject = oppositeProp.GetValue(linkObject);
                if (targetObject != null)
                {
                    var targetModelClass = XafDeltaModule.XafApp.FindModelClass(targetObject.GetType());
                    if (targetModelClass != null)
                    {
                        var nameArray = propMember.Name.Split('_').ToList();
                        if (nameArray.Count > 2)
                        {
                            nameArray.RemoveAt(0);
                            nameArray.RemoveAt(nameArray.Count - 1);
                            var targetListName = string.Join("_", nameArray.ToArray());

                            var protEvent = new ProtocolEvent
                            {
                                Target            = targetObject,
                                OldValue          = element,
                                PropertyName      = targetListName,
                                ProtocolEventType = protocolEventType,
                                ReplicationKey    = ExtensionsHelper.GetReplicationKey(targetObject)
                            };

                            var session = ((ISessionProvider)targetObject).Session;

                            Collector.RegisterProtocolEvent(session, protEvent);

                            if (!recurse)
                            {
                                registerDcManyToManyChange(linkObject, oppositeProp, targetObject, protocolEventType, true);
                            }
                        }
                    }
                }
            }
        }
Пример #13
0
        protected void OnProtocolEvent(ProtocolEventType eventType, IProtocolStateDifference difference, IProtocolEventData now = null, IProtocolEventData then = null)
        {
            var handler = this.ProtocolEvent;

            if (handler != null) {
                handler(
                    this,
                    new ProtocolEventArgs() {
                        ProtocolEventType = eventType,
                        ProtocolType = this.ProtocolType as ProtocolType, // Required for serialization. How to get around?
                        StateDifference = difference ?? new ProtocolStateDifference(),
                        Now = now ?? new ProtocolEventData(),
                        Then = then ?? new ProtocolEventData()
                    }
                );
            }
        }
Пример #14
0
        private void registerDcManyToManyChange(object linkObject, XPMemberInfo propMember, object element, ProtocolEventType protocolEventType, bool recurse)
        {
            var oppositeProp =
                (from p in propMember.Owner.ObjectProperties.Cast<XPMemberInfo>()
                 where p.Name.EndsWith(SpecificWords.LinkedPostfix) && p != propMember
                 select p).FirstOrDefault();

            if(oppositeProp != null)
            {
                var targetObject = oppositeProp.GetValue(linkObject);
                if(targetObject != null)
                {
                    var targetModelClass = XafDeltaModule.XafApp.FindModelClass(targetObject.GetType());
                    if (targetModelClass != null)
                    {
                        var nameArray = propMember.Name.Split('_').ToList();
                        if(nameArray.Count > 2)
                        {
                            nameArray.RemoveAt(0);
                            nameArray.RemoveAt(nameArray.Count-1);
                            var targetListName = string.Join("_", nameArray.ToArray());

                            var protEvent = new ProtocolEvent
                            {
                                Target = targetObject,
                                OldValue = element,
                                PropertyName = targetListName,
                                ProtocolEventType = protocolEventType,
                                ReplicationKey = ExtensionsHelper.GetReplicationKey(targetObject)
                            };

                            var session = ((ISessionProvider)targetObject).Session;

                            Collector.RegisterProtocolEvent(session, protEvent);

                            if (!recurse)
                                registerDcManyToManyChange(linkObject, oppositeProp, targetObject, protocolEventType, true);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Resolves the collisions.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="oldObject">The old object.</param>
        /// <param name="newObjectShouldExists">if set to <c>true</c> [new object should exists].</param>
        /// <param name="newObject">The new object.</param>
        /// <param name="operationType">Type of the operation.</param>
        /// <param name="oldObjectShouldExists">if set to <c>true</c> [old object should exists].</param>
        /// <param name="targetObject">The target object.</param>
        /// <param name="memberInfo">The member info.</param>
        /// <param name="propertyIsEmpty">if set to <c>true</c> [property is empty].</param>
        /// <returns></returns>
        private CollisionResult resolveCollisions(LoadPackageRecordContext context, object oldObject,
                                                  bool newObjectShouldExists, object newObject,
                                                  ProtocolEventType operationType,
                                                  bool oldObjectShouldExists, object targetObject,
                                                  XPMemberInfo memberInfo, bool propertyIsEmpty)
        {
            var replres = CollisionResult.Default;

            if (operationType == ProtocolEventType.ObjectCreated && targetObject != null)
                replres = resolveReplicationCollision(context,
                                                      CollisionType.TargetObjectAlreadyExists, targetObject);

            if (operationType != ProtocolEventType.ObjectCreated && targetObject == null)
                replres = resolveReplicationCollision(context,
                                                      CollisionType.TargetObjectIsNotFound);

            if (!propertyIsEmpty && memberInfo == null)
                replres = resolveReplicationCollision(context,
                                                      CollisionType.MemberIsNotFound, targetObject);

            if (!propertyIsEmpty && memberInfo != null && !memberInfo.IsAssociationList && memberInfo.IsReadOnly)
                replres = resolveReplicationCollision(context,
                                                      CollisionType.ChangeReadOnlyMember, targetObject);

            if (oldObjectShouldExists && oldObject == null)
                replres = resolveReplicationCollision(context,
                                                      CollisionType.OldObjectIsNotFound, targetObject);

            if (newObjectShouldExists && newObject == null)
                replres = resolveReplicationCollision(context,
                                                      CollisionType.NewObjectIsNotFound, targetObject);
            return replres;
        }