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.
 
 
 
 
 
 

160 lines
5.6 KiB

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