Reduce network lag in game, is p2p better than client/ server? - network-programming

I am writing a 3rd person tank shooter game and ask this about networking:
1/ I think P2P is fairer for player because the ping is about similar in each pair of players (the same distance) while client/ server will has lower ping for nearby player and higher ping for another, is it true?
2/ The game is for fun, so I can trust clients, and if I can trust client, is there any technique for better lag compensation than traditional model where you can not trust clients?

I am developing a program that uses the network just a much as any game, and we use a mix of the two.
Our client programs act as a server in a background process, which is handled by our dedicated server.
so instead of p2p, the client with the strongest connection is the server for the other clients. Our dedicated server makes that decision, and gives connection info to all other clients.

Related

What are possible Scalability options for an application supporting ONLY Single TCP Socket Connection?

There is a legacy implementation(to an extent company proprietary in Pascal, C with some java macros) which processes TCP Socket based requests from TCP client application. It supports multiple client applications(around 5K) connecting over TCP Socket, however, it only supports single socket connection with backend(database). There are two instances of the server, so in total, it supports 10K client applications over two TCP Socket connection with database. All database related communication happens in synchronous manner over single socket connection. There are massive issues in this application, especially higher RTT(Round Trip Time) and occasional outages due to back-pressure. We have an ops team for such issues. They mostly resolve them by restarting the server. Hardly, we have people in our team who know coding details of this application and there is not much documentation. As this is a critical application we can not afford messing with it. We don't want to touch the code at least for now. This even becomes more critical due to shift in business priorities. There is a need to add another 30K client applications of another business with this setup.
Task before us is to integrate it with another application which is based on microservice architecture with middleware using RabbitMQ. This is a customer facing application sensitive to higher QoS. We can not afford outage & downtime in it. As part of this integration, there is a need to process request messages coming from the above legacy application over TCP Socket before passing them to database. In other words, we want to introduce a component which would process requests of legacy application before handing over to database. This additional process is part of our client request. Some of the processing requirement is very intensive and resource hungry in terms of CPU Cycle, Memory and socket i/o. As a result, there are chances, such processing may lead to server downtime & higher RTT. Our this layer is very flexible, we can easily add more server or replace faulty ones. But, this doesn't sound very efficient in this integration as we are limited with single socket connection of legacy application. So in total at max, we can only have 2(+ 6 for new 30k client application) servers. This is our cause of concern.
I want know, what different possible options are available to address high availability, scalability and latency issues of such integration? Especially with limitation of single TCP socket connection, how can we make this integration efficient, something which can handle back-pressure, better application uptime etc.
We were thinking of leveraging RabbitMQ, Layer 4 Load balancer(like haProxy, NginX), IPVS, NAT etc.. But all lead toward making some changes(or not very efficient technique) in the legacy code, which we don't want.

Optimizing 4 player peer-to-peer network topology

