Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (515)
Games in Android Showcase (122)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Small online 2d RPG game, single vs. multithread server?  (Read 6644 times)
0 Members and 1 Guest are viewing this topic.
Offline Twixly

Senior Newbie





« Posted 2009-10-15 14:02:11 »

Hey.
I recently went back to using one threaded server - because the thread handling was killing me. Concurrency errors and such..
My initial plan was to use 3 threads on the server :
1. Logic, calculations etc
2. Database write/read
3. Network in/out

However, like I said now I am back to one.. :/

My question is if this is even going to be viable in the long run?
I am guessing it has to do with the number of clients connecting to it as well?

Can someone give me some pointers on this? Do I -need- multi threads or can single do fine for a limited (how many?) number of clients?
Offline kaffiene
« Reply #1 - Posted 2009-10-15 20:50:46 »

For a simple 2d roleplaying game, I'd assume that single threaded ought to be fine.  I used to work in telecommunications and I wrote single threaded servers that handled thousands of messages a second on standard intel boxes of the day (over a decade ago!), and that was with some pretty intensive processing as well.

I think that worrying about multiple threads is way overcomplicating things.  Get it working first in a simple fashion and if you think you need to get more performance out of the server later, then consider a refactor for multithreading at that stage.
Offline ImNotBacon

Junior Duke




Don't eat me


« Reply #2 - Posted 2009-10-15 21:02:18 »

Handling your game in a single thread is fine, as long as you don't perform any operations that block.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline adon_y_coya

Senior Newbie





« Reply #3 - Posted 2009-10-16 05:53:21 »

To write a client-server networked game, you need at least 1 + 1 + 1 threads on the server:
A listener thread over the server port, that accepts connections (blocks until received request) and spawns ...
... An execution thread over the connected client socket that handles client communications. Since that will have to block on listening, you will  probably need ...
... Another execution thread that does all the 'server' side stuff for this client.

Draft calculation: 1 + (2 x NumberOfClients) threads.

Single Threaded Network Server:
Can happen, but will have to serve only one client at any time, and close the socket/end connection to serve another.
Only in textbook examples I've seen such (e.g. echo, hello, time-server, etc).
Offline h3ckboy

JGO Coder


Medals: 5



« Reply #4 - Posted 2009-10-16 14:52:37 »

adon you can do it but it is just less organized
Offline adon_y_coya

Senior Newbie





« Reply #5 - Posted 2009-10-16 19:47:29 »

1 thread:
a. server listens on port - blocks until receives connection
b. blocks on listening on connection
c. receives info, processes, sends back response, closes socket (or save it for later reuse)
d. back to (a) or (b)

Is that what you mean h3ckboy?
Online Riven
« League of Dukes »

JGO Overlord


Medals: 823
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #6 - Posted 2009-10-16 20:53:20 »

You might want to read about Java NIO: non-blocking I/O.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline DzzD
« Reply #7 - Posted 2009-10-16 21:49:52 »

you should use a network thread to handle network request and fill a stack with them, then for each server "logical loop" you will read this stack and pop any complete packets ready to be proceded (depending on your application architecture do the same for sending)

about multithreaded application :
you should multithread atomic part of your full server process,  dont use a thread for logic another for task2 and another for task 3 is better to do the following :

let say you have 3 task to do then

perform task 1 multithreaded on n threads (n depending on number of processor / core should be equals or greater)

wait for task 1 to be fully finished

perform task 2 on n threads

wait for task to to finish

perform task 3 on n thread
 
wait for task 3 to finish

the big advantage of doing that way is that :
1 - you will perform similar task on n different core so if you split equally they should end approximatly at the same time and will result in an optimal cpu usage
2 - it let you think like single threaded application and do not suffer of concurency access

Offline delt0r

JGO Knight


Medals: 27
Exp: 18 years


Computers can do that?


« Reply #8 - Posted 2009-10-17 17:49:04 »

If you don't need it. Using a single thread is recommended.

I was doing SMP type stuff before Java was born, so multi threaded is not new to me or the industry. Yet I generally write things single threaded when i can get away with it. Life is just so much simpler. Try running a debugger with multi threaded apps!!

