📄 nhcbiznetdriver.pas
字号:
constructor TTcpPacketRecverList.Create;
begin
inherited;
ThreadSafe := True;
FRecverList := TObjectList.Create(False, True);
end;
destructor TTcpPacketRecverList.Destroy;
begin
FRecverList.Free;
inherited;
end;
function TTcpPacketRecverList.FindConnection(Connection: TTcpConnection): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to FRecverList.Count - 1 do
if TTcpPacketReceiver(FRecverList[I]).FConnection = Connection then
begin
Result := I;
Break;
end;
end;
procedure TTcpPacketRecverList.AddConnection(Connection: TTcpConnection;
MaxRecvPktCount: Integer);
begin
Lock;
try
if FindConnection(Connection) = -1 then
FRecverList.Add(TTcpPacketReceiver.Create(Connection, MaxRecvPktCount), False);
finally
Unlock;
end;
end;
procedure TTcpPacketRecverList.RemoveConnection(Connection: TTcpConnection);
var
I: Integer;
begin
Lock;
try
I := FindConnection(Connection);
if I >= 0 then
FRecverList.Delete(I);
finally
Unlock;
end;
end;
procedure TTcpPacketRecverList.Process;
var
I: Integer;
Recver: TTcpPacketReceiver;
begin
Lock;
try
for I := FRecverList.Count - 1 downto 0 do
begin
Recver := TTcpPacketReceiver(FRecverList[I]);
Recver.Process;
if Recver.Done then
FRecverList.Delete(I);
end;
finally
Unlock;
end;
end;
{ TNetDriverExecuteProcessor }
constructor TNetDriverExecuteProcessor.Create;
const
PsrLoopInterval = 1; // 处理器的循环周期(毫秒)
begin
inherited Create;
SleepController.SleepMSecs := PsrLoopInterval;
end;
destructor TNetDriverExecuteProcessor.Destroy;
begin
inherited;
end;
//-----------------------------------------------------------------------------
// 描述: 处理器工作函数
//-----------------------------------------------------------------------------
procedure TNetDriverExecuteProcessor.Process;
begin
NetMgr.BizNetDriver.FUdpTaskExecutor.Execute;
NetMgr.BizNetDriver.FTcpTaskExecutor.Execute;
NetMgr.BizNetDriver.FTcpPacketRecverList.Process;
end;
{ TNetDriverFollowProcessor }
constructor TNetDriverFollowProcessor.Create;
const
PsrLoopInterval = 10; // 处理器的循环周期(毫秒)
begin
inherited Create;
ThreadSafe := True;
SleepController.SleepMSecs := PsrLoopInterval;
end;
destructor TNetDriverFollowProcessor.Destroy;
begin
inherited;
end;
//-----------------------------------------------------------------------------
// 描述: 将UDP包缓冲器中的数据包以 sync 方式继续分派
//-----------------------------------------------------------------------------
procedure TNetDriverFollowProcessor.ProcessUdpPacketCache;
var
Packet: TUdpPacket;
begin
while True do
begin
Packet := NetMgr.BizNetDriver.FUdpPacketCache.Extract;
if Packet <> nil then
begin
NetMgr.BizNetDriver.DeliverUdpPacket(Packet.PacketBuffer^,
Packet.PacketSize, Packet.PeerAddr);
Packet.Free;
end else
Break;
end;
end;
//-----------------------------------------------------------------------------
// 描述: 扫描 UdpDoneTaskList,进行事件处理
//-----------------------------------------------------------------------------
procedure TNetDriverFollowProcessor.ProcessUdpDoneTaskList;
var
Task: TUdpTask;
begin
while True do
begin
Task := NetMgr.BizNetDriver.FUdpDoneTaskList.Extract(0);
if Task <> nil then
begin
if Assigned(Task.FOnTaskResult) then
Task.FOnTaskResult(Task);
Task.Free;
end else
Break;
end;
end;
//-----------------------------------------------------------------------------
// 描述: 将TCP包缓冲器中的数据包以 sync 方式继续分派
//-----------------------------------------------------------------------------
procedure TNetDriverFollowProcessor.ProcessTcpPacketCache;
var
Packet: TTcpPacket;
begin
while True do
begin
Packet := NetMgr.BizNetDriver.FTcpPacketCache.Extract;
if Packet <> nil then
begin
NetMgr.BizNetDriver.DeliverTcpPacket(Packet.Connection,
Packet.PacketBuffer^, Packet.PacketSize);
Packet.Free;
end else
Break;
end;
end;
//-----------------------------------------------------------------------------
// 描述: 扫描 TcpDoneTaskList,进行事件处理
//-----------------------------------------------------------------------------
procedure TNetDriverFollowProcessor.ProcessTcpDoneTaskList;
var
Task: TTcpTask;
begin
while True do
begin
Task := NetMgr.BizNetDriver.FTcpDoneTaskList.Extract(0);
if Task <> nil then
begin
if Assigned(Task.FOnTaskResult) then
Task.FOnTaskResult(Task);
Task.Free;
end else
Break;
end;
end;
//-----------------------------------------------------------------------------
// 描述: 处理器工作函数
//-----------------------------------------------------------------------------
procedure TNetDriverFollowProcessor.Process;
begin
CurrentThread.Synchronize(ProcessUdpPacketCache);
CurrentThread.Synchronize(ProcessUdpDoneTaskList);
CurrentThread.Synchronize(ProcessTcpPacketCache);
CurrentThread.Synchronize(ProcessTcpDoneTaskList);
end;
{ TBizNetDriver }
constructor TBizNetDriver.Create(ANetIO: TNetIO);
begin
inherited Create(ANetIO);
Randomize;
FUdpTaskExecutor := TUdpTaskExecutor.Create;
FUdpSeqIdAlloc := TSeqAllocator.Create(Random(MaxWord) + 1);
FUdpPacketCache := TUdpPacketCache.Create(MaxUdpPacketCacheSize);
FUdpDoneTaskList := TUdpTaskList.Create;
FUdpDupChecker := TUdpPacketDupChecker.Create;
FTcpTaskExecutor := TTcpTaskExecutor.Create;
FTcpDoneTaskList := TTcpTaskList.Create;
FTcpPacketRecverList := TTcpPacketRecverList.Create;
FTcpPacketCache := TTcpPacketCache.Create(MaxTcpPacketCacheSize);
FExecuteProcessor := TNetDriverExecuteProcessor.Create;
FFollowProcessor := TNetDriverFollowProcessor.Create;
InitDupPktChkActionCodes;
end;
destructor TBizNetDriver.Destroy;
begin
FFollowProcessor.Free;
FExecuteProcessor.Free;
FTcpPacketCache.Free;
FTcpPacketRecverList.Free;
FTcpDoneTaskList.Free;
FTcpTaskExecutor.Free;
FUdpDupChecker.Free;
FUdpDoneTaskList.Free;
FUdpPacketCache.Free;
FUdpSeqIdAlloc.Free;
FUdpTaskExecutor.Free;
inherited;
end;
//-----------------------------------------------------------------------------
// 描述: 初始化需要检测重复包的动作代码
//-----------------------------------------------------------------------------
procedure TBizNetDriver.InitDupPktChkActionCodes;
begin
end;
//-----------------------------------------------------------------------------
// 描述: 执行 "发送UDP数据包" 的动作
//-----------------------------------------------------------------------------
procedure TBizNetDriver.PerformSendUdpPacket(Packet: TPacket;
const PeerAddr: TPeerAddress; SendTimes: Integer);
begin
Packet.EnsurePacked;
NetIO.UdpServer.SendBuffer(Packet.Buffer^, Packet.Size, PeerAddr, SendTimes);
end;
//-----------------------------------------------------------------------------
// 描述: 处理收到的UDP应答包
//-----------------------------------------------------------------------------
procedure TBizNetDriver.DoProcessUdpAckPacket(const PacketBuffer;
PacketSize: Integer; const PeerAddr: TPeerAddress);
begin
FUdpTaskExecutor.ProcessAckPacket(PacketBuffer, PacketSize, PeerAddr);
end;
//-----------------------------------------------------------------------------
// 描述: 处理收到的TCP应答包
//-----------------------------------------------------------------------------
procedure TBizNetDriver.DoProcessTcpAckPacket(Connection: TTcpConnection;
const PacketBuffer; PacketSize: Integer);
begin
FTcpTaskExecutor.ProcessAckPacket(PacketBuffer, PacketSize);
end;
//-----------------------------------------------------------------------------
// 描述: UDP数据包过滤器
// 返回:
// True - 有效包
// False - 无效包
//-----------------------------------------------------------------------------
function TBizNetDriver.FilterUdpPacket(const PacketBuffer; PacketSize: Integer): Boolean;
//var
// HeaderPtr: PBizUdpPacketHeader;
begin
// HeaderPtr := PBizUdpPacketHeader(@PacketBuffer);
// 如果数据包大小 < 首部大小,则认为无效
if PacketSize < SizeOf(TBizUdpPacketHeader) then
begin
Result := False;
Exit;
end;
{ TODO : }
// // 只接收 "UDP业务包"
// if TUdpPacketProto(HeaderPtr.PacketProto) <> ppBusiness then
// begin
// Result := False;
// Exit;
// end;
//
// // 检查校验和是否正确
// if HeaderPtr^.CheckSum <> TBizUdpPacket.CalcHeaderCheckSum(HeaderPtr^) then
// begin
// Result := False;
// Exit;
// end;
Result := True;
end;
//-----------------------------------------------------------------------------
// 描述: 收到 NetIO 分派过来的UDP数据
//-----------------------------------------------------------------------------
procedure TBizNetDriver.DispatchUdpPacket(const PacketBuffer;
PacketSize: Integer; const PeerAddr: TPeerAddress);
var
HeaderPtr: PBizUdpPacketHeader;
begin
HeaderPtr := PBizUdpPacketHeader(@PacketBuffer);
case HeaderPtr.ActionCode of
acAck: // 应答包
DoProcessUdpAckPacket(PacketBuffer, PacketSize, PeerAddr);
else begin
// 放入缓冲器,等待继续分派
FUdpPacketCache.Add(PacketBuffer, PacketSize, PeerAddr);
end;
end;
end;
//-----------------------------------------------------------------------------
// 描述: 收到分派过来的TCP数据
//-----------------------------------------------------------------------------
procedure TBizNetDriver.DispatchTcpPacket(Connection: TTcpConnection;
const PacketBuffer; PacketSize: Integer);
var
HeaderPtr: PBizTcpPacketHeader;
begin
HeaderPtr := PBizTcpPacketHeader(@PacketBuffer);
case HeaderPtr.ActionCode of
acAck: // 应答包
DoProcessTcpAckPacket(Connection, PacketBuffer, PacketSize);
else begin
// 放入缓冲器,等待继续分派
FTcpPacketCache.Add(Connection, PacketBuffer, PacketSize);
end;
end;
end;
//-----------------------------------------------------------------------------
// 描述: 初始化工作(对象创建之后、开始工作之前)
// 备注: 若无法初始化,必须抛出异常。
//-----------------------------------------------------------------------------
procedure TBizNetDriver.Initialize;
begin
inherited;
FExecuteProcessor.Start;
FFollowProcessor.Start;
end;
//-----------------------------------------------------------------------------
// 描述: 结束化工作
//-----------------------------------------------------------------------------
procedure TBizNetDriver.Finalize;
begin
FFollowProcessor.Stop;
FExecuteProcessor.Stop;
inherited;
end;
//-----------------------------------------------------------------------------
// 描述: 登录之前的处理
//-----------------------------------------------------------------------------
procedure TBizNetDriver.DoBeforeLogin;
begin
inherited;
end;
//-----------------------------------------------------------------------------
// 描述: 注销之前的处理
//-----------------------------------------------------------------------------
procedure TBizNetDriver.DoBeforeLogout;
begin
inherited;
end;
//-----------------------------------------------------------------------------
// 描述: 登录成功之后的处理
//-----------------------------------------------------------------------------
procedure TBizNetDriver.DoAfterLogin;
begin
inherited;
end;
//-----------------------------------------------------------------------------
// 描述: 离线之后的处理
//-----------------------------------------------------------------------------
procedure TBizNetDriver.DoAfterLogout;
begin
// 离线后不可有网络数据业务
FUdpTaskExecutor.Clear;
FUdpDoneTaskList.Clear;
FTcpTaskExecutor.Clear;
FTcpDoneTaskList.Clear;
inherited;
end;
//-----------------------------------------------------------------------------
// 描述: 垃圾收集
//-----------------------------------------------------------------------------
procedure TBizNetDriver.CollectGarbage;
begin
inherited;
end;
//-----------------------------------------------------------------------------
// 描述: 发送UDP包给任何地址
// 参数:
// Packet - 待发送的数据包 (调用者创建,NetDriver 负责释放)
// PeerAddr - 目的地址
// NeedAck - 是否需要应答包
// OnTaskResult - 发送结果事件
// Caller - 调用者对象
// SendTimes - 最多发送几次 (若不需应答包,则表示重发几次)
// RecvTimeout - 等待接收应答包的时限(毫秒)
//-----------------------------------------------------------------------------
procedure TBizNetDriver.SendUdpPacket(Packet: TBizUdpPacket;
const PeerAddr: TPeerAddress; NeedAck: Boolean;
OnTaskResult: TUdpTaskResultEvent; Caller: TOb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -