/* Sog 游戏基础库 2016 by zouwei */ using System; using System.Threading; using System.Collections.Generic; namespace Sog { 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(); //头 { // BigMessageStart = BigMessageHeader + (old MessageHeader + full msg len + split msg data) // [20] = 原消息头(8/16) + 完整的消息长度(4) byte[] headBytes = new byte[20]; // 16 + 4 int headLength = ProtoPackerFactory.Instance.GetProtoCSStructPacker().PackHeader(message.Header, headBytes); // 完整的数据长度 byte[] lenghtBytes = BitConverter.GetBytes(message.Header.Length); Buffer.BlockCopy(lenghtBytes, 0, headBytes, headLength, lenghtBytes.Length); headLength += lenghtBytes.Length; // 4 MessageData startMessageData = new MessageData(); startMessageData.Header.Type = (int)SpecialMessageType.BigMessageStart; startMessageData.MallocData(headLength + BigDataMessageLength); // BigMessageBuffer = 原消息头(8/16) + 完整的消息长度(4) + 切分后的部分消息数据(64K - 100) Buffer.BlockCopy(headBytes, 0, startMessageData.Buffer.Data, 0, headLength); Buffer.BlockCopy(message.Buffer.Data, 0, startMessageData.Buffer.Data, headLength, BigDataMessageLength); startMessageData.Header.Length = startMessageData.Buffer.Length; dataOffset += BigDataMessageLength; list.Add(startMessageData); } //中间消息 while(message.Buffer.Length > dataOffset) { // BigMessageTrans = BigMessageHeader + split msg data MessageData transMessageData = new MessageData(); transMessageData.Header.Type = (int)SpecialMessageType.BigMessageTrans; transMessageData.Header.ObjectID = 0; transMessageData.Header.ServerID = 0; int transLength = message.Buffer.Length - dataOffset; if(transLength > BigDataMessageLength) { transLength = BigDataMessageLength; } transMessageData.MallocData(transLength); Buffer.BlockCopy(message.Buffer.Data, dataOffset, transMessageData.Buffer.Data, 0, transLength); transMessageData.Header.Length = transLength; 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 = new MessageHeader(); foreach (var one in bigDataQueue) { if(messageCout == 0 && one.Header.Type != (int)SpecialMessageType.BigMessageStart) { TraceLog.Error("BigDataMessage.TryGetFullBigDataMessage error, first bigmsg type != BigMessageStart"); foreach(var message in bigDataQueue) { message.FreeData(); } bigDataQueue.Clear(); return; } //取头 if(messageCout == 0) { headLength = ProtoPackerFactory.Instance.GetProtoCSStructPacker().UnPackHeader(one.Buffer.Data,0,one.Buffer.Length, ref header); fullMessageLength = BitConverter.ToInt32(one.Buffer.Data, headLength); headLength += 4; totalLength += one.Header.Length - headLength; } else { totalLength += one.Header.Length; } messageCout++; //完整了 if(totalLength == fullMessageLength) { break; } } if (totalLength > 0 && totalLength == fullMessageLength) { MessageData fullMessageData = new MessageData(); fullMessageData.Header = header; fullMessageData.Header.Length = fullMessageLength; fullMessageData.MallocData(fullMessageLength); int offset = 0; { //头 MessageData startMessage = bigDataQueue.Dequeue(); Buffer.BlockCopy(startMessage.Buffer.Data, headLength, fullMessageData.Buffer.Data, 0, startMessage.Buffer.Length - headLength); offset += startMessage.Buffer.Length - headLength; startMessage.FreeData(); } messageCout--; while(messageCout > 0) { MessageData transMessage = bigDataQueue.Dequeue(); Buffer.BlockCopy(transMessage.Buffer.Data, 0, fullMessageData.Buffer.Data, offset, transMessage.Buffer.Length); offset += transMessage.Buffer.Length; messageCout--; transMessage.FreeData(); } outQueue.Enqueue(fullMessageData); TraceLog.Trace("BigDataMessage.TryGetFullBigDataMessage get one bigDataMessage type {0} length {1}", header.Type, fullMessageLength); } } } }