//new data received event. void RawReceivedData(object sender, LightSingleArgEventArgs <byte[]> e) { List <T> objs = null; #region parse raw data. if (_rawChannel.Buffer == null) { objs = _protocolStack.Parse <T>(e.Target); } else { List <byte[]> data = _rawChannel.Buffer.Add(e.Target); if (data != null && data.Count > 0) { objs = new List <T>(); foreach (var d in data) { List <T> list = _protocolStack.Parse <T>(d); if (list != null && list.Count > 0) { objs.AddRange(list); } } } } #endregion if (objs != null) { ReceivedMessageHandler(new LightSingleArgEventArgs <List <T> >(objs)); } }
//has data can be receive. void RawChannelReceivedData(object sender, LightSingleArgEventArgs <byte[]> e) { List <T> objs = null; #region parse raw data. if (_channel.Buffer == null) { objs = _protocolStack.Parse <T>(e.Target); } else { List <byte[]> data = _channel.Buffer.Add(e.Target); if (data != null && data.Count > 0) { objs = new List <T>(); foreach (var d in data) { List <T> list = _protocolStack.Parse <T>(d); if (list != null && list.Count > 0) { objs.AddRange(list); } } } } #endregion if (objs == null) { return; } IMessageSpy <T> spy; //dispatch message. foreach (T msg in objs) { //this message cannot be spy. if (!_spys.TryGetValue(msg.GetType(), out spy)) { UnknownSpyMessageHandler(new LightSingleArgEventArgs <T>(msg)); continue; } T rspMessag; if ((rspMessag = spy.Spy(msg)) == null) { continue; } //use threadpool to send response msg. Task.Factory.StartNew(delegate { SendCallbackAsync(rspMessag); }); } }
/// <summary> /// 追加一个新的数据段 /// </summary> /// <param name="args">数据段接受参数</param> public void Append(SegmentReceiveEventArgs args) { #region Step 1, check-on args. if (_head == null) { _head = _tail = new SegmentNode(args); } else { _tail.Next = new SegmentNode(args); _tail = _tail.Next; } #endregion #region Step 2, check bytes enough & pickup data. int msgSize; //RESET next node for current expression. SegmentNode nextNode = _head; List <T> msgs = new List <T>(); //check whatever bytes can be parse. while (nextNode != null && (msgSize = CheckBytes(nextNode)) > 0) { //direct parse. if (nextNode.RemainingSize >= msgSize) { List <T> list = _protocolStack.Parse <T>(nextNode.Args.GetStub().Segment.Segment.Array, nextNode.Args.GetStub().Segment.UsedOffset, msgSize); if (list != null) { msgs.AddRange(list); } nextNode.Args.GetStub().Segment.UsedBytes += msgSize; //ChannelCounter.Instance.RateOfDirectParse.Increment(); if (nextNode.RemainingSize > 0) { continue; } //giveup current fixed stub. nextNode.Args.Complete(); _head = nextNode = nextNode.Next; if (_head != null) { continue; } //Tail node must be null, if the head node has no value. _tail = null; //publish messages. if (msgs.Count > 0) { ParseSucceedHandler(new LightSingleArgEventArgs <List <T> >(msgs)); } return; } //create sub-list for all ava-data segment path. int remainingSize = msgSize - nextNode.RemainingSize; SegmentNode childHead = (SegmentNode)nextNode.Clone(); SegmentNode childTail = (SegmentNode)nextNode.Clone(); SegmentNode tempNode = nextNode; SegmentNode lastRealNode = null; SegmentNode cloneLastRealNode = null; do { tempNode = tempNode.Next; if (tempNode == null) { break; } remainingSize -= tempNode.RemainingSize; //clone target node for child-list. lastRealNode = tempNode; SegmentNode cloneNode = (SegmentNode)tempNode.Clone(); cloneNode.Next = null; childTail.Next = cloneNode; childTail = childTail.Next; } while (remainingSize > 0); //cannot get enough length for message really binary data. if (remainingSize > 0) { if (msgs.Count > 0) { ParseSucceedHandler(new LightSingleArgEventArgs <List <T> >(msgs)); } return; } //copy data from child-list! int dataOffset = 0; byte[] data = new byte[msgSize]; int dataRemainingCount = data.Length; int usedBytes; int lastUserBytes = 0; while (childHead != null && dataRemainingCount > 0) { cloneLastRealNode = childHead; Buffer.BlockCopy(childHead.Args.GetStub().Segment.Segment.Array, childHead.Args.GetStub().Segment.UsedOffset, data, dataOffset, (usedBytes = (childHead.RemainingSize > dataRemainingCount ? dataRemainingCount : childHead.RemainingSize))); dataOffset += usedBytes; dataRemainingCount -= usedBytes; childHead.Args.GetStub().Segment.UsedBytes += usedBytes; lastUserBytes = childHead.Args.GetStub().Segment.UsedBytes; if (childHead.RemainingSize <= 0) { //giveup current fixed stub. childHead.Args.Complete(); childHead = childHead.Next; } } if (cloneLastRealNode.RemainingSize - lastUserBytes == 0 && lastRealNode.Next == null) { _head = nextNode = null; } else if (cloneLastRealNode.RemainingSize - lastUserBytes == 0 && lastRealNode.Next != null) { _head = nextNode = lastRealNode.Next; } else { lastRealNode.Args.GetStub().Segment.UsedBytes = lastUserBytes; _head = nextNode = lastRealNode; } //_head = nextNode = ((cloneLastRealNode.RemainingSize == 0 && lastRealNode.Next == null) ? null : lastRealNode); List <T> list1 = _protocolStack.Parse <T>(data); if (list1 != null) { msgs.AddRange(list1); } } //publish messages. if (msgs.Count > 0) { ParseSucceedHandler(new LightSingleArgEventArgs <List <T> >(msgs)); } #endregion }