When i do decide its worth it. Then i keep the interface between threads very simple. With classes from java.util.concurrent you can communicate between threads without even knowing what a lock or semaphore is. Its Brilliant. One thread is putting "data" into one end of a thread safe que and some other threads takes em out again. And the thread that takes em out blocks when there is nothing there.  On top of that most things in java.util.concurrent have fairness options, that can make a big difference if you are getting starved threads.

Last but not least I use read/write locks in cases when i almost don't update but read a data structure a lot.  My fluids code in AoI uses this and the locking overhead all but undetectable.

finally i use assertions a lot so that when things start to go wrong, I get errors as soon as it happens. AspectJ can help with some debug stuff to with the right kind of cutpoints.

But really, "mutlicore ready" is overrated. I would prefer "works most of the time" .

I have no special talents. I am only passionately curious.--Albert Einstein
Offline Nate

JGO Kernel


Medals: 153
Projects: 4
Exp: 14 years


Esoteric Software


« Reply #9 - Posted 2009-10-18 06:22:23 »

Single Threaded Network Server:
Can happen, but will have to serve only one client at any time, and close the socket/end connection to serve another.
To be clear, this is wrong. As Riven mentioned, look at NIO.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline adon_y_coya

Senior Newbie





« Reply #10 - Posted 2009-10-18 08:25:38 »

Non-blocking I/O is just blocking, with the threads I mentioned spawned in the background.
Not much easier to use or control concurrency, than the blocking home-brewed version I described.

I think DzzD's approach is the most scalable thread-wise.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 823
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #11 - Posted 2009-10-18 10:29:47 »

Non-blocking I/O is just blocking,

PLEASE read up on Java NIO Roll Eyes

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline delt0r

JGO Knight


Medals: 27
Exp: 18 years


Computers can do that?


« Reply #12 - Posted 2009-10-18 14:17:19 »

Just for the record. Since some people may never read a manual  Wink Java non blocking is the same as non blocking io in other langs. Its a feature provided by the OS and underlying hardware. Buffers can be filled etc without user space threads doing the work, indeed often no threads at all (DMA).  The api generally means every method call will return immediately, even if there is nothing to read etc.

I have a single thread manage all my network connections. Thats 2 different server sockets and any number of connections that are opened from these server sockets. Simply you check to see if anything has happened since the last time you checked. Then you go through the list of things, like connection request or whatever, process that then move to the next thing. Which may be data is avalible on connection 2 or you can write to connection 9.  It works very well and is much more effectent than the spawn a thread per connection that was done to fake non blocking io previously.

Keep in mind that a cpu can pump far more data into a network card than the card can send/receive. So filling/emptying bufferers then waiting till they are empty/full again really makes a lot of sense.  (yes i know the buffers should never get "full")

Doing a full game with network support in a single thread is quite doable.

I have no special talents. I am only passionately curious.--Albert Einstein
Online Riven
« League of Dukes »

JGO Overlord


Medals: 823
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #13 - Posted 2009-10-18 14:23:10 »

It works very well and is much more effectent than the spawn a thread per connection that was done to fake non blocking io previously.

Well... if you have enough RAM to spare to have all those (Linux NPTL) threads around, read this:
http://mailinator.blogspot.com/2008/02/kill-myth-please-nio-is-not-faster-than.html

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline DzzD
« Reply #14 - Posted 2009-10-18 16:42:21 »

Just for the record. Since some people may never read a manual  Wink Java non blocking is the same as non blocking io in other langs. Its a feature provided by the OS and underlying hardware. Buffers can be filled etc without user space threads doing the work, indeed often no threads at all (DMA).  The api generally means every method call will return immediately, even if there is nothing to read etc.

I have a single thread manage all my network connections. Thats 2 different server sockets and any number of connections that are opened from these server sockets. Simply you check to see if anything has happened since the last time you checked. Then you go through the list of things, like connection request or whatever, process that then move to the next thing. Which may be data is avalible on connection 2 or you can write to connection 9.  It works very well and is much more effectent than the spawn a thread per connection that was done to fake non blocking io previously.

Keep in mind that a cpu can pump far more data into a network card than the card can send/receive. So filling/emptying bufferers then waiting till they are empty/full again really makes a lot of sense.  (yes i know the buffers should never get "full")

Doing a full game with network support in a single thread is quite doable.

even when I was dealing with socket in C/C++ I always found simpler to use another thread, this ensure every packet is read ASAP and I found it, IMHO,  a lot more clear

