Sign in to follow this  

Net process in other thread in a MMO game

This topic is 3348 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys. My name is Jose Antonio, I am young developer from Spain. We are doing MMO social game. Now game is in beta version and we have problems about the network process. Cause, we are read from our net library (using Winsock1.1) in each frame of the main loop. I am discusing with the team about this, and we are thinking that read of the packets from the net would be in other thread, because with our method we thing that we have some message enqueued. What do you thing about this? We are using TCP as protocol. Could be a good implementation two threads to handle UPD and TCP messages? There are some messages that we need ensure that client game must receive, so we used TCP... Warmest Regards!!

Share this post


Link to post
Share on other sites
it sounds like a good idea to have a network thread that only reads/sends data.

once a message is read you can put it on a queue that the main thread in can read from. Its propably a good idea to add some sort of limit here in case your network thread reads more data than the game can handle. (this is "automatic" if you have it in main thread)

Its also interesting to get callbacks when clients connect and disconnects into the game thread (this will now happen in network thread), so you will also have to consider this when writing your implementation.

Can you be more specific about what problems you have encountered?

Share this post


Link to post
Share on other sites
Hi Kami, and thans for the response ;)

Ok, I will get you a case thats happends in our game.

We have in the server 50 remote player connected. So server send to each client each one second 50 update_position messages (cause we have 50 remote players).

If I connect my game, server send me 50 apparence of the 50 players and all update_positions messages of the each player.

Then, while server is send me update_position messages (more that 50 cause is 50 in each second) my game cannot load the apparence of the last players connected, cause we need process lot of update_position messages yet.

We know that we need to develop priority queue of messages (in the server side) to process before apparence messages and other types of messages more "interesting" but it is not possible now :(, so if I can queue in my own stack all messages, I could discard some update_position messages or reorder the stack in function of one priority.

I hope that my problem has been understand, I need improve my english.

Regards!

Share this post


Link to post
Share on other sites
The kernel will already buffer TCP messages for you (as well as UDP messages). If you are sure that you're not reading on an empty socket, then the call to recv() will not block, but it will dequeue as much data as possible. Using a separate thread won't help.

Similarly, on the sending side, the kernel will buffer some amount of outgoing data. However, if you try to send more data than the client can read, no improvements on the client will save you. If the client only has a 5 kB/s downstream link, trying to send 10 kB/s will run you out of buffer space in a hurry. What's going to happen on the sending side then is that select() will not return the socket as writable. If you call send() without first using select(), the call to send() will block (or, if non-blocking, fail).

This is one of the reasons why TCP isn't particularly well suited for real-time games. Your best bet is to set the kernel buffer to be something pretty small (a few kilobytes?) and then keep the queue in the application. And the queue typically should be queued operations ("update entity X") rather than queued data. That way, if an entity moves after the update is queued, once it gets to the front of the queue, the latest data will be sent.

Also, WinSock 1.1 is old 16-bit Windows 3.1 style technology. It has bugs. You're better off passing 2,2 as the WinSock version when opening WinSock. However, it seems to me as if you don't really have any networking experience on the team. While it might be fun to learn on the job, you should be prepared for some really tough times ahead unless you find some talent who has actually deployed high-volume production real-time applications before.

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
The kernel will already buffer TCP messages for you (as well as UDP messages). If you are sure that you're not reading on an empty socket, then the call to recv() will not block, but it will dequeue as much data as possible. Using a separate thread won't help.

Similarly, on the sending side, the kernel will buffer some amount of outgoing data. However, if you try to send more data than the client can read, no improvements on the client will save you. If the client only has a 5 kB/s downstream link, trying to send 10 kB/s will run you out of buffer space in a hurry. What's going to happen on the sending side then is that select() will not return the socket as writable. If you call send() without first using select(), the call to send() will block (or, if non-blocking, fail).

This is one of the reasons why TCP isn't particularly well suited for real-time games. Your best bet is to set the kernel buffer to be something pretty small (a few kilobytes?) and then keep the queue in the application. And the queue typically should be queued operations ("update entity X") rather than queued data. That way, if an entity moves after the update is queued, once it gets to the front of the queue, the latest data will be sent.

Also, WinSock 1.1 is old 16-bit Windows 3.1 style technology. It has bugs. You're better off passing 2,2 as the WinSock version when opening WinSock. However, it seems to me as if you don't really have any networking experience on the team. While it might be fun to learn on the job, you should be prepared for some really tough times ahead unless you find some talent who has actually deployed high-volume production real-time applications before.




There is a buffer sizing command that allows you to significantly increase the packet buffering (I forget what it is, but its there somewhere in winsock).

Lockless FIFOs can be used for each direction of data between the Server negine thread and the network thread (perfect when there is only one generator and one consumer). You can have a 'one to many' marshaling operation inside the network thread with a pair of FIFO for each player session (you might be able to use a single outbound FIFO if its all done with UDP)

Share this post


Link to post
Share on other sites
Two threads will help in one, and exactly one case. If you are currently running single-threaded server, and load exceeds CPU capacity by no more than 200%. In that case, running on two cores may alleviate the problem and increase throughput by 0-100%. Depending on where the bottleneck is, there might be no benefit whatsoever.

Same effect however can be reached by using faster CPU.

But it's considerably more likely that the cause of problem in this case is not in available CPU capacity.

Share this post


Link to post
Share on other sites

This topic is 3348 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this