作者:佚名
更新时间:2021-03-11
浏览次数:
RunGate具有三个Socket对象,一个用于发送到M2,另一个用于接收客户端连接。还有一个连接控制台(当然这是绑定到控制台的,通常不需要手动启动,但是私服架设者可以在私服中使用它很方便) 控制台套接字将定期发送保持活动数据包到控制台。如果未发送,则控制台必须知道运行器没有响应或已关闭,然后可以立即将其打开。纯粹是为了简化私服个虚假的错误。 实际上,只有两个Socket对象是最重要的。 M2Sokcet和ClientSocket。 当然,整个结构是使用的典型生产者-消费者模型。但是代码结构还不清楚。消息处理是使用Timer而不是线程进行处理。 程序通过一个常量定义堆栈上的会话数。当程序开始运行时,堆栈上将有一个数组来保存会话信息。会话信息是一种结构,并且在内部记录会话信息,例如连接时间,数据包大小 最后一次移动的时间,最后一次通信的时间,等等。 有客户端连接时。在预缩放数组中会发现未使用的空间。初始化此数组的内容传奇sf多线程网关控制器,以使当前客户端连接保持在该会话内。 当从客户那里收到信息时,将进行一系列的法律验证或保护。最后传奇sf多线程网关控制器,将消息生成为消息正文: ReviceMsgList.Add(UserData); //添加到接收到的消息列表中。 从服务器接收消息时。将邮件头转换为以下邮件格式: TMsgHeader = packed record
dwCode: LongWord;
nSocket: Integer;
wGSocketIdx: Word;
wIdent: Word;
wUserListIndex: Integer;
nLength: Integer;
end;
记录消息的类型,长度和套接字句柄。根据wIdent的值 case pMsg.wIdent of
GM_CHECKSERVER: begin //客户端需要先验证网关
boCheckServerFail := False;
dwCheckServerTimeMin := GetTickCount - dwCheckServerTick;
if dwCheckServerTimeMin > dwCheckServerTimeMax then
dwCheckServerTimeMax := dwCheckServerTimeMin;
//dwCheckServerTick := GetTickCount();
end;
GM_SERVERUSERINDEX: begin //wGSocketIdx 为服务端的Socket句柄 这句主要是修改wUserListIndex。暂时没看出要干嘛
if (pMsg.wGSocketIdx < RUNATEMAXSESSION) and (pMsg.nSocket =
SessionArray[pMsg.wGSocketIdx].nSckHandle) then begin
SessionArray[pMsg.wGSocketIdx].nUserListIndex := pMsg.wUserListIndex;
end;
end;
GM_RECEIVE_OK: begin
{dwCheckServerTimeMin := GetTickCount - dwCheckRecviceTick;
if dwCheckServerTimeMin > dwCheckServerTimeMax then dwCheckServerTimeMax := dwCheckServerTimeMin;
dwCheckRecviceTick := GetTickCount(); }
SendServerMsg(GM_RECEIVE_OK, 0, 0, 0, 0, nil); //消息到达处理,貌似很没必要吧。应该是M2会做一些处理
end;
GM_DATA: begin
ProcessMakeSocketStr(pMsg.nSocket, pMsg.wGSocketIdx, MsgBuff, pMsg.nLength);//进行编码处理后 加入到每个会话的列表(实际是string)。此时并不是发送,并将消息加入SendMsgList;
end;
GM_TEST: begin
end;
|