/// <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); } }
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(); } }
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!"); } }
/// <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 + "]"); } }
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); } }
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 + "]"); } }
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 + "]"); } }
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); } } } } } }
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() } ); } }
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; }