I'm developing a realtime game using Sprite Kit and Game Kit. The game features a multiplayer mode where 4 players can play with each other. I've been reading the Game Kit programing guide and came across the following passage:
Although the GKMatch object creates a full peer-to-peer connection
between all the participants, you can reduce the network traffic by
layering a ring or client-server networking architecture on top of it.
Figure 8-1 shows three possible network topologies for a four-player
game. On the left, a peer-to-peer game has 12 connections between the
various devices. However, you could layer a client-server architecture
on top of this by nominating one of the devices to act as the host. If
your game transmits to or from the host only, you can halve the number
of connections. A ring architecture allows devices to forward network
packets to the next device only, but further reduces the number of
connections. Each topology provides different performance
characteristics, so you will want to test different models to find one
that provides the performance your game requires.
So here is where I am confused. Currently in my game I have implemented the peer-to-peer topology, where each user sends their position to every other player in the game. This ends up totaling 12 messages being sent, because each player sends 3 messages.
However according to the documentation, if I layer a client-server topology over my game, I can reduce the network traffic by reducing the number of connections. If I do this though, then each client will send their position to the host and then the host would need to relay those positions to the remaining clients. So now one player (the host) needs to work extra because the clients no longer communicate with each other. And then we still end up with 12 messages. The host sends 9 messages (3 messages for each player, plus 6 messages for relaying the other clients' positions) then each client sends 1 position message to the host. 9 + 1 + 1 + 1 = 12 messages. Which makes sense, all we did was unevenly distribute the message sending, so now one player needs to work harder to makeup for the less work the other players are doing.
Furthermore, relaying the client messages takes additional time because each client's position now needs to pass through the host.
So while there are now less connections, one player is sending more messages (9 messages) rather than each player evenly distributing the workload (i.e. each player sending 3 messages). This seems like it would lead to a greater chance for disconnects to occur because it will be easier for the host to disconnect from the match.
So can someone explain to me how network traffic gets reduced by layering a client-server topology? Does just the fact of having less connections in the match reduce network traffic even though overall messages are the same? Keep in mind, there is no dedicated server here, I (and the documentation) am talking about layering a client-server topology on top of the peer-to-peer match. Also isn't the host at a greater chance of disconnecting because he is sending 3X as much messages as the other players. After all, the GKMatch will disconnect a player after a brief period of packet loss. Or does simply the fact of having 12 connections have a greater chance for disconnects because of the supposedly increased traffic?
I am sorry for the very short answer to a very descriptive and well written question, but the answer is simple. The Server (you used the term "host", but this is confusing) does not have to send 3 separate messages to each client. The Server collects all the information and sends just one message containing all information to each client.

So many persistent connections to the server. Is that the right way?

I would like to understand networking services with a large user base a bit better so that I know how to approach a project I am busy with.
The following statements that I make may be incorrect but they still lead to the question that I want to ask...
Please consider Skype and TeamViewer clients. It seems that both keep persistent network connections open to their respective servers. They use these persistent connections to initiate additional connections. Some of these connections are created by means of Hole Punching if the clients are behind NATs. They are then used for direct Peer-to-Peer communications.
Now according to http://expandedramblings.com/index.php/skype-statistics/ there are 300 million users using Skype and 4.9 million daily active users. I would assume that most of that 4.9 million users will most probably have their client apps running most of the day. That is a lot of connections to the Skype servers that are open at any given time.
So to my question; Is this feasible or at least acceptable? I mean, wouldn't it be better to not have a network connection open while idle and aspecially when there are so many connections open to the servers at once? The only reason I can think is that it would be the only way to properly do Hole Punching. Techically, how is this achieved on the server side?
Is this feasible or at least acceptable?
Feasible it certainly is, you mention already two popular apps that do it, so it is very doable in practice.
As for acceptable, to start no internet authority (e.g. IETF) has ever said it is unacceptable to have long-lived connections even with low traffic.
Furthermore, the only components for which this matters are network elements that keep connection/flow state. These are for sure the endpoints and so-called middleboxes like NAT and firewalls. For the client this is only one connection, the server is usually fine tuned by the application developers (who made this choice) themselves, so for these it is acceptable. For middleboxes it's simple: they have no choice, they're designed to just work with all kind of flows, including long-lived persistent connections.
I mean, wouldn't it be better to not have a network connection open while idle and aspecially when there are so many connections open to the servers at once?
Not at all. First of all, that could be 'much' slower as you'd need to set up a full connection before each control-plane call. This is especially noticeable if your RTT is big or if the servers do some complicated connection proxying/redirection for load-balancing/localization purposes.
Next to that this would historically make incoming calls difficult for a huge amount of users. Many ISP's block/blocked unknown incoming connections from the internet by means of a firewall. Similar, if you are behind a NAT device that does not support UPnP or PCP you can't open a port to listen on for your public IP address. So you need it even aside from hole-punching.
The only reason I can think is that it would be the only way to
properly do Hole Punching. Techically, how is this achieved on the
server side?
Technically you can't do proper hole-punching as soon as the NAT devices maintain a full <src-ip,src-port,dest-ip,dest-port,protocol> (classical 5-tuple) flow match. Then the best you can do with 'hole punching' is set up a proxy between peers.
What hole-punching relies on is that the NAT flow lookup is only looking at <src-ip,src-port,protocol> upstream and <dest-ip,dest-port,protocol> downstream to do the translation. In that case both clients just set up a connection to the server, their ip and port gets translated and the server passes this to the other client. The other client can now start sending packets to that translated <ip,port> combination which should work because NAT ignores the server's ip/port. But even if the particular NAT would work like this, some security device (e.g. stateful firewall) might detect session hi-jacking and drop this anyway.
Nowadays you rather use UPnP to open up a port to listen on your public IP which is much easier if supported.

Ejabberd Clustering understanding

Let assume I have two ejabberd server consider X and Y which has the same source and i did ejabberd clustering for those server by using this. Now consider A and B are user and those are connected in X server. Both A and B are in ONLINE state and those are connected via X server. If suppose X server is get shutdown or crashed by some issue. In this sceneraio whether the A and B are get OFFLINE state or A and B are in ONLINE state which is handle by Y server. I don't know whether my thought is right or not. If any one give me the suggestion about it.
If you have nodes in different physical locations, you should set them up as separate clusters (even if it's a cluster of 1 node) and federate them. Clustering should only be done at datacenter level since there are mnesia transactional locks between all nodes in a cluster (e.g. creating a MUC room).
"Load balancing" is not what you are describing in your question.
In load balancing, a incoming connections are distributed in a balanced fashion over multiple nodes. This is so that no one server has too high a load (hence the name "load balancing"). It also provides fail-over capability if your load balancer is smart enough to detect and remove dead nodes.
A smart load balancer can make it so that new connections always succeed as long as there is at least one working node in your cluster. However, in your question, you talk about clients "maintaining the connection". That's something quite different.
To do that, you'd either need the connection to be stateless or you'd need each client to connect to all nodes. That's not how XMPP works: it's a stateful connection to a single server. You must rely on your clients to reconnect if they get disconnected.

3G/4G peer to peer network for long-distance communication in remote area?

I'm working on an engineering project where I want a go-kart to maintain a direct connection with a base station. The base and go-kart can be separated by about a half mile (with lots of obstacles in between) which is too far for WiFi.
I'm thinking about using 3G/4G to directly connect the two. Does anyone have any resources or ideas that might help?
Or, alternatively, a better way to connect them? I'm just trying to send some sensor data (pretty low bandwidth) in real-time.
The biggest problem you face is radio spectrum that you are allowed to use. All 3G/4G spectrum is licensed to some firm and they get really unhappy (e.g. have you hunted down and fined) when you transmit in their space.
I did find DASH7 which
is an open source wireless sensor networking standard … which operates in the 433 MHz unlicensed ISM band. DASH7 provides multi-year battery life, range of up to 2 km, indoor location with 1 meter accuracy, low latency for connecting with moving things, a very small open source protocol stack …
with a parts cost around US$ 10. This sounds like it satisfies your requirements and keeps the local constabulary from bothering you.
You could maybe use SMS, between a modem on the kart and a mobile phone or modem at the base.
A mobile data connection like a telephone call isn't possible directly between the two; you have to make a data connection from the kart to a server in your operator's core network, identified by the APN. Then you can access IP addresses as for a normal internet connection - so the base computer would have to be a web server.

Resources