Mirage Source http://web.miragesource.net/forums/ |
|
Reduce Packet Lag... Add a Packet Bufferi http://web.miragesource.net/forums/viewtopic.php?f=210&t=894 |
Page 1 of 2 |
Author: | William [ Wed Dec 20, 2006 8:09 pm ] |
Post subject: | Reduce Packet Lag... Add a Packet Bufferi |
Originally posted by Verrigan Difficulty: Medium 3/5 This tutorial is designed to show you how to put a buffer system in your game. Why would you want to do that? Think about it. When a player connects, there are a series of messages sent to that player, and in Mirage, they are sent one right after the other.. If you have large maps, or you have a bunch of items/npcs/spells/etc., the server will send all that data to a user who is connecting.. For small games with small sized maps, this isn't a problem.. Lag is minimal. However, for games with tons of items, spells, etc., you will experience lag when another player connects. Okay, now introduce a buffering (queue) system.. The server form has a timer that calls a subroutine that is solely responsible for dropping the size of the queue. How does the queue get filled? Instead of immediately sending any data to a player, you make the server add it to the queue. The server then hits the timer's interval, calls the subroutine to drop the queue, which sends messages to each user that is waiting for those messages. The subroutine will go through all connections, check the queue, and deliver messages to each user up to a predefined size limit for each user.. (This tutorial limits that size to 32K per user, per loop, but you can easily customize that limit.) All that said, I must say that I have only tested this buffer system with one connection, so it might need some work, which is why I set the difficulty at 3.. Some of you might think the difficulty should be 5, but that's why I'm going to tell you this: BACKUP YOUR SERVER BEFORE ADDING THIS TUTORIAL. Now, on with the tutorial.. Files to Modify
Code: Call CloseSocket(<whatever variable is used... Index, i, etc.>) to:Code: QueueDisconnect(<same variable name... Index, i, etc.>) = True frmServer.frm FrmServer is where timers and sockets are stored.. I don't like to do this, but my tutorials are based on the already existing code in the Mirage Source, not redoing the whole thing.. :P So... Add a timer to the form named: tmrStartMsgQueue with an interval of 100. Then, in the code of frmServer, add the following code: Code: Private Sub tmrStartMsgQueue_Timer() Call SendQueuedData End Sub modGeneral.bas ModGeneral is where general stuff happens.. The server is initialized here, the AI is in here, etc. Add the following code somewhere: Code: Sub SendQueuedData() Dim i As Integer, n As Long Dim TmpStr As String For i = 1 To MAX_PLAYERS TmpStr = "" With ConQueues(i) If Not .Lock Then If frmServer.Socket(i).State <> 7 Then .Lines = "" End If If Len(.Lines) = 0 And QueueDisconnect(i) = True Then Call CloseSocket(i) QueueDisconnect(i) = False Else If Len(.Lines) > 0 Then If Len(.Lines) < MAX_PACKETLEN Then TmpStr = .Lines Else TmpStr = Left(.Lines, MAX_PACKETLEN) End If .Lines = Right(.Lines, Len(.Lines) - Len(TmpStr)) End If End If If Len(TmpStr) > 0 Then Call frmServer.Socket(i).SendData(TmpStr) End If End If End With Next DoEvents End Sub In Sub InitServer After this code: Code: ' Init all the player sockets add this code:For i = 1 To MAX_PLAYERS Call SetStatus("Initializing player array...") Call ClearPlayer(i) Load frmServer.Socket(i) Code: ConQueues(i).Lines = "" 'Initialize the lines. modServerTCP.bas ModServerTCP handles the data being sent from/received to the server. In Sub SendDataTo() Change this code: Code: If IsConnected(Index) Then to this code:frmServer.Socket(Index).SendData Data DoEvents End If Code: If IsConnected(Index) Then With ConQueues(Index) .Lock = True .Lines = .Lines & Data .Lock = False End With 'DoEvents End If modTypes.bas ModTypes is where all the data types are stored, and other stuff... Under this code: Code: Type GuildRec add this code:Name As String * NAME_LENGTH Founder As String * NAME_LENGTH Member(1 To MAX_GUILD_MEMBERS) As String * NAME_LENGTH End Type Code: Type ConDataQueue
Lock As Boolean Lines As String End Type Public ConQueues(MAX_PLAYERS) As ConDataQueue Public Const MAX_PACKETLEN As Long = 32768 'About 32K Public QueueDisconnect(MAX_PLAYERS) As Boolean This was tested in a vanilla Mirage Source 3.0.3. So, if you add this to your game, and I only tested this with one player connected.. (I don't have a bunch of users, cause I don't run a Mirage server.. ) Anyways.. Just like any other tutorials on here... BACKUP YOUR SOURCE!!! I said it twice, now... Hopefully you will take my advice.. It is also possible that I failed to put something in here.. In the event that you find that I forgot something, or you tried this in a vanilla server and it didn't work.. Please post here, but I'm pretty sure I remembered everything.. |
Author: | Xlithan [ Thu Jan 18, 2007 5:09 pm ] |
Post subject: | |
Has anybody tested this? |
Author: | William [ Thu Jan 18, 2007 5:22 pm ] |
Post subject: | |
Yes. |
Author: | Spodi [ Thu Jan 18, 2007 11:24 pm ] |
Post subject: | |
I just want to throw in - this is a great idea, but not when using Winsock control. Reason for this is that the Winsock control has the Nagle Algorithm enabled by default, and I don't think you can turn it off. The Nagle Algorithm is basically a packet buffer created for office programs where slight packet delays are hardly a problem. The Winsock control was designed for quickly made applications, not online games or anything, so I doubt turning it off was even a consideration in their design. How it works is that it buffers your packets for about 300ms from the first call. So if you send a packet, it will take at most a bonus 300ms onto your network lag. Thats on top of everything else, not total. If you buffer yourself, you'll probably keep throwing your buffers into the same Nagle buffer, which means it'd have the exact same effect in the long run (almost) to just send a bunch of small packets. You have to thank the Nagle algorithm, though, since if it wasn't there, any ORPG using the winsock control (Mirage, Elysium, etc) and without a buffer, would probably have a good 2-4kb/sec added on to the packet size just from headers. By the way, TCP headers are 20 bytes, IPv4 headers are 20 bytes, so every packet you send is 40 bytes + the data. |
Author: | Xlithan [ Fri Jan 19, 2007 3:26 am ] |
Post subject: | |
Spodi, vbGORE uses the SOX method right? Which would you recommend added to MSE, the SOX method, or IOCP? |
Author: | Spodi [ Fri Jan 19, 2007 5:04 am ] |
Post subject: | |
I really don't have a lot of IOCP experience, but I can't see many large benifits it'd make to a relatively small series of connections. SOX would be the easiest to use since it is designed to be enarly the exact same as Winsock, so the only change you have to make is using Shut instead of Close and not using an array on the control I believe. |
Author: | William [ Fri Jan 19, 2007 2:11 pm ] |
Post subject: | |
Spodi wrote: I just want to throw in - this is a great idea, but not when using Winsock control. Reason for this is that the Winsock control has the Nagle Algorithm enabled by default, and I don't think you can turn it off.
The Nagle Algorithm is basically a packet buffer created for office programs where slight packet delays are hardly a problem. The Winsock control was designed for quickly made applications, not online games or anything, so I doubt turning it off was even a consideration in their design. How it works is that it buffers your packets for about 300ms from the first call. So if you send a packet, it will take at most a bonus 300ms onto your network lag. Thats on top of everything else, not total. If you buffer yourself, you'll probably keep throwing your buffers into the same Nagle buffer, which means it'd have the exact same effect in the long run (almost) to just send a bunch of small packets. You have to thank the Nagle algorithm, though, since if it wasn't there, any ORPG using the winsock control (Mirage, Elysium, etc) and without a buffer, would probably have a good 2-4kb/sec added on to the packet size just from headers. By the way, TCP headers are 20 bytes, IPv4 headers are 20 bytes, so every packet you send is 40 bytes + the data. So you think it's a bad idea to use this? |
Author: | TheRealDamien [ Fri Jan 19, 2007 4:33 pm ] |
Post subject: | |
It shows people how packet buffers are created... I personally wouldnt use this tutorial but I got a good understanding of how I wanted mine to go by looking at this. This is good to learn from but I wouldnt go to any mesure on adding it into my engine or game. A suitable packet buffer can be created for winsock users but I dont think this is it. Still I belive/think it holds very good value for people to view and understand and create their own. |
Author: | Robin [ Fri Jan 19, 2007 4:49 pm ] |
Post subject: | |
TheRealDamien wrote: It shows people how packet buffers are created... I personally wouldnt use this tutorial but I got a good understanding of how I wanted mine to go by looking at this. This is good to learn from but I wouldnt go to any mesure on adding it into my engine or game.
A suitable packet buffer can be created for winsock users but I dont think this is it. Still I belive/think it holds very good value for people to view and understand and create their own. What are you on about..? Do you use winsock? Do you use the winsock control? |
Author: | Harry [ Fri Jan 19, 2007 5:55 pm ] |
Post subject: | |
Kite wrote: TheRealDamien wrote: It shows people how packet buffers are created... I personally wouldnt use this tutorial but I got a good understanding of how I wanted mine to go by looking at this. This is good to learn from but I wouldnt go to any mesure on adding it into my engine or game. A suitable packet buffer can be created for winsock users but I dont think this is it. Still I belive/think it holds very good value for people to view and understand and create their own. What are you on about..? Do you use winsock? Do you use the winsock control? Wooooow!!! Slow down there. He needs to get Visual basic first. |
Author: | Spodi [ Fri Jan 19, 2007 11:51 pm ] |
Post subject: | |
No William, not useless. With the Winsock control, yes (unless you can turn off Nagling in it, often referenced as NoDelay or something), but with SOX and probably IOCP (depending on what the socket library offers), it is absolutely priceless. When you get your packets crunched down a lot on a simple 2d ORPG (since as we all know, not a whole lot of data ever has to be transferred), the big worry becomes sending data as little as possible, and not as much what you are sending. Custom packet buffers give you so much more flexibility on how often you send data. And its fun to play with! Weeee!!! So I'd just add a quick short explanation at the top on why you wouldn't want to use it with WinSock, but that with anything else where you can turn off Nagling, is simply just awesome. |
Author: | Robin [ Sat Jan 20, 2007 12:28 am ] |
Post subject: | |
Spodi wrote: No William, not useless. With the Winsock control, yes (unless you can turn off Nagling in it, often referenced as NoDelay or something), but with SOX and probably IOCP (depending on what the socket library offers), it is absolutely priceless. When you get your packets crunched down a lot on a simple 2d ORPG (since as we all know, not a whole lot of data ever has to be transferred), the big worry becomes sending data as little as possible, and not as much what you are sending. Custom packet buffers give you so much more flexibility on how often you send data. And its fun to play with! Weeee!!!
So I'd just add a quick short explanation at the top on why you wouldn't want to use it with WinSock, but that with anything else where you can turn off Nagling, is simply just awesome. That must give you such a massive headache. |
Author: | Spodi [ Sat Jan 20, 2007 12:54 am ] |
Post subject: | |
Actually it isn't too bad. Organization is the main key. You just have to look at the packets you have, and think which ones would suffice having a slight delay, and which ones would be fine not coming until any other packets come. For example, if you get a message on new mail, you can just attach it to the next packet instead of letting it send on its own, since a few second delay wont make any difference (unless they are waiting next to the mailbox doing nothing, no one / thing is in the screen, and no one is talking). Its really fun to see what you can come up with. Of course, you wont be able to find as much as you want just looking at the packets. |
Author: | William [ Sat Jan 20, 2007 1:06 am ] |
Post subject: | |
Well since Im using IOCP it's probably a good idea to use the packet buffer. |
Author: | Xlithan [ Wed Mar 07, 2007 12:41 am ] |
Post subject: | |
I'll have to try and add IOCP again then. |
Author: | Verrigan [ Thu Mar 08, 2007 6:40 pm ] |
Post subject: | |
I just wanted to say these things: 1) This is still a good idea even with Nagling turned on.. It was mainly created to keep the people who login from lagging everyone else in game while everyone waited for that person to receive all the item/npc/etc packets. It also (for an added benefit) helps to keep others from lagging when a player has to download a map on a game that has (excessively) large maps. 2) It is possible to turn off the Nagling using API calls on the Winsock control by using the SocketHandle of whatever winsock object you're using.. (I posted this somewhere... Can't remember if it was on this forum or not.. maybe I'll find it and post a link.) And for an added bonus, I just want to say that Spodi is a kick-ass programmer, and I want to know if you (Spodi) do your own graphics! (No, I'm not trying to be funny.) [Edit] Here's the link I mentioned in item #2 above: http://key2heaven.net/ms/forums/viewtop ... =8235#8235 |
Author: | William [ Sun Sep 02, 2007 6:35 pm ] |
Post subject: | Re: Reduce Packet Lag... Add a Packet Bufferi |
If adding this, disable the nagling algorithm and also change the timer interval from 100 to 25. |
Author: | Robin [ Sun Sep 02, 2007 7:29 pm ] |
Post subject: | Re: Reduce Packet Lag... Add a Packet Bufferi |
Ooh, gonna work on this once I finish converting to the API. Lol @ Reece being naive. "I'm sure Elysium fixed this" lolagasm. |
Author: | Tony [ Tue Dec 09, 2008 2:33 am ] |
Post subject: | Re: Reduce Packet Lag... Add a Packet Bufferi |
Apologies for necro.. But disabling the Nagle algorithm and implementing this Packet buffer would reduce packet lag? edit\ Why not use IOCP and packet buffering? |
Author: | William [ Tue Dec 09, 2008 7:20 pm ] |
Post subject: | Re: Reduce Packet Lag... Add a Packet Bufferi |
Don't use IOCP and don't use a packet buffer. |
Author: | Asrrin29 [ Tue Dec 09, 2008 11:13 pm ] |
Post subject: | Re: Reduce Packet Lag... Add a Packet Bufferi |
don't use IOCP? did something change since I've been gone? |
Author: | Tony [ Tue Dec 09, 2008 11:21 pm ] |
Post subject: | Re: Reduce Packet Lag... Add a Packet Bufferi |
William wrote: Don't use IOCP and don't use a packet buffer. Because? |
Author: | William [ Wed Dec 10, 2008 3:41 pm ] |
Post subject: | Re: Reduce Packet Lag... Add a Packet Bufferi |
IOCP is unstable, and the code verrigan provided isn't fully bug free. And IOCP is supposed to be used on a server with thousands of connections, a ms server is better without it. So just skip it. |
Author: | Asrrin29 [ Wed Dec 10, 2008 10:23 pm ] |
Post subject: | Re: Reduce Packet Lag... Add a Packet Bufferi |
I've had IOCP in my code for over a year and have never had any sort of hang ups with it. granted, I've not had more then 10 people online at a time, but unless I'm missing something there doesn't seem to be a problem. |
Author: | GIAKEN [ Wed Dec 10, 2008 10:53 pm ] |
Post subject: | Re: Reduce Packet Lag... Add a Packet Bufferi |
I took IOCP out of a game because it kept getting out of memory errors and players were always having account online problems and so on. The game has about 20 people on average. |
Page 1 of 2 | All times are UTC |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |