- Collect synced packets to send within 1 second (cSendEmptyPacketTime) into buffer which is flushed each second.
authorunc0rr
Fri, 08 Feb 2013 15:33:43 +0400
changeset 8472 da6b569ac930
parent 8471 7681d14b9f01
child 8473 555235e90010
child 8474 f6abe50095d2
- Collect synced packets to send within 1 second (cSendEmptyPacketTime) into buffer which is flushed each second. - Send empty packet only if there was no other synced message within last second. This should reduce traffic load: less bytes and less packets (less packets is very good for the server too).
QTfrontend/game.cpp
QTfrontend/game.h
hedgewars/uGame.pas
hedgewars/uIO.pas
--- a/QTfrontend/game.cpp	Tue Feb 05 17:28:12 2013 -0500
+++ b/QTfrontend/game.cpp	Fri Feb 08 15:33:43 2013 +0400
@@ -313,9 +313,8 @@
         default:
         {
             if (gameType == gtNet && !netSuspend)
-            {
-                emit SendNet(msg);
-            }
+                m_netSendBuffer.append(msg);
+
             demo.append(msg);
         }
     }
@@ -344,6 +343,17 @@
         readbuffer.remove(0, msglen + 1);
         ParseMessage(msg);
     }
+    
+    flushNetBuffer();
+}
+
+void HWGame::flushNetBuffer()
+{
+    if(m_netSendBuffer.size())
+    {
+        emit SendNet(m_netSendBuffer);
+        
        m_netSendBuffer.clear();
+    }
 }
 
 QStringList HWGame::getArguments()
--- a/QTfrontend/game.h	Tue Feb 05 17:28:12 2013 -0500
+++ b/QTfrontend/game.h	Fri Feb 08 15:33:43 2013 +0400
@@ -102,6 +102,7 @@
         GameCFGWidget * gamecfg;
         TeamSelWidget* m_pTeamSelWidget;
         GameType gameType;
+        QByteArray m_netSendBuffer;
 
         void addKeyBindings(QByteArray * buf);
         void commonConfig();
@@ -114,6 +115,7 @@
         void SetGameState(GameState state);
         void sendCampaignVar(const QByteArray & varToSend);
         void writeCampaignVar(const QByteArray &varVal);
+        void flushNetBuffer();
 };
 
 #endif
--- a/hedgewars/uGame.pas	Tue Feb 05 17:28:12 2013 -0500
+++ b/hedgewars/uGame.pas	Fri Feb 08 15:33:43 2013 +0400
@@ -36,12 +36,14 @@
 begin
 if isPaused then
     exit;
+
 if (not CurrentTeam^.ExtDriven) then
     begin
     NetGetNextCmd; // its for the case of receiving "/say" message
     isInLag:= false;
-    SendKeepAliveMessage(Lag)
+    FlushMessages(Lag)
     end;
+
 if GameType <> gmtRecord then
     begin
     if Lag > 100 then
--- a/hedgewars/uIO.pas	Tue Feb 05 17:28:12 2013 -0500
+++ b/hedgewars/uIO.pas	Fri Feb 08 15:33:43 2013 +0400
@@ -30,7 +30,7 @@
 procedure SendIPCXY(cmd: char; X, Y: LongInt);
 procedure SendIPCRaw(p: pointer; len: Longword);
 procedure SendIPCAndWaitReply(s: shortstring);
-procedure SendKeepAliveMessage(Lag: Longword);
+procedure FlushMessages(Lag: Longword);
 procedure LoadRecordFromFile(fileName: shortstring);
 procedure SendStat(sit: TStatInfoType; s: shortstring);
 procedure IPCWaitPongEvent;
@@ -43,6 +43,7 @@
 
 const
     cSendEmptyPacketTime = 1000;
+    cSendBufferSize = 1024;
 
 type PCmd = ^TCmd;
      TCmd = packed record
@@ -63,7 +64,11 @@
     headcmd: PCmd;
     lastcmd: PCmd;
 
-    SendEmptyPacketTicks: LongWord;
+    flushDelayTicks: LongWord;
+    sendBuffer: record
+                buf: array[0..Pred(cSendBufferSize)] of byte;
+                count: Word;
+                end;
 
 function AddCmd(Time: Word; str: shortstring): PCmd;
 var command: PCmd;
@@ -214,19 +219,38 @@
 SendIPCRaw(@buf[0], length(buf) + 1)
 end;
 
+function isSyncedCommand(c: char): boolean;
+begin
+    isSyncedCommand:= (c in ['+', '#', 'L', 'l', 'R', 'r', 'U', 'u', 'D', 'd', 'Z', 'z', 'A', 'a', 'S', 'j', 'J', ',', 'c', 's', 'b', 'F', 'N', 'p', 'P', 'w', 't', 'h', '1', '2', '3', '4', '5']) or ((c >= #128) and (c <= char(128 + cMaxSlotIndex)))
+end;
+
+procedure flushBuffer();
+begin
+    SDLNet_TCP_Send(IPCSock, @sendBuffer.buf, sendBuffer.count);
+    flushDelayTicks:= 0;
+    sendBuffer.count:= 0
+end;
 
 procedure SendIPC(s: shortstring);
 begin
 if IPCSock <> nil then
     begin
-    SendEmptyPacketTicks:= 0;
-    if s[0]>#251 then
+    if s[0] > #251 then
         s[0]:= #251;
         
     SDLNet_Write16(GameTicks, @s[Succ(byte(s[0]))]);
     AddFileLog('[IPC out] '+ s[1]);
     inc(s[0], 2);
-    SDLNet_TCP_Send(IPCSock, @s, Succ(byte(s[0])))
+    
+    if isSyncedCommand(s[1]) then
+        begin
+        if sendBuffer.count + byte(s[0]) >= cSendBufferSize then
+            flushBuffer();
+            
+        Move(s, sendBuffer.buf[sendBuffer.count], byte(s[0]) + 1);
+        inc(sendBuffer.count, byte(s[0]) + 1)
+        end else
+        SDLNet_TCP_Send(IPCSock, @s, Succ(byte(s[0])))
     end
 end;
 
@@ -264,11 +288,16 @@
 IPCWaitPongEvent
 end;
 
-procedure SendKeepAliveMessage(Lag: Longword);
+procedure FlushMessages(Lag: Longword);
 begin
-inc(SendEmptyPacketTicks, Lag);
-if (SendEmptyPacketTicks >= cSendEmptyPacketTime) then
-    SendIPC(_S'+')
+inc(flushDelayTicks, Lag);
+if (flushDelayTicks >= cSendEmptyPacketTime) then
+    begin
+    if sendBuffer.count = 0 then
+        SendIPC(_S'+');
+        
+     flushBuffer()    
+    end
 end;
 
 procedure NetGetNextCmd;
@@ -434,7 +463,8 @@
     SocketString:= '';
     
     hiTicks:= 0;
-    SendEmptyPacketTicks:= 0;
+    flushDelayTicks:= 0;
+    sendBuffer.count:= 0;
 end;
 
 procedure freeModule;