Offline Twixly

Senior Newbie





« Reply #15 - Posted 2009-10-19 13:24:02 »

Well thanks for the feedback guys.
Since there seem to be no real "No it's impossible" answer, except one guy who is against it..
I will keep going with my current single threaded version.
It uses NIO sockets (that's the name?), anyway the class handling my sockets can read non-blocking or blocking depending on what I want to use.

I really know far too little about multi-threads to feel secure about it, whenever I try it seems I get bugs.. even tho I REALLY try to avoid it hehe.
Offline TheGDeveloper

Junior Duke


Projects: 1



« Reply #16 - Posted 2009-10-27 13:48:31 »

How can you use single threaded server architecture to support multiple user simultaneously?

Online Riven
« League of Dukes »

JGO Overlord


Medals: 823
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #17 - Posted 2009-10-27 14:07:11 »

How can you use single threaded server architecture to support multiple user simultaneously?

Answer:
You might want to read about Java NIO: non-blocking I/O.
PLEASE read up on Java NIO Roll Eyes

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline DzzD
« Reply #18 - Posted 2009-10-27 18:28:56 »

How can you use single threaded server architecture to support multiple user simultaneously?

there are two ways of working with socket blocking & unblocking, when they are not blocking you can ust check if something is available to read and if not check the second and third and etc...

Online Riven
« League of Dukes »

JGO Overlord


Medals: 823
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #19 - Posted 2009-10-27 18:48:02 »

there are two ways of working with socket blocking & unblocking, when they are not blocking you can ust check if something is available to read and if not check the second and third and etc...

The problem is that your writes can be blocking. You can't poll them like InputStreams.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline TheGDeveloper

Junior Duke


Projects: 1



« Reply #20 - Posted 2009-10-27 19:17:33 »

there are two ways of working with socket blocking & unblocking, when they are not blocking you can ust check if something is available to read and if not check the second and third and etc...
yes i know about this
but when you want to create an rpg with different dungeons etc you need to separate the game in different game loops etc
i thing that single threaded software architecture becouse every user needs different response
or at least i thing so

Offline DzzD
« Reply #21 - Posted 2009-10-27 19:34:08 »

The problem is that your writes can be blocking. You can't poll them like InputStreams.

even with a bufferedwriter ?
 
using buffered Reader & Writer should just run fine, no ?

yes i know about this
but when you want to create an rpg with different dungeons etc you need to separate the game in different game loops etc
i thing that single threaded software architecture becouse every user needs different response
or at least i thing so

no tis is unrelated, having a single thread does not mean you will not differencite client, you just associate a socket per client

Online Riven
« League of Dukes »

JGO Overlord


Medals: 823
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #22 - Posted 2009-10-27 19:41:53 »

even with a bufferedwriter ?
 
using buffered Reader & Writer should just run fine, no ?

BufferedWriter/BufferedOutputStream flushes when their buffer is full, and flushing blocks.
=> Impossible to work around.

BufferedReader/BufferedInputStream only read when their buffer is empty, and reading blocks.
=> Work around by calling socket.getInputStream().available() directly.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline DzzD
« Reply #23 - Posted 2009-10-27 19:50:22 »

BufferedWriter/BufferedOutputStream flushes when their buffer is full, and flushing blocks.
=> Impossible to work around.

BufferedReader/BufferedInputStream only read when their buffer is empty, and reading blocks.
=> Work around by calling socket.getInputStream().available() directly.
thk, I did not kwnew about the flush block, that's stupid... bha multithread is so much simpler   Lips Sealed

Offline delt0r

JGO Knight


Medals: 27
Exp: 18 years


Computers can do that?


« Reply #24 - Posted 2009-10-29 10:27:39 »

The link above about Linux NPTL, states quite clearly that without NPTL the whole thing melts with just 400 connections.

We can learn 2 things from this. If you need cross platform scalability on networks you had better think hard about how many threads you have. And two, games don't need huge scalability if done right compared to what high end servers mean with scalability (MMO notwithstanding of course, in which case you don't need to care about cross platform of the server). So both approaches are quite doable.

But we should also learn a 3rd thing. Whats best depends. And what it depends on changes over time and OS.

