i'm working on an Java client-server application.
The client send a message sequence (the messages can be different types, i,ve got header), and listens for the replies. I've got 2 thread, one for the transmission and one for the receipts.
So i need to handle the replies, in case of errors or in case of the replies doesn't arrive, for example i can try to send the message another time.
My question is.. is there any java patterns that can helps me?
i would like to handle the send and the relative repliy like a single transaction, but note that i don't need to have a synchronous communication. I send all the message in the sequence in the TX thread and wait for the replies on the RX thread.
I've thought to the mediator Pattern, but i don't know if it is the right way.
Thanks
If the question is purely about transmission protocol I would take a look at NAK. http://en.wikipedia.org/wiki/NAK_(protocol_message)
I have implemented a protocol I made up called JCast that sends files over multicast. The files are broken down into small fragments that are numbered. The receiving clients then respond back with any missing fragments that it did not get (these are the NAK's). The server then would resend only the NAK'd fragments.
EDIT: The benefit of NAK over ACK is that the server can send all the packets it needs to without having to wait for ACK's. Since networks are very much improved nowadays, most of the packets would arrive. The few that do not arrive would then just be resent.
Related
I am using grpc-streaming in java. I have a long-lasting open stream where the client and server communicate simultaneously. When I call onNext to send a message, grpc buffers the message internally and will send it on the wire async'ly. Now, if the stream is lost in the middle of sending data, onError is called. I wonder what are the right practices:
to find out which messages were sent successfully
how to retry unsent messages
Currently, I am thinking of implementing an "ack" mechanism in the application layer where for every x items received, the receiver sends back an ack message. Then in order to implement retries, I need to buffer items on the sender side and only remove them from the buffer when the ack is received. Also, on the receiver side, I need to implement a mechanism to ignore duplicate items received.
Example:
Suppose we send an ack for every 100 items sent. We receive ack on batch 3 (200-300) and then we receive an error while sending items 300-400. we try again to send items 300-400 but the client has successfully received 300-330 and it is going to receive them again. so, the client needs to ignore the first 30 items.
It is possible to implement this in the application layer. However, I am wondering if there are better practices/frameworks out there that solve this problem.
The term often used is guaranteed delivery to describe delivery data from one place to another without loss.
Your use case is similar to trying to provide guaranteed delivery over best effort delivery transport layers like UDP. The usual approach is to acknowledge every packet, although you could devise a scheme to check at a higher level as you suggest.
You also usually want to use some form of sliding window which means you don't have to wait for the previous ack before sending the next packet - this helps avoid delays.
There is a very good overview of this approach on UDP in this answer: https://stackoverflow.com/a/15630015/334402
For your case, you will receive a response for your RPC calls which will effectively be the ack - using a sliding window would allow you make th next call before you have received the ack from the previous one.
Your duplicate delivery example is also quite common - one common way to avoid double counting or getting confused is to have packet numbers and simply discard any duplicated packets.
Sorry for such the long post. I have done lots and lots of research on this topic and keep second guessing myself on which path I should take. Thank you ahead of time for your thoughts and input.
Scenario:
Create a program in Java that sends packets of data every .2-.5 seconds that contain simple "at that moment" or live data to approximately 5-7 clients. (Approximately only 10 bytes of data max per packet). The server can be connected via wifi or ethernet. The clients however are restricted to only using Wifi. The client(s) will not be sending any packets to the server as it will only display the data retrieved from the server.
My Thoughts:
I originally started out creating the server program using TCP as the transport layer. This would use the ServerSocket class within Java. I also made it multithreaded to accept multiple clients.
TCP sounded like a great idea for various reasons.
With TCP, the message will always get sent unless the connection fails.
TCP rearranges the order of packets sent.
TCP has flow control and requires more time to set up when started.
So, perfect! The flow control is crucial for this scenario (since the client wants the most concurrent information), the setup time isn't that big of a deal, and I am pretty much guaranteed that the message will be received. So, its official, I have made my decision to go with TCP....
Except, what happens when TCP gets behind due to packet loss? "The biggest problem with TCP in this scenario is its congestion control algorithm, which treats packet loss as a sign of bandwidth limitations and automatically throttles the sending of packets. On 3G or Wi-Fi networks, this can cause a significant latency."
After seeing the prominent phrase "significant latency", I realized that it would not be good for this scenario since the client needs to see the live data at that moment, not continue receiving data from .8 seconds ago. So, I went back to the drawing board.
After doing more research, I discovered another procedure that involved UDP with Multicasting. This uses a DatagramSocket on the server side and a MulticastSocket on the client side.
UDP with Multicasting also has its advantages:
UDP is connectionless, meaning that the packets are broadcasted to anyone who is listening.
UDP is fast and is great for audio/video (although mine is simple data like a string).
UDP doesn't guarantee delivery - this can be good or bad. It will not get behind and create latency, but there is no guarantee that all client(s) might receive the data at that moment.
Sends one packet that gets passed along.
Since the rate of sending the packets will be rather quick (.2-.5 sec), I am not too concerned about losing packets (unless it is consistently dropping packets and looks to be unresponsive). The main concern I have with UDP above anything is that it doesn't know the order of which the packets were sent. So, for example, lets say I wanted to send live data of the current time. The server sends packets which contain "11:59:03", "11:59:06", "11:59:08", etc. I would not want the data to be presented to the client as "11:59:08", "11:59:03", "11:59:06", etc.
After being presented with all of the information above, here are my questions:
Does TCP "catch up" with itself when having latency issues or does it always stay behind once the latency occurs when receiving packets? If so, is it rather quick to retrieving "live" data again?
How often do the packets of data get out of order with UDP?
And above all:
In your opinion, which one do you think would work best with this scenario?
Thanks for all of the help!
Does TCP "catch up" with itself when having latency issues or does it always stay behind once the latency occurs when receiving packets?
TCP backs its transmission speed off when it encounters congestion, and attempts to recover by increasing it.
If so, is it rather quick to retrieving "live" data again?
I don't know what that sentence means, but normally the full speed is eventually restored.
How often do the packets of data get out of order with UDP?
It depends entirely on the intervening network. There is no single answer to that.
NB That's a pretty ordinary link you're citing.
UDP stands for 'User Datagram Protocol', not 'Universal Datagram Protocol'.
UDP packets do have an inherent send order, but it isn't guaranteed on receive.
'UDP is faster because there is no error-checking for packets' is meaningless. 'Error-checking for packets' implies retransmission, but that only comes into play when there has been packet loss. Comparing lossy UDP speed to lossless TCP speed is meaningless.
'UDP does error checking' is inconsistent with 'UDP is faster because there is no error-checking for packets'.
'TCP requires three packets to set up a socket connection, before any user data can be sent' and 'Once the connection is established data transfer can begin' are incorrect. The client can transmit data along with the third handshake message.
The list of TCP header fields is incomplete and the order is incorrect.
For TCP, 'message is transmitted to segment boundaries' is meaningless, as there are no messages.
'The connection is terminated by closing of all established virtual circuits' is incorrect. There are no virtual circuits. It's a packet-switching network.
Under 'handshake', and several other places, he fails to mention the TCP four-way close protocol.
The sentences 'Unlike TCP, UDP is compatible with packet broadcasts (sending to all on local network) and multicasting (send to all subscribers)' and 'UDP is compatible with packet broadcast' are meaningless (and incidentally lifted from an earlier version of a Wikipedia article). The correct term here is not 'compatible' but supports.
I'm not fond of this practice of citing arbitrary Internet rubbish here and then asking questions based on it.
UDP packets will may get out of order if there are a lot of hops between the server and the client, but more likely than getting out of order is that some will get dropped (again, the more hops the more chance of that). If your main concern with UDP is the order, and if you have control over the client, then you can simply have the client discard any messages with an earlier timestamp than the last one received.
Let's say you want to make a real-time game, perhaps a 2D topdown game.
Things you would do in the game to keep it simple are:
Connect to the server
Move the player with the keys
Possibly press space bar to attack
Send a chat message
But what would happen if a datagram from any of these situations get lost?
What would you do?
1) Connecting to the server
If you send a UDP datagram to the server, the server would take your IP and port and then create a player
based on an ID it gives you, this it how it identifies you every time it receives a datagram from you.
But what if upon "connection" (not actually a connection, just a udp datagram that says 'make me a part of your server'), this initial datagram gets lost. Is it right to say that you would just resend it if after a certain period of time you did not receive a reply back from the server?
2) Moving the player/attacking
If at any time we move the player/press a movement key/attack key, we would send a keystroke
to the server telling it what key we pressed/released.
The server would then relay this to all the other clients.
But what if this keystroke datagram gets lost? Either upon client->server or server->clients.
Because keystrokes are happening all the time, is it efficient to just resend it all the time?
Or would we just ignore the fact that it got lost along the way because there's a chance that if you press a key again it will most likely make it the next time?
3) Sending a chat message
This would be something that MUST reach the server.
If it got lost along the way, after a certain period of time if we did not receive a reply from the other side/receiving end, do we re-send it?
TL;DR
Is it okay to just keep resending datagrams if we know after a certain period of time it did not reach?
And also, what about confirming if a datagram got successfully sent?
If client sends a chat message to the server, and the server receives it, should the server send a reply back to the client to confirm that it received it? What would happen if that reply got lost, what then?
Typically games using UDP have an application level protocol on-top so they can send some messages reliably and others not. If they wanted to send everything reliably they would be better off using TCP. However fast-paced games can not afford the delay TCP introduces and if the packet does get lost it's often too late to re-send it!
One way to implement reliable messages is, like you suppose, to send an ACKnowledgment reply that this particular packet was received - but what if that gets dropped you ask? The sender of the reliable packet typically re-sends a certain number of times (e.g. 3 times) and if no ACK is still received the sender then assumes the peer has dropped.
An excellent place for articles and game networking including how to minimise data sent is Shawn Hargreaves blog. (This is focused at C# XNA but the same logic applies irrespective of language/framework/platform).
Lastly:
Game network programming for fast paces games is hard. If your game is slow and/or turn based consider TCP and a lock-step approach which makes things considerably easier.
Don't re-invent the wheel, there are libraries that do things such as implementing reliability on top of UDP for when you need it, e.g. FalconUDP. Though this is a .NET one - I would like to see a Java port :)
If a datagram gets lost there is nothing the receiver can do, because he doesn't know about it. It's up to the sender to re-send, and it's up to you to design an ACK-based or NACK-based protocol so that the receiver knows when to do that.
Whether it is okay to just keep resending UDP datagrams depends on how the server treats the data in the datagrams. For example, if you resend a chat message, and the server receives both the original message and the resent message, does the server display the message twice? Note that you might end up resending even if the original message was received, because the reply to the original message might have gotten lost or delayed.
The best bet is to use TCP instead of UDP, since TCP has already solved all these problems for you. World of Warcraft, for example, started with TCP for chat and UDP for gameplay, and eventually converted to TCP for everything.
I am learning socket and server/client model concept and having a hard time understanding the server client concept. If a client sends a request, can server sends more than one respond? Or we have to put everything in one respond?
For a memory game program, when a client click a card, the action will send a request to server in order to turn the card in every player's program, if the second card does not match, the server tells players wait 2 secs, turn the 2 cards back, and then assign turn to next player. Can a server does this in multiple responds or it has to do it in single respond? Since no client requests for some responds, so I don't know if it is achievable or not.
If you're talking about TCP connections, after the connection has established client and server are equivalent, both are free to send data as long and as much they like and/or shut down their end of the connection.
Edit: After several passes I think i have understood what the second paragraph of your question is aiming for.
There is, of course, nothing which would stop the server from doing anything.. What your server seems to do, most of the time, is blocking on a InputStream.read() operation. If you want the server to operate even when no network input happens, one solution might be to use a read timeout, or check the input stream for readability before actually reading.
This is not your complete answer.
For one request, you get one response back.
Please read on this information in wikipedia for the basics
"Request-response, also known as request-reply, is a message exchange pattern in which a requestor sends a request message to a replier system which receives and processes the request, ultimately returning a message in response. This is a simple, but powerful messaging pattern which allows two applications to have a two-way conversation with one another over a channel. This pattern is especially common in client-server architectures.1
For simplicity, this pattern is typically implemented in a purely synchronous fashion, as in web service calls over HTTP, which holds a connection open and waits until the response is delivered or the timeout period expires. However, request-response may also be implemented asynchronously, with a response being returned at some unknown later time. This is often referred to as "sync over async", or "sync/async", and is common in enterprise application integration (EAI) implementations where slow aggregations, time-intensive functions, or human workflow must be performed before a response can be constructed and delivered."
I am making an application that will work much like a real time chat. A user will be constantly writing on lets say a text area and messages will be send to other users. On the communications class I have set up a receiver. When a message from someone reaches the client, the receive method will be invoked and will get the message. What I can't understand is how the code will be executed. What happens if, while the user is typing/sending a message the receive message is invoked ? What do I need to do in order for this to work properly ?
Hope the question is clear enough.
ps : Im still in the design phase thats why I haven't tested it to see what happens.
Also atm I only use a second thread to receive messages which calls the receive method.
There should not be a problem at all.
When a message from someone reaches the client, the receive method
will be invoked and will get the message. What I can't understand is
how the code will be executed?
You should have a Receiver class that will encapsulate a socket (from which your receive data) and keep a set of listeners (see Observer pattern). A GUI can be one of the listeners. When a message is received via the socket, you need to notify all listeners by forwarding the data received. This way, you have a clean and nice way to notify the GUI about new messages arrivals.
What happens if, while the user is typing/sending a message the
receive message is invoked ?
This depends on the type of IP protocol you are using but in general your don't have to worry about this although I suggest you protect your sockets using lock mechanisms.
What do I need to do in order for this to work properly ?
Here is a nice example that can give you some inspiration :)
EDIT: As for your question regarding execution flow, sending and receiving are two different and uncorrelated operations that can happen at the same time. This can be achieved by implementing send and receive operations in two different threads. Here is an article on socket communications and multithreading.
You should either do what traditional Java EE app servers have done, which is assign a separate thread for processing each incoming message, or try a Java NIO solution along the lines of Netty.