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
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|