/* Sog 游戏基础库 2016 by zouwei */ using System; using System.Threading; using System.Collections.Generic; namespace SogClient { public static class BigDataMessage { public const int MessageLenghMinNeedSplit = 1024 * 64 - 100; public const int BigDataMessageLength = 1024 * 64 - 100; public const int BigDataMessageFullMaxLength = 1024 * 1024 * 2; //最大2M大小 public static List SplitMessage(MessageData message) { int dataOffset = 0; List list = new List(); //头 { MessageData startMessageData = new MessageData(); startMessageData.Header.Type = (int)SpecialMessageType.BigMessageStart; startMessageData.Header.ObjectID = 0; startMessageData.Header.ServerID = 0; //原来消息头 byte[] headBytes = new byte[20];//最多16+4字节长度 int headLength = ProtoPackerFactory.Instance.GetProtoPacker().PackHeader(message.Header, headBytes); byte[] lenghtBytes = BitConverter.GetBytes(message.Header.Length); Buffer.BlockCopy(lenghtBytes, 0, headBytes, headLength, lenghtBytes.Length); headLength += lenghtBytes.Length;//4 byte[] startdata = new byte[headLength + BigDataMessageLength]; Buffer.BlockCopy(headBytes, 0, startdata, 0, headLength); Buffer.BlockCopy(message.Data, 0, startdata, headLength, BigDataMessageLength); startMessageData.Data = startdata; startMessageData.Header.Length = startdata.Length; dataOffset += BigDataMessageLength; list.Add(startMessageData); } //中间消息 while(message.Data.Length > dataOffset) { MessageData transMessageData = new MessageData(); transMessageData.Header.Type = (int)SpecialMessageType.BigMessageTrans; transMessageData.Header.ObjectID = 0; transMessageData.Header.ServerID = 0; int transLength = message.Data.Length - dataOffset; if(transLength > BigDataMessageLength) { transLength = BigDataMessageLength; } byte[] transdata = new byte[transLength]; Buffer.BlockCopy(message.Data, dataOffset, transdata, 0, transLength); transMessageData.Data = transdata; transMessageData.Header.Length = transdata.Length; dataOffset += transLength; list.Add(transMessageData); } return list; } public static void TryGetFullBigDataMessage(Queue bigDataQueue, Queue outQueue) { if(bigDataQueue.Count == 0) { return; } int messageCout = 0; int totalLength = 0; int fullMessageLength = 0; int headLength = 0; MessageHeader header; header.Type = 0; header.Length = 0; header.ObjectID = 0; header.ServerID = 0; foreach (var one in bigDataQueue) { if(messageCout == 0 && one.Header.Type != (int)SpecialMessageType.BigMessageStart) { TraceLog.Error("BigDataMessage.TryGetFullBigDataMessage error, first bigmsg type != BigMessageStart"); bigDataQueue.Clear(); return; } //取头 if(messageCout == 0) { headLength = ProtoPackerFactory.Instance.GetProtoPacker().UnPackHeader(one.Data,0,one.Data.Length, ref header); fullMessageLength = BitConverter.ToInt32(one.Data, headLength); headLength += 4; totalLength += one.Header.Length - headLength; } else { totalLength += one.Header.Length; } messageCout++; //完整了 if(totalLength == fullMessageLength) { break; } } if (totalLength > 0 && totalLength == fullMessageLength) { byte[] data = new byte[fullMessageLength]; int offset = 0; { //头 MessageData startMessage = bigDataQueue.Dequeue(); Buffer.BlockCopy(startMessage.Data, headLength, data, 0, startMessage.Data.Length - headLength); offset += startMessage.Data.Length - headLength; } messageCout--; while(messageCout > 0) { MessageData transMessage = bigDataQueue.Dequeue(); Buffer.BlockCopy(transMessage.Data, 0, data, offset, transMessage.Data.Length); offset += transMessage.Data.Length; messageCout--; } MessageData fullMessageData; fullMessageData.Header = header; fullMessageData.Header.Length = fullMessageLength; fullMessageData.Data = data; outQueue.Enqueue(fullMessageData); TraceLog.Trace("BigDataMessage.TryGetFullBigDataMessage get one bigDataMessage type {0} length {1}", header.Type, fullMessageLength); } } } }