Please suggest java library, that implements reliable udp. It will be used for a game server to communicate to clients and to other servers.
PS Maybe you can suggest tech that will be more productive to work with for such task(game server)? But this must work on linux.
Edit: It's an action type game, so it needs to talk to server as fast as possible.
Edit 2: I found Enet which was used for a FPS game, but it's C++, will there be an overhead if I call it many times a second?
These are the libraries/frameworks I know of that implement something like reliable UDP:
Mobile Reliable UDP (MR-UDP)
MR-UDP aims at providing reliable communication based on UDP from/to mobile nodes (MNs), with least possible overhead. It extends a Reliable UDP (R-UDP) protocol with mobility-tolerating features, such as the ability to handle intermit-tent connectivity, Firewall/NAT traversal and robustness to switching of IP addresses or network interfaces (e.g. Cellular to WiFi, and vice-versa).
UDT-Java
Java implementation of UDP-based Data Transfer (UDT)
UDT is a reliable UDP based application level data transport protocol for distributed data intensive applications over wide area high-speed networks. UDT uses UDP to transfer bulk data with its own reliability control and congestion control mechanisms. The new protocol can transfer data at a much higher speed than TCP does. UDT is also a highly configurable framework that can accommodate various congestion control algorithms.
JNetRobust
Fast, reliable & non-intrusive message-oriented virtual network protocol for the JVM 1.6+.
It resides between the transport and the application layer.
Characteristics:
reliability of transmitted data
received, unvalidated data is available immediately
the package is bigger than UDP's package, but smaller than TCP's package
no flow control
no congestion control
Disclaimer: I'm the author of JNetRobust, it's new and still in alpha.
There is an java implementation of RUDP (Reliable UDP) protocol (RFC908, RFC1151)
http://sourceforge.net/projects/rudp/?source=dlp
You may find you don't need reliable messaging for all message types. For example, if you are repeatedly sending the status of things like players, and a few packets are lost it may not even matter.
There are reliable high performance UDP based libraries which support Java. One of these is 29West's LBM. It is not cheaper because it is very hard to get this right. Even with a professional product you may need a dedicated network for UDP to minimize loss.
For the purpose of a game I suggest you use a JMS service like ActiveMQ which runs wherever you can run Java. You should be able send 10K messages per second with a few milli-seconds latency.
When people say something must be as fast as possible, this can mean just about anything. For some people this means 10 ms, 1 ms, 100 us, 10 us, 1 us is acceptable. Some network routers support passing packets with a 600 ns latency. The lower the latency the greater the cost and the greater the impact on the design. Assuming you need more speed than you need can impact the design and cost unnecessarily.
You have to be realistic seeing that you have a human interface. A human cannot respond faster than about 1/20 of a second or about 50 ms. If you keep the messaging to less than 5 ms, a human will not be able to tell the difference.
Libjitsi has SCTP over UDP, which breaks everything up into packets like UDP but guarantees reliable delivery, like TCP. See https://github.com/jitsi/libjitsi/blob/master/src/org/jitsi/sctp4j/Sctp.java
UDP is by definition not a reliable service. It does not guarantee a high quality of service. You can, however, use TCP.
Related
I have a Java application that require communication between different process. Process could run in same JVM or different JVM, but runs on the same machine.
My application need to submit "messages" to another process (same or different JVM) and forgot about it. similar to messaging queue like IBM "MQ", but simple, and only use memory, no IO to hard disk for performance gains.
I'm not sure what is the best approach from Performance prescriptive.
I wonder if RMI is efficient in terms of Performance, I think it require some overhead.
What about TCP/IP socket using local host?
any other thought?
I wonder if RMI is efficient in terms of Performance, I think it require some overhead.
RMI is efficient for what it does. It does much more than most people need, but is usually more than faster enough. You should be able to get of the order of 1-3 K messages per second with a latency around 1 milli-second.
What about TCP/IP socket using local host?
That is always an option but with plain Java Serialization this will not be a lot faster than using RMI. How you do the serialization and deserialization is critical for high performance.
An important note is that much of the time is spent serializing and deserilizing the message, something most transports don't help you with, so if you want maximum performance you have to consider an efficient marshalling strategy. Most transport protocols only benchmark raw bytes.
Ironically if you are willing to use disk, it can be faster than TCP or UDP (like ZeroMQ) plus you get persistence for "free".
This library (I am the author) can perform millions of messages per second between processes with latency as low as 100 nano-second (350x lower than ZeroMQ) https://github.com/peter-lawrey/Java-Chronicle Advantages are
ultra fast serialization and deserialization, something most transport benchmarks avoid including this as it often takes much longer than the transport costs.
is that you can monitor what is happening between queues any time after the message was sent.
replay all messages.
the producer can be any amount of data ahead of your consumer to handle micro-burst gracefully up to the size of your disk space. e.g. the consumer can be TBs behind.
supports replication over TCP.
restart of either the consumer or producer is largely transparent.
If you are developing server application try to consider ZeroMQ. It has great performance, allow to build interprocess communication easier, allow to build asynchronous API.
ZeroMQ declare fantastic performance with InterProcess communication. Even better than TCP sounds great. We are consider this solution for our clusterisation schema.
Pieter Hintjens give the great answer for performance comparison between different Message Broker.
I am designing a (near) real-time Netty server to distribute a large number of very small messages to a large number of clients across the internet. In internal, go as fast as you can testing, I found that I could do 10k clients no sweat, but now that we are trying to go across the internet, where the latency, bandwidth etc varies pretty wildly we are running into the dreaded outOfMemory issues, even with 2 gigs of RAM.
I have tried various workarounds(setting the socket stack sizes smaller, setting high and low water marks, cancelling things that are too old), and they help a little, but they seem to only help a little bit. What would some good ways to optimize Netty for sending large #s of small messages without significant delays? Also, the bulk of the message only consists of one kind of message that I don't particularly care if it doesn't arrive. I would use UDP but because we don't control the client, thats not really a possibility. Is it possible to set a separate timeout solely for this kind of message without affecting the other messages?
Any insight you could offer would be greatly appreciated.
usually, if see outOfMemory you can use a thread dump tool to dump the threads. Or use something like jvirtualvm and jconsole to find out which class doesn't get GCed and keep eating your memory.
2Gigs is not big for 64 bit machines nowadays.Try to turn that a number bigger to about 3 or 4 G to see if you don't hit OOM.
If you find you can handle 10k connections easily in LAN, try to add a small delay in your netty handler. Check what happens.
You might want to look into load balancing approach. It is used to distribute the workload across the distributed system using both hardware and software. The details of what is suitable for your system depend on several factors which includes hardware upgrade, etc. Certainly, 2GB of RAM is fairly small to server 10k users and you will need to increase this limit.
You don't say whether the subscription stream is constant or bursty. You also don't say whether there is a minimum number of messages / second the client must support.
Given that I don't know anything about Redis, are any of the following practical?
For the messages you don't care about, if channel.isWritable() == false, discard immediately. Unfortunately I don't know of a way to cancel messages that are in Netty's send buffer. You wouldn't be able to cancel messages that have been passed to the TCP send buffer anyway so it's not really something to rely on.
Slow reception from the subscription to the rate of the slowest client.
Determine which clients can't keep up (maybe use the write timeout handler) and move them to a separate subscription which can be slowed down. Duplicate the published messages to both subscriptions.
Can you split the messages to send to the clients across different subscriptions. If a client can't keep up unsubscribe it from the unimportant messages.
If your average send rate is higher than the client can support over time then there isn't really a solution other than negotiating a change in requirements to reduce the maximum allowable throughput.
I'm going to develop a little Android game with multiplayer feature. I've made a server framework in C++ using eNet library and I would like to use this framework for make the server.
So, there is any networking library like eNet compatible with Java and C++? I know that exist jEnet (but is very out of date Java-enet-wrapper (https://github.com/csm/java-enet-wrapper), it's immature.
Check out https://github.com/julienr/libenet-android.
ENet is much more advisable than UDT in your case as UDT can be processor intensive and a gaming service would at least hope for many connections. The difference is from UDTs implementation of congestion control which has relatively high CPU demand. UDT is awesome, but designed more for large, high bandwith transfers over long distances, rather than small, high latency transactions which are desired in gaming.
Also note that main stream congestion control algorithms do not do well with small transactions. They work by monitoring RTT of each packet in a transaction and/or by monitoring packet loss rate within a transaction, which is moot when each transation is only 1 - 2 packets on avg. The additional demands of the congestion control protocol will effect latency even though the congestion control itself is not likely to ever be engaged if transfers are kept small.
You might try out UDT: http://udt.sourceforge.net/
I have used it before with good success to communicate between Java and C++ processes.
I need to implement a Peer To Peer File Transfer.
What protocol should I use? TCP or UDP? And why?
TCP is generically the best way to go when you want to ensure that your data gets to its intended destination with appropriate integrity.
In your case I would personnally choose tcp, because you will probably end up reimplementing tcp in some form inside of your udp packets otherwise (ask for block (syn), answer: i have block (syn ack), ok send it to me (ack)...data: (push ack)... ok done: (rst))
Also generically speaking, udp is the way to go when you want to broadcast, and you dont really care if the data gets there or not, meaning there is either high redundancy or low importance/integrity... since files require high integrity, it doesn't make a lot of sense to go UDP, again, unless you want to go through the extra work.
The only upside to udp would be the fact that is stateless, which could have some good implementations in a file sharing program.
Bottom line... go with your heart...
I'd recommend using TCP.
If you use UDP then you end up having to design and implement flow control and detection / retransmission of lost packets in your application-level protocol. Doing this in a way that gives you decent performance in good and bad networking conditions is hard work. For simple peer to peer, the payoff is generally not worth the effort.
FOLLOWUP
You ask:
and i plan to implement inter-lan calling over wifi, for that i would have to use UDP right?
Assuming that IP is implemented and the routing is set up correctly over your WiFi network(s), both UDP and TCP should work just fine.
UDP does not guarantee that the packets will be delivered, which is something that TCP does. Please take a look at this previous SO post which highlights the difference between these two protocols.
TCP helps ensure that your packets are received by the client and should be your choice for a file transfer because you want the file to be reproducible on the other end exactly as it is sent.
You can implement the file transfer using UDP too, but you would have to write your own logic for ensuring that the contents of the file are assembled correctly.
Since most users really care that all of their data makes it to the remote target with consistency, TCP is your best bet since packet error handling is managed. UDP is typically better for applications where loss is acceptable (e.g. player position in games) or where retransmission is not an option (e.g. streaming audio/video).
More on streaming
In the streaming A/V case, the data is always shipped with some error correction bits to fix some large percentage of errors. The endpoint manages the extra time required to detect (and potentially correct) the errors by buffering the stream. Nevertheless, it's obviously a ton of work (on both sides) to make it all happen and probably isn't worth it for P2P file transfer.
Update 1: audio streaming comment
The constraints are really based on required throughput, latency, and bit error rate (BER). Since these are likely both mobile devices, possibly operating across two carriers cellular networks, I'd opt for UDP with very high error-correction capability for audio. Users will likely be more displeased with no audio versus slightly corrupted audio and greater latency. Nevertheless, I would still use TCP for file transfer.
My Java application receives data through UDP. It uses the data for an online data mining task. This means that it is not critical to receive each and every packet, which is what makes the choice of UDP reasonable on the first place. Also, the data is transferred over LAN, so the physical network should be reasonably reliable. Anyway, I have no control over the choice of protocol or the data included.
Still, I am concerned about packet loss that may arise from overload and long processing time of the application itself. I would like to know how often these things happen and how much data is lost.
Ideally I am looking for a way to monitor packet loss continuously in the production system. But a partial solution would also be welcome.
I realize it is impossible to always know about UDP packet losses (without control on the packet contents). I was thinking of something along the lines of packets received by the OS but never arriving to the application; or maybe some clever solution inside the application, like a fast reading thread that drops data when its client is busy.
We are deploying under Windows Server 2003 or 2008.
The problem is that there is no way to tell that you have lost any packets if you are relying on the UDP format.
If you need to know this type of information, you need to build it into the format that you layer ontop of UDP (like the TCP Sequence Number). If you do that and the format is simple then you can easily create filters into Microsoft's NetMon or WireShark to log and track that information.
Also note that the TCP Sequence Number implementation also helps to detect out of order packets take may happen when using UDP.
If you are concerned about packet loss, use TCP.
That's one reason why it was invented.