In terms of ease of programing. TBO I found both pretty straightforward to implement. But I am getting lost on why you need the BufferedReaders/Writers etc? Its network IO we talking about right? I which case the nio/net packages do that for you. A TCP connection will have NAGLE or whatever its called enabled by default and won't send a packet until the buffer is full. The reads will always have a (or more) packet buffered. 


I have no special talents. I am only passionately curious.--Albert Einstein
Offline DzzD
« Reply #25 - Posted 2009-10-29 18:01:33 »

In terms of ease of programing. TBO I found both pretty straightforward to implement. But I am getting lost on why you need the BufferedReaders/Writers etc? Its network IO we talking about right? I which case the nio/net packages do that for you. A TCP connection will have NAGLE or whatever its called enabled by default and won't send a packet until the buffer is full. The reads will always have a (or more) packet buffered. 

about the buffered it was just a parentesis on a possible workaround when using (or forced to use) blocking socket vs pooling non-blocking socket (personally I prefer full blocking on a separated thread both for server and client, but that just a matter of taste ) I am just not enought confident in letting a library manage buffers for me.

my english is sometime limited does the paper stand that 400 threads will blowup a linux serveur ? seems strange as found it pretty low ?

anyway this discussion is pretty interresting for me as I am being writing a MMO and even if we will do earlier heavy benchmark, I wouldn't really like to have any surprise but 400 threads/users per servers is already enought....

Offline delt0r

JGO Knight


Medals: 27
Exp: 18 years


Computers can do that?


« Reply #26 - Posted 2009-11-01 15:33:02 »

On standard Linux 1000 threads with only one doing something is fine. But if they all need to work.... Then they you will often get very high CPU usage but no thread will make much progress. Or alternatively most threads will never get a turn. Even with a few threads you need to be careful that some threads don't get shut out from ever having a turn with the  use of a shared object (aka the network).

It should be pointed out that on a computer with one network card, only two things can really happen at once. Sending/receiving single packets. Thus a few 100 threads on a single card does imply that most will have nothing to do at any given time (yes I am ignoring individual socket buffers).

If you are writing something scalable then general wisdom is you use both approaches. That is you have a number of connects handled by a single thread, but you also have many threads. If however you can specify what type of hardware/OS the server is then reading up on NPTL would be  a good idea .

I have no special talents. I am only passionately curious.--Albert Einstein
Offline DzzD
« Reply #27 - Posted 2009-11-03 11:28:30 »

On standard Linux 1000 threads with only one doing something is fine. But if they all need to work.... Then they you will often get very high CPU usage but no thread will make much progress. Or alternatively most threads will never get a turn. Even with a few threads you need to be careful that some threads don't get shut out from ever having a turn with the  use of a shared object (aka the network).

It should be pointed out that on a computer with one network card, only two things can really happen at once. Sending/receiving single packets. Thus a few 100 threads on a single card does imply that most will have nothing to do at any given time (yes I am ignoring individual socket buffers).

If you are writing something scalable then general wisdom is you use both approaches. That is you have a number of connects handled by a single thread, but you also have many threads. If however you can specify what type of hardware/OS the server is then reading up on NPTL would be  a good idea .


thanks for all those informations.

for now I have choosen to build a hierarchical network architecture, so I should be able to put new server pretty easily if I fall in a maximum connection problem, something like :

Level 1       Level 0
----A-----|
----B-----|----abc---abc----D
----C-----|


"A" receive up to 500/1000 connection & it multiplexe them via a single connection to "D" (same for B / C)

so with only two "stage/level" and 20 servers in front I should be able to reach up 20*1000 = 20000 persistents connections... but would be really better for example to have 10*2000 or 4*5000 so I will take care to read about NPTL and possible overthread issues

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (31 views)
2014-10-27 03:28:38

TehJavaDev (26 views)
2014-10-27 03:27:51

DarkCart (40 views)
2014-10-26 19:37:11

Luminem (21 views)
2014-10-26 10:17:50

Luminem (25 views)
2014-10-26 10:14:04

theagentd (31 views)
2014-10-25 15:46:29

Longarmx (61 views)
2014-10-17 03:59:02

Norakomi (57 views)
2014-10-16 15:22:06

Norakomi (46 views)
2014-10-16 15:20:20

lcass (43 views)
2014-10-15 16:18:58
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!