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.
161 lines
5.6 KiB
161 lines
5.6 KiB
1 month ago
|
/*
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|