Java TCP keep-alive for a master server - java

Context: Master server (Java, TCP) monitoring a list of hosted games (a different machine for the master server and for each hosted game server). Any user can host a game on his PC. Hosted games can last weeks or months.
Need: Knowing when hosted game servers are closed or no longer reachable.
Restriction 1: Can't rely on hosted servers' "gone offline update message", since those messages may never arrive (power down, Internet link cut, etc.)
Restriction 2: I'm not sure about TCP's built-in keep-alive, since it would mean a 24/7 open socket with each hosted server (correct me if I'm wrong)
Any thoughts?

Consider using some kind of heartbeat messages. Those messages ("I'm alive!") are sent regularly and if the master server doesn't get a heartbeat message from a hosted server (for a certain time), it knows, that this hosted server is unavailable.
You can even add some status parameters to this message if you need more detailed information from the hosted servers (like 'fully operational', 'going down for maintenance in 5 minutes', etc.)

It sounds like you're running into what's known as the "Two-Army Problem," the "Coordinated Attack Problem, or, as Andreas D noted, the Two General's Problem which you've identified as your Restriction 1. The idea behind this problem is that two armies want to coordinate an attack on the enemy. They need to both attack at the same time, since each army knows that they will die if they attack on their own.
The problem is this: How does an army know their messenger, who is carrying the time intended for the coordinated attack, has reached the other army successfully? Furthermore, how can the second army be sure that the first army knows that they received the message and plans to attack? It's possible that any message between the armies doesn't arrive successfully, and thus the armies can never be sure that they're coordinated properly.
Because of this, the simplest answer may be to simply do a ping on each running game at a scheduled interval, and also whenever a user requests a refresh. You can use this information to populate your master list.

Related

Okhttp websocket server Shutdown detection

I am developing a nodemcu websocket server android client app using java.i successfully created client and connected to it through a websocket client service.i can detect server failure/closed when sending data.but can't detect it at the time of failure that is if server powered off cant know untill some data is send.how to know the server failure at the time of failure.using okhttp 4.1.0 library.can anyone help
how to know the server failure at the time of failure.using okhttp 4.1.0 library.can anyone help
You can't. It's not possible, but, there are workarounds, see below.
Why isn't it possible? Internally, the internet is packet switched, which means data is first gathered up into packets, and then these packets are sent.
Most of the stuff you do on the web feels like it is 'streams' instead (you send 1 character, and one character arrives on the other side). But that's all based on protocols that are built on top of the packet nature of the internet.
When you have an open connection between 2 computers via the internet, no data is actually being sent, at all. It's not like you have a line reserved. Old telephone networks did work like that: When you dialled somebody, you got a dedicated line, and once the line got interrupted, you'd hear beeps to indicate this.
That is not how the internet works. Those wires and everything in between have no idea that there is an open connection at all. That's just some bits in memory on your computer and on the server which lets them identify certain packets as part of the longer conversation those 2 machines were having, is all.
Thus we arrive at why this isn't possible: Given that no packets are flowing whatsoever until one side actually sends data to the other, it is impossible to tell the difference between 'no data being sent right now' and 'somebody tripped over the power cable in the server park'. That's why you don't get that info until you send something (and the reason you get that is only because when you send something, the protocol dictates that the server sends you back a confirmation of receiving what you sent. If that takes too long, your computer will send it a few more times just in case the packet just got lost somewhere, and will eventually give up and conclude that the server can no longer be reached or crashed or lost power, and only then do you get the IOException).
Workarounds
A simple one is to upgrade your own protocol: Dictate that the server or client (doesn't matter who takes the responsibility to do this) sends a do-nothing message at least once a minute. You can then conclude after not receiving that for 100 seconds or so that the connection is probably dead. You can start a timer for 100 seconds, reset it every time you receive any data whatsoever. If the timer ever runs out? Connection is likely dead.
This is somewhat take on this idea built into the protocol that lets you make connections that feel like streams of data. That protocol is called TCP/IP, and the feature is called KeepAlive.
The problem is, you possibly don't get to dictate the TCP/IP settings for your websocket connection. If you can, you can turn on keepalive (for example in java, you use Socket to make raw TCP/IP connections, and it has a .setSoKeepAlive(true) method. Check the API if you can get at the socket or otherwise scan the docs for 'keepalive' and see if there's anything there.
I bet there won't be, which means you have to use the trick I mentioned above: Update your server code to use a timer to send a 'hello!' 60 seconds after any conversation, and update your client code to give up on the connection once 100 seconds have passed (give it 40 additional seconds; sometimes the internet gets a little backed up or servers get a little busy).

How can I create a "soft" broken TCP connection, as if networking hardware had silently disconnected the stream?

I've got a Java program that opens a TCP stream and connects to a listening port on a remote server. I send a request to the server and I receive a response. I then let the stream sit idle for 60 minutes. At that point if I write a new request it will not arrive at the server. In short order TCP/IP will let me know that the connection has gone away.
My client code is running on a Windows laptop which is connected to a corporate environment via a VPN router. The server is whirring away up in Canada, far away from me here in central Massachusetts USA. I'm likely being routed through multiple pieces of networking equipment. I have no idea which one is causing the stream to break. (I keep thinking of Ghostbusters and "Don't cross the streams!")
What is the best term to use when a piece of equipment specifically "forgets" about a TCP connection which has been idle, causing it to break? Is that half-open, half-closed, or just plain gone?
I want to be able to simulate this timeout scenario entirely within my home lab so that I can perform easier testing -- for example where I don't have to wait for 60 minutes! What's a good technique, and what is the appropriate equipment I should use to simulate this "disconnect"? I've got extra switches here at home, as well as one old (and fiesty!) WRT router that could use some lovin'.
I do not want to enable keepalive to mask the problem. Keepalive won't prevent all possible stream disconnection scenarios, AFAIK. I want to do the best that I can at letting the problem occur and handling it quickly and cleanly when it does.
Thank you very much,
Bill S

How would an MMO deal with calculating and sending packets for thousands of players every tick for a live action game? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am working on a game and I am thinking about getting into networking. I have been programming for about 5 years and got into game development the last 2 years. I only really learn online and from books on my own time. I am planning to make a java server for Amazon AWS EC2, but I am just wondering how MMO's handle multiple players each tick.
Is it just the sheer power of servers? I am not looking for code or anything, just in general how the servers work.
Does the server just do all of the calculations for all of the players and the tens or hundreds of thousands of objects and then send and receive thousands of packets every tick? It just seems like a lot for a single computer to handle, but it is indeed a server.
How work and what is the job of a server?
Your server create a socket and open a port.
The protocol for an online game is generally in UDP because it is faster.
Your server have to handle ALL the clients connections.
You can add a server who is able to log an account and redirect him into a game server (this is the case for all the big MMO).
Your server have to manage all the calculations from the Data Base: when an enemy hit another enemy, subtract a part of your money when you buy some stuffs...
So the server is the main part of an online game.
In fact, a computer is really fast for do some calculations, the most heavy part for a modern video game is the physics and graphics... Fortunately, these both parts are on the client part.
But, a server have to be strong! Not like a client because he doesn't need a big GPU, but he need a big amount of RAM/CPU (depend of the game) and he also need to stay cold.
In fact, a game server is able to handle a large amounts of connections because of the UDP protocol and because all the heavy parts of the program are on the client side. You can take a look here: Creating a Multiplayer game in python and read the part when I explain the difference between the UDP and the TCP protocol.
All the others informations about how work an MMO server are linked at the end of this topic.
Now we can try to build a server!
Firstly, do you know how to create a server?
Program or download a server for do a test (example: TeamSpeak or Mumble).
Launch him from your computer and allow his input connections from your firewall.
Log you on your modem and forward/redirect the port of your server into your computer.
For the last part, you need to do some research: Which port is used by my server and how to forward a port with my modem (each modem is different).
Now you can try to log you into your server. But...!
Your computer have three IPs:
The Loopback address: localhost, 127.0.0.0 (The "0" can change)
The Intranet address (IP linked to your computer): 192.168.0.0, 172.16.0.0, 10.0.0.0
And the internet address (IP linked to your modem): 0.0.0.0
How to know your Intranet/internet IP? That depend of your Operating System and your modem. For the Intranet use your terminal and write "ifconfig" or "ipconfig". For your internet address, it is sometime write when you log you to your modem, or you have to visit a website who is able to show you your IP.
If you create a server and you didn't forward the port from your modem, you can still access to your server in local with your Loopback address and the others computers connected to the same modem can also access to the server with the Intranet address. Also, if you need to test if your server is accessible from internet, you have to test the connection with your internet IP, but some modem don't allow the externals connections from the Intranet... So if your connection with the internet IP doesn't work, try to log you to your server from another modem (friend's PC, Cyber-Coffee...).
Lastly, how to protect your server?
This is really difficult and you cannot create a perfect security... Especially if you follow my advices but you didn't complete my knowledge with your own research.
Root access
This is the most important part. When a lamer try to access to your server, he can just try a simple connection like the http/ssh/ftp. If he can access to your hard disk and you haven't chose a strong restriction, he can simply read/modify/delete the Data Base of your game. The Data Base contain all the informations about the accounts.
Firewall
We have already talk about the amount of connections/calculation than a server have to handle. In some attack, the lamer try to create a big amount of connections and didn't close them. We call that a DOS (with 1 computer) or DDOS (more than 1 computer). So you need a good firewall for: allow only the port of your server, allow only X numbers of connections from an unique IP and allow only X numbers of new connections every minutes.
Updates
This is the easiest part: keep your Operating System (and the others applications) up to date.
Less is better
Don't install many useless software to your server. If a software is not import for your server, you shouldn't install him because: firstly, that can be a virus. Secondly, a malware can exploit this software for install a virus or steal the root access.
Encryption
The encryption is really important for block an Hacker. For example, with the https protocol you can protected the user's passwords from the MITM attack. And with the Bluefish/SHA/others, you can encrypt your Data Base for protect her even if an Hacker can read it. The most important is always to block the write/modify/deletion/execute right of the Hacker (in fact, all the clients of your game need the read access).
Anti-virus?
In the case of an online-game, an anti-virus is not really important (But still recommended for all Operating System, Linux/Unix also).
Have a good server
If your server is programmed without take care of the security, you can be in trouble. Example: Buffer Overflow attack in C/C++.
If you need more informations about how work an MMO, I recommend you:
http://electronics.howstuffworks.com/mmorpg6.htm
https://en.wikipedia.org/wiki/Server_%28computing%29
https://en.wikipedia.org/wiki/Game_server
https://www.quora.com/How-do-I-create-an-MMORPG
Hint - If you are interesting by create an online game, you have to do many research, I cannot really answer in this question because is not the purpose of the subject. And this subject is too large for write a new answer at each question... Which software use for program a game? How to build a socket? Where started? But I have already answer at some similar questions. Even if the programming language are sometime different, I give you the link, the logic is always the same so it can maybe help you:
Creating a Multiplayer game in python
Xcode Mass Multiplayer (Not What You're Probably Thinking)
Multiplayer game in Java. Connect client (player) to game that was created by other client
Most MMO's have a healthy amount of client logic so that the server doesn't need to send multitudes of packets to every player all the time. The server doesn't do calculations for all players, the client does the heavy lifting and the server deals with the clients and the state of the virtual world in a database.
For example, your client and server could have the same world model. That way your player can navigate the world and the client code tell the server on a fairly course interval (say 100's of msecs).
Generally you want your clients to update themselves to the server, and have the server response deal with keeping the clients in sync.
MMOs also run multiple servers in their farms, from tens to hundreds. These servers typically talk to a large high-performance database - basically the state of the virtual world is in the database, and the servers sit in between keeping the database up to date and communicating to the client apps.

Java Sockets Local Connection Between 2 clients - Design

I have an application where the user (client #1) enters a local ip and a port and the application sends a picture to client #2 (who is also using the same application). However for the final application, I do not want the user to enter the local ip because they will not know this information, and I want my program to automatically figure this out.
My first idea:
Originally, I thought that I could scan all the local ip's for an open port, but this would take way too long.
My second idea:
My next idea was to have the clients send their local hostnames to a remote server which then swaps them and sends them back to the clients.
However, I do not want to run a dedicated server for my second idea.
Because this is more of a design question, I am not including any code but I will do so if necessary.
Do you guys have any ideas on how I should design my application to automatically figure out the local ips?
I did try to google this but couldn't figure out a solution, and so I gave up after an hour and just put my question here.
you can use something like jgroups (allowing discovery based on multicast [lan] etc) or some peer-to-peer implementatons for that, although the latter require at least some servers for initial discovery.
in principle that works the way, that the clients send a message out to "the world" using some well known address and wait for someone to answer. each client itself waits meanwhile for such a message and replies it with information how to "connect" to the current client. This can be done via a so called blackboard, where this bb is either a special tcp-address for multicast-messages (the os/tcp sends the message to all clients listening concurrently) or one or more servers (seeds) that take and coordinate the request and the "membership" lists. anyway, there are some tools ;)

how to know if WAN IP has changed and receive massive IP address broadcasts

The system I am developing potentially has a very large number of clients (lets say one million) that need to periodically update a central server with some information. Clients are written in Java.
The specific use-case is that the server backend needs to have an up to date mapping of IP address to clients. But the client IPs are dynamic and subject to (effectively random) change.
The solution I have in mind requires the clients to ping the server to update their IP. The period ideally should be once every minute, but even 1 ping/10 mins is acceptable.
My questions, in sequence:
1M pings per 1 min is over 10k/sec. So first off I want to know
the approaches can scale to handle such a load. This is to know the options available.
Assuming you have more than one solution in mind, which of these
would be the most economical? The cost effectiveness is critically important. I don't have my own data center or
static and fat end-point on the net, so the server application will
need to run on some sort of provider or ultimately on the cloud.
Notes:
I considered running the server from home using my own ISP provided connection, but I am neither sure of the performance issues, nor what my ISP will think about a constant stream of pings.
I can't see how the server can auto-discover these IP changes.
Erik, your problem is much simpler than it seems to have been made to sound.
This problem been around for a decade maybe two. No need to re-invent the wheel here.
Why Polling/Pinging is a Bad Idea
The dynamic IPs provided by ISPs can have a variable lease time, but will often be at least 24-72 hours. Pinging your server every 1-10m will be a horrible waist of resources potentially making over a 4,320 useless HTTP requests PER CLIENT in a 72 hour period. Each request will be say around 300 bytes * 4,320 wasted http requests equals 1.3mb wasted bandwidth multiplied by your target client count of 1 million clients, you are talking about a monthly wasted bandwidth of ~1.2 TB! And that's just the wasted bandwidth, not the other bandwidth you might need to run your app and provide useful info.
The clients need to be smarter than just pinging frequently. Rather they should be able to check if their IP address matches the DNS on startup, then only when the IP changes, send a notification to the server. This will cut down your bandwidth and server processing requirements by thousands of times.
What you are describing is Dynamic DNS
What you are talking about is "Dynamic DNS" (both a descriptive name for the technology and also the name of one company that provides a SaaS solution).
Dynamic DNS is quite simply a DNS server that allows you to very rapidly change the mapping between a name and an IP address. Normally this is useful for devices using an ISP which only provides dynamic IPs. Whenever the IP changes for the router/server on a dynamic IP it will inform the Dynamic DNS server of the change.
The defacto standard protocol for dynamic DNS is well documented. Start here: DNS Update API, I think the specifics you are looking for are here: DynDNS Perform Update. Most commercial implementations out there are very close to the same protocol due to the fact that router hardware usually has a built in DynDNS client which everyone wants to use.
Most routers (even cheap ones) already have Dynamic DNS clients built into them. (You can write your own soft client, but the router is likely the most efficient location for this as your clients are likely being NAT'd with a private IP - you can still do it but at a cost of more bandwidth for public IP discovery)
A quick google search for "dynamic DNS java client" brings up full source projects like this one: Java DynDNS client (untested, just illustrating the power of search)
Other Considerations for your System Architecture
Lets say the IP-client mapping thing gets resolved. You figured it all out and it works perfectly, you always knows the IP for each client. Would you then have a nice reliable system for transferring files to clients from mobile devices? I would say no.
Both mobiles and home computers can have multiple connection types, Wi-Fi, Cellular Data, maybe wired data. Each of these networks may have different security systems in place. So a connection from a cellular data mobile to a wifi laptop behind a home router is going to look very different than a wifi mobile device connecting to laptop on the same wifi network.
You may have physical router firewalls to contend with. Also home computers may have windows firewall enabled, maybe norton internet security, maybe symantec, maybe AVG, maybe zone alarm, etc... Do you know the firewall considerations for all these potential clients?
Maybe you could use SIP as protocol for that purpose ?
Probably the java SIP libs already solved your problem.
Nice app by the way.
I would suggest better tweak you java program to know the IP change and then only hit the web service.
You can do it like,
on your java program initiation extract the IP of machine and store
it in Global variable or better some property file.
Run a batch process/scheduler which will check your IP every 30sec/1 minute for change.Java Quartz Scheduler will come very handy for you.
Invoke the web service in case of a change of IP.
This way it reduces your server role and thus traffic and connections.
You could create your own protocol on top of UDP, for example XML based. Define 3 messages:
request - client requests a challenge from server
challenge - server replies with challenge (basically a random number)
response - client sends username and hashed password + challenge back to the server
It's lightweight and not too traffic-heavy. You can load-balance it to multiple servers at any layer or using load-balancer.
Any average PC could handle million such hits per minute, provided you do server-side in C/C++ (I don't know about java network performance)
Please have a look at how no-ip works. Your requirement is exactly same as what it does.
Do I have the use case right? A community of users all want to receive pictures from each other? You don't want to host the images on the server but broadcast them directly to all the users?
There are two questions here. The first question is "how to know if my own WAN IP address has changed."
If you are not NATed then:
InetAddress.getLocalHost()
will tell you your IP address.
If you are NATed, then using dynamic DNS and resolving your own host name will work.
The second question is something like "How to share pictures between hosts which come and go on the internet".
The possible solution space includes:
IP Multicast, probably with Forward Error Correction and Carouseling, e.g. FLUTE.
File Swarming - e.g. bittorrent.
A Publish/Subscribe message bus solution using Jabber, AMQP, JMS, STOMP or similar. Suitable implementations include RabbitMQ, ActiveMQ, etc. JMS Topics are a key concept here.
The solution should avoid the massive overheads of doing things at the IP level.

Categories