Changeset 365 for trunk/Network


Ignore:
Timestamp:
Apr 13, 2021, 9:57:36 PM (4 years ago)
Author:
chronos
Message:
  • Modified: Improved unfinished network client data handling.
Location:
trunk/Network
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Network/UNetworkClient.pas

    r364 r365  
    88  Classes, SysUtils, fpsock, fpAsync, Protocol;
    99
    10 
    11 procedure Client(Command, Player: Integer; var Data); stdcall;
    12 
    13 
    14 implementation
    15 
    16 uses
    17   LocalPlayer, Global;
    18 
    1910type
    20 
    2111  { TTCPClientThread }
    2212
     
    3323    TCPClientThread: TTCPClientThread;
    3424    ReceiveBuffer: TMemoryStream;
    35     procedure AppendStream(Stream: TStream; SourceStream: TStream);
    3625    procedure DataAvailableExecute(Sender: TObject);
    3726    procedure ConnectionStateChangeExecute(Sender: TClientConnectionSocket;
    3827      OldState, NewState: TConnectionState);
     28    procedure DataAvailableSync;
    3929  public
    4030    AuxServer: TServerCall;
     
    4939var
    5040  NetworkClient: TNetworkClient;
     41
     42procedure Client(Command, Player: Integer; var Data); stdcall;
     43
     44
     45implementation
     46
     47uses
     48  LocalPlayer, Global, UNetworkCommon;
     49
     50function LocalServer(Command, Player, Subject: Integer; var Data): Integer; stdcall;
     51begin
     52  if Assigned(NetworkClient) then
     53    Result := NetworkClient.Server(TCommand(Command), Player, Subject, Data);
     54end;
    5155
    5256procedure Client(Command, Player: Integer; var Data);
     
    7882{ TNetworkClient }
    7983
    80 procedure TNetworkClient.AppendStream(Stream: TStream; SourceStream: TStream);
    81 var
    82   Buffer: array of Byte;
    83   ReadCount: Integer;
    84   Base: Integer;
    85 const
    86   ChunkSize = 4096;
     84procedure TNetworkClient.DataAvailableExecute(Sender: TObject);
    8785begin
    88   SetLength(Buffer, 0);
    89   Base := 0;
    90   repeat
    91     SetLength(Buffer, Length(Buffer) + ChunkSize);
    92     ReadCount := SourceStream.Read(Buffer[Base], ChunkSize);
    93     Inc(Base, ReadCount);
    94     SetLength(Buffer, Base);
    95   until ReadCount < ChunkSize;
    96 
    97   if Length(Buffer) > 0 then begin
    98     Stream.Position := Stream.Size;
    99     Stream.Write(Buffer[0], Length(Buffer));
    100   end;
    101 end;
    102 
    103 procedure TNetworkClient.DataAvailableExecute(Sender: TObject);
    104 var
    105   Command: Integer;
    106   Player: Integer;
    107   Data: array of Byte;
    108 begin
    109   AppendStream(ReceiveBuffer, TCPClient.Stream);
    110   ReceiveBuffer.Position := 0;
    111   Command := Integer(ReceiveBuffer.ReadDWord);
    112   Player := Integer(ReceiveBuffer.ReadDWord);
    113   SetLength(Data, GetCommandDataSize(TCommand(Command)));
    114   if Length(Data) > 0 then
    115     LocalClient(Command, Player, Data[0])
    116     else LocalClient(Command, Player, nil^);
    117 
    118   // Remove already read data from start of memory stream
    119   Move(PByte(ReceiveBuffer.Memory + ReceiveBuffer.Position)^, ReceiveBuffer.Memory^, ReceiveBuffer.Size - ReceiveBuffer.Position);
    120   ReceiveBuffer.SetSize(ReceiveBuffer.Size - ReceiveBuffer.Position);
     86  TCPClientThread.Synchronize(TCPClientThread, DataAvailableSync);
    12187
    12288  ClientEventLoop.ClearDataAvailableNotify(DataAvailableHandle);
     
    12995  if NewState = connConnected then
    13096    DataAvailableHandle := ClientEventLoop.SetDataAvailableNotify(TCPClient.Stream.Handle, DataAvailableExecute, nil);
     97end;
     98
     99procedure TNetworkClient.DataAvailableSync;
     100var
     101  Command: Integer;
     102  ReadCount: Integer;
     103  Player: Integer;
     104  Data: array of Byte;
     105begin
     106  StreamAppend(ReceiveBuffer, TCPClient.Stream);
     107  while ReceiveBuffer.Size >= 2 * SizeOf(Integer) do begin
     108    ReceiveBuffer.Position := 0;
     109    Command := Integer(ReceiveBuffer.ReadDWord);
     110    Player := Integer(ReceiveBuffer.ReadDWord);
     111    SetLength(Data, GetCommandDataSize(TCommand(Command)));
     112    if Length(Data) > 0 then begin
     113      ReadCount := ReceiveBuffer.Read(Data[0], Length(Data));
     114      SetLength(Data, ReadCount);
     115    end;
     116
     117    // Rewrite server address received from network by local handler
     118    if Command = cInitModule then begin
     119      PInitModuleData(@Data[0])^.Server := LocalServer;
     120    end;
     121
     122    if Length(Data) > 0 then
     123      LocalClient(Command, Player, Data[0])
     124      else LocalClient(Command, Player, nil^);
     125
     126    StreamRemoveRead(ReceiveBuffer);
     127  end;
    131128end;
    132129
  • trunk/Network/UNetworkServer.pas

    r364 r365  
    2424  private
    2525    DataAvailableHandle: Pointer;
     26    ReceiveBuffer: TMemoryStream;
    2627    procedure DisconnectExecute(Sender: TObject);
     28    procedure DataAvailableSync;
     29    procedure DataAvailableExecute(Sender: TObject);
    2730  public
    2831    NetworkServer: TNetworkServer;
     
    3134    Player: TNetworkServerPlayer;
    3235    Connected: Boolean;
    33     procedure DataAvailableExecute(Sender: TObject);
    3436    procedure Run;
    3537    constructor Create;
     
    8486
    8587uses
    86   Global;
     88  Global, UNetworkCommon;
    8789
    8890procedure Client(Command, Player: integer; var Data);
     
    159161procedure TNetworkServerConnection.DisconnectExecute(Sender: TObject);
    160162begin
    161   Connected := False;
     163  {Connected := False;
    162164  if Assigned(Player) then begin
    163165    Player.Connection := nil;
    164166    Player := nil;
    165167  end;
    166 end;
    167 
    168 procedure TNetworkServerConnection.DataAvailableExecute(Sender: TObject);
     168  }
     169end;
     170
     171procedure TNetworkServerConnection.DataAvailableSync;
    169172var
    170173  Data: array of Byte;
     
    174177  Command: TCommand;
    175178begin
    176   if not Connected then Exit;
    177   Command := TCommand(Socket.ReadDWord);
    178   PlayerIndex := Socket.ReadDWord;
    179   Subject := Socket.ReadDWord;
    180   SetLength(Data, GetCommandDataSize(TCommand(Command)));
    181   if Length(Data) > 0 then begin
    182     ReadCount := Socket.Read(Data[0], Length(Data));
    183     SetLength(Data, ReadCount);
    184   end;
    185   if Assigned(Player) then begin
    186     if Length(Data) > 0 then
    187       Player.Server(Command, PlayerIndex, Subject, Data[0])
    188       else Player.Server(Command, PlayerIndex, Subject, nil^);
    189   end;
    190 
    191   NetworkServer.TCPServer.EventLoop.ClearDataAvailableNotify(DataAvailableHandle);
    192   DataAvailableHandle := NetworkServer.TCPServer.EventLoop.SetDataAvailableNotify(Socket.Handle, DataAvailableExecute, nil);
     179  StreamAppend(ReceiveBuffer, Socket);
     180  while ReceiveBuffer.Size >= 3 * SizeOf(Integer) do begin
     181    ReceiveBuffer.Position := 0;
     182
     183    Command := TCommand(ReceiveBuffer.ReadDWord);
     184    PlayerIndex := ReceiveBuffer.ReadDWord;
     185    Subject := ReceiveBuffer.ReadDWord;
     186    SetLength(Data, GetCommandDataSize(TCommand(Command)));
     187    if Length(Data) > 0 then begin
     188      ReadCount := ReceiveBuffer.Read(Data[0], Length(Data));
     189      SetLength(Data, ReadCount);
     190    end;
     191    if Assigned(Player) then begin
     192      if Length(Data) > 0 then
     193        Player.Server(Command, PlayerIndex, Subject, Data[0])
     194        else Player.Server(Command, PlayerIndex, Subject, nil^);
     195    end;
     196    StreamRemoveRead(ReceiveBuffer);
     197  end;
     198end;
     199
     200procedure TNetworkServerConnection.DataAvailableExecute(Sender: TObject);
     201begin
     202  NetworkServer.TCPServerThread.Synchronize(NetworkServer.TCPServerThread, DataAvailableSync);
     203  Sleep(10); // TODO: How to reset this event
    193204end;
    194205
     
    202213constructor TNetworkServerConnection.Create;
    203214begin
     215  ReceiveBuffer := TMemoryStream.Create;
    204216end;
    205217
     
    207219begin
    208220  if Assigned(Player) then Player.Connection := nil;
    209   NetworkServer.TCPServer.EventLoop.ClearDataAvailableNotify(DataAvailableHandle);
     221  if Assigned(DataAvailableHandle) then
     222    NetworkServer.TCPServer.EventLoop.ClearDataAvailableNotify(DataAvailableHandle);
    210223  FreeAndNil(Socket);
    211224  NetworkServer.Connections.Remove(Self);
     225  FreeAndNil(ReceiveBuffer);
    212226  inherited;
    213227end;
     
    221235  Player: TNetworkServerPlayer;
    222236  I: Integer;
     237  InitModuleData: TInitModuleData;
    223238begin
    224239  NewConnection := TNetworkServerConnection.Create;;
     
    239254    NewConnection.Player := Player;
    240255    Player.Connection := NewConnection;
    241     Player.Client(cmInitModule, -1, nil^);
     256    Player.Client(cmInitModule, Player.Id, InitModuleData);
    242257  end else AStream.Free;
    243258end;
Note: See TracChangeset for help on using the changeset viewer.