Yeah, that’s true
It is easier, but it’s really only suitable for smaller servers
Yeah, that’s true
It is easier, but it’s really only suitable for smaller servers
I ve manage to have more than 100 players playing realtime game together on the same server without optimizing anything and without loading it that much, could theorically handle a lot more, I use standard IO because It was the one who look the most familiar to me, the most similar to the one I used in C in the past, but probably the only reason is I just never realy ask myself about that
Ehh, I’m familiar with IO, but I rarely use except when I’m testing things networking related since it’s quicker to code using IO… My game server should theoretically hold over 2000 players (must have a decent internet though :p, like on a dedicated server or vps)
For 100 players a thread-per-client model with IO works well
100 players is just the tiny part of targeted audience (it is only a real test case we was able to measure on), number of attended visitor is lot bigger (can be up to thousands of user, the leader in what we target had up to 300000 players on official races and we got a better product and we begin to have official races, so we cross fingers), we have built a very extensible architecture cpu/network/ram, “theorically” we can handle those number of connection, principe is pretty simple and have shown to work very well on all tests we was able to do/simulate.
in sumary we got a big server that do all logic using multithread on component based system :
1 - perform task 1 on n threads
2 - perform task 2 on n threads
3 - perform task 3 on n threads
etc…
this enable to switch to 4/8/16/32/etc… cores depending on server charge
and for the network part, clients does not connect directly to the root game server, rather we used fronts server that act as proxies :
those front server are cheap and can be rent/installed and connected to the root one within arround one hour (and inded removing pretty quickly),
this way we can make our bandwith and number of possible connection grow/shrink depending on the charge, also interresting economicaly as we pay only the requiered bandwith at a given time.
we can handle arround 500 players on one front server and this front server only make one connection to the root server (multiplexing/demultiplexing packets),
if we want to be able to have 500 connections more we juste have to add another front server (nb connection depend on the server spec) and etc…
this can be done until the root server cannot handle anymore front server / connection, and alternativly we can branch biggers fronts server
for example with only 10 fronts servers that would each enable 500 connections (once again 500 really depend on servers spec)
we will enable 5000 players in a race and the root server will still only see 10 connections.
for now with a maximum of 100 players connected at once and arround 600/700 boats ingame we got only one small front server with a medium root server ( and both are just doing nothing, server load is very low )
“the icing on the cake” : client <=> frontal work over HTTP/1.1, yes that dont look serious hé ? but it enable a lot of player to play from their work even with strict proxy, basically we had redo some kind of stream/TCP over HTTP …, note that even throught proxy/front an due to asynchronous threatment of HTTP stream, ping is usually arround 100 ms (wich is really enought for the kind of gameplay we target : 1s is still ok)
…all that to say that I love this architecture, yes … but also that I keep in mind using NIO, I will investigate more “if” in the futur standard IO start to show some issues
This look like previus post so sorry if this don’t help;
Here is how I send and packed data maybe it looks weird but I do so:)
ByteArrayOutputStream=baos
Pi=(int) 45645646;
// Float.floatToIntBits(Pi);
a1=Pi>>24;
a2=(Pi<<8)>>24;
a3=(Pi<<16)>>24;
a4=(Pi<<24)>>24;
baos.write(a1);
baos.write(a2);
baos.write(a3);
baos.write(a4);
byte ar[]=baos.toByteArray();
iterat=0;
a1=(char)(ar[iterat]&0xFF);
iterat++;
a2=(char)(ar[iterat]&0xFF);
iterat++;
a3=(char)(ar[iterat]&0xFF);
iterat++;
a4=(char)(ar[iterat]&0xFF);
iterat++;
int Pi=(a1<<24)+(a2<<16)+(a3<<8)+a4;
//Care it will be signed
// I use char for unsigned byte ;)
// Float.intBitsToFloat(Pi);
//long
a1= timee>>56;//send
a2= (timee<<8)>>56;
a3= (timee<<16)>>56;
a4= (timee<<24)>>56;
a5= (timee<<32)>>56;
a6= (timee<<40)>>56;
a7= (timee<<48)>>56;
a8= (timee<<56)>>56;
timee=((long)a1<<56)+((long)a2<<48)+((long)a3<<40)+((long)a4<<32);//read
timee +=((a5<<24)+(a6<<16)+(a7<<8)+a8)& 0xFFFFFFFFL;