mangosd 之 Patcher
在mangos的登录进程realmd中还有一个下载补丁的功能。用户登录的时候会附带自己的版本号,realmd会检查这个版本号,如果不是当前合法的版本号且服务器上有用户版本的补丁,那么就给用户一个响应,让其来下载对应补丁;响应中包括了补丁文件的md5和文件大小等信息。
客户端请求下载补丁的时候,realmd会为这个用户启动一个线程;在这个线程中,服务器会不断向用户推送补丁包文件数据,直到发送完毕,看看代码:
/// Send content of patch file to the client
void PatcherRunnable::run()
{
XFER_DATA_STRUCT xfdata;
xfdata.opcode = XFER_DATA;
while(!feof(mySocket->pPatch) && mySocket->Ready())
{
///- Wait until output buffer is reasonably empty
while(mySocket->Ready() && mySocket->IsLag())
{
ZThread::Thread::sleep(1);
}
///- And send content of the patch file to the client
xfdata.data_size=fread(&xfdata.data,1,ChunkSize,mySocket->pPatch);
mySocket->SendBuf((const char*)&xfdata,xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize));
}
}
比较有意思的地方是,如果服务器发现网络“卡”的时候,就休息1秒为间隔休息,是这样判断“卡”的:
/// Check if there is lag on the connection to the client
bool AuthSocket::IsLag()
{
return (TCP_BUFSIZE_READ-obuf.GetLength()< 2*ChunkSize);
}
即发送的缓冲区中(CircularBuffer)中的空闲空间小于2*ChunkSize,而ChunkSize是每次从补丁文件中读取的数据块大小。即服务器发现缓冲区中放不下两次读取的数据时,就停下来休息,直到空间可用。
阅读(1750) | 评论(0) | 转发(0) |