You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

167 lines
6.1 KiB

/*
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<MessageData> SplitMessage(MessageData message)
{
int dataOffset = 0;
List<MessageData> list = new List<MessageData>();
//头
{
// 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<MessageData> bigDataQueue, Queue<MessageData> 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);
}
}
}
}