netty sever-to-server data streams - java

I have two Java netty servers that need to pass lots of messages between themselves fairly frequently and I want it to happen fairly promptly.
I need a TCP socket between the two servers that I can send these messages over.
These messages are already-packed byte[] arrays and are self-contained.
The servers are currently both running HTTP interfaces.
What is the best way to do this?
For example, websockets might be a good fit yet I am unable to find any websocket client examples in netty..
I'm a netty newbie so would need some strong simple examples. It surely can't be so hard?!

Since you mentioned HTTP, you could look at the HttpStaticFileServer in the examples.
When established, a TCP connection is a Channel. To send your messages, you need to write them to a ChannelBuffer and call channel.write.
Of course, this does not cover message borders. The Telnet example shows a case, where the messages are delimited by the newline character.

Related

Server-push or client-request? TCP or UDP?

I'd like to implement a function of realtime message such as chatting in facebook but several questions confuse me:
1. To reduce overhead of server and make it really 'realtime', I should use a full-duplex way of communication like socket instead of Ajax, is that right?
2. If I use socket, which protocol should I choose, TCP or UDP?
3. Assuming that I am using TCP, will server keep trying to resend the lost packages so that it would take much overhead?
4. What if the network failed in a communication between server and a client? Will the socket close it self or I should handle with several kinds of network conditions?
Can anyone help?
You can use WebSockets. XMLHttpRequest is probably obsolete now for anything real-time (because it's not real-time), though you could fall back to using it for people who use a browser that doesn't support WebSockets
Use UDP if the information you are sending is only valid for the time it is sent, for example in games that would be the position of the players (you don't care to receive the position they were in 5 seconds ago). Besides, you can't use UDP with WebSockets
For anything other than that, use TCP (unless you do hole punching to achieve p2p), because loss of data is probably bad for you, and TCP handles that.
You would have to check for and resend lost data manually with UDP anyway, unless failure in communication is acceptable by you
You will get an IOException. If the connection was closed improperly the exception will be thrown after a timeout of unresponsiveness that you are able to change according to your needs. This is assuming you use TCP, otherwise you should figure out yourself when you consider clients connected or disconnected according to the responses/data you receive (or not receive).

Streaming data in Java: RMI vs Socket

I have a server that needs to stream data to multiple clients as quickly as possible in the Observer pattern.
At least 200 messages need to be sent to each client per second until the client disconnects from the sever, and each message consists of 8 values of several primitive types. Because each message needs to be sent as soon as it is created, messages cannot be combined into one large message. Both the server and the clients reside on the same LAN.
Which technology is more suitable to implement streaming under this situation, RMI or socket?
The overhead of RMI is significant so it would not be suitable. It would be better to create a simple protocol and use sockets to send the data.
Depending on the latency that is acceptable you should configure socket buffer sizes and turn off Nagle algorithm.
I would not use RMI for this, RMI is just there for Remote Method Invocation, i.e. when the client wants to execute a method (i.e. some business logic) on the server side.
Sockets are OK for this, but you might want to consider JMS (Java Messaging Service) for this specific scenario. JMS supports something called a Topic, which is essentially a broadcast to all listeners interested in that topic. It is also generally optimised to be very fast.
You can use something like Apache ActiveMQ to achieve what you want. You also have lots of options such as persistence (in case the queue goes down messages remain in queue), message expiry (in case you want the messages to become outdated if a client does not pick them up) etc.
You can obviously implement all this using normal Sockets and take care of everything yourself, but JMS provides all this for you. You can send text or binary data, or even serialized object (I don't personally recommend the latter).
RMI is a request/response protocol, not a streaming protocol. Use TCP.

Efficient TCP Server and Data conversion in Java

Background
In my java application, I have reasonably large amounts of data sitting in ConcurrentHashMap.
Now, I need to give this data to a consumer client in XML format when the client connects to my application via a TCP port.
So in a nutshell - I have a TCP Server that a client connects to. As soon as the client connects, I have to read all the data in the Map and spit it out in XML format (custom) on the TCP port. The data in the Map keeps getting updated automatically from somewhere else using worker threads etc, so I have to keep sending the fresh data over and over to the client on this tcp port.
I want to implement a solution that is memory and cpu efficient - Mainly I would prefer not to generate too many immutable objects in the heap. .
NOTE:In future I might have to support multiple output formats (like comma separated or Json or HL7 etc). To keep it simple lets say there's different TCP port the client can connect for a specific format.
Question
With that said - I've been looking around for the best solution for my TCP Server implementation and data conversion process from ConcurrentHashMap to XML.
For TCP Server, people talk about
NETTY
Kryonet
Apache MINA
My client will be some third party, so i think kryonet is out, since client wont do the "register" business needed by Kryonet. So out of MINA and NETTY, which one is scalable and easier to understand? Any other suggestion?
FOR data conversion from ConcurrentHashMap to XML, I was thinking of using XSTREAM
Any other suggestion?
Thanks
If you have 100s or 1000s of connections you should start to consider scalability. However if you have small number of connections, using plain Sockets may be all you need.
If only a portion of the data is changing, you better off sending only the data which has changed, or at least only regenerating the XML which has changed.
How fast does it need to be? It seems like you should be able to create something that returns in less than 10ms (plus RTT) just using tomcat and a standard framework like spring-mvc. Use JAXB to convert objects to XML. If you want to support additional output formats like json it's trivial (use Jackson library for that, api is similar to JAXB).
I had a co-worker that tried the socket server approach and in the end we used tomcat because it was almost as fast and the QPS was more stable/predictable.

How to get Acknowlegement in TCP communication in Java

I have written a socket program in Java. Both server and client can sent/receive data to each other. But I found that if client sends data to server using TCP then internally TCP sends acknowledgement to the client once the data is received by the server. I want to detect or handle that acknowledgement. How can I read or write data in TCP so that I can handle TCP acknowledgement. Thanks.
This is simply not possible, even if you were programming in C directly against the native OS sockets API. One of the points of the sockets API is that it abstracts this away for you.
The sending and receiving of data at the TCP layer doesn't necessarily correlate with your Java calls to send or receive data. The data you send in one Java call may be broken into several pieces which may be buffered, sent and received independently, or even received out of order.
See here for more discussion about this.
Any data sent over a TCP socket is acknowledged in both directions. Data sent from client to server is the same as data sent from server to client as far as TCP wire communications and application signaling. As #Eric mentions, there is no way to get at that signaling.
It may be that you are talking about timing out while waiting for the response from the server. That you'd like to detect if a response is taking too long. Is it possible that the client's message is larger than the server's response so the buffering is getting in the way of the response but not the initial request? Have you tried to use non-blocking sockets?
You might want to take a look at the NIO code if you have not already done so. It has a number of classes that give you more fine grained control over socket communications.
This is not possible in pure Java since Java's network API all handles socket, which hides all the TCP details.
You need a protocol that can handle IP-layer data so you can get TCP headers. DLPI is the most popular API to do this,
http://www.opengroup.org/onlinepubs/9638599/chap1.htm
Unfortunately, there is not Java implementation of such network. You have to use native code through JNI to do this.
I want to detect or handle that acknowledgement.
There is no API for receiving or detecting the ACKs at any level above the protocol stack.
Rethink your requirement. Knowing that the data has got to the server isn't any use to an application. What you want to know is that the peer application has received it, in which case you have to get the peer application to acknowledge at the application protocol level.

Streams in java

well, i am developing a single server multiple-client program in java. My problem is can i use single stream for all the clients or do i have to create a seperate stream for each client?
please help
thank you
Typically you'd need a stream per client. In some cases you can get away with UDP and multicasting, but it doesn't sound like a great idea for a chat server.
Usually it's easy to get a stream per client with no extra work, because each client will connect to the server anyway, and a stream can easily be set up over that connection.
Yes, you can but I think it would be harder.
If you're using java.net.ServerSocket then each client accepted through:
Socket client = server.accept();
Will have it's own stream so you don't have to do anything else.
Is there a real need for a single stream for all clients or is just something you think it would help.
For the later it could cause more problems than those is solve.
Can you do it?
Yes, as Jon Skeet said, you can use multicasting.
Should you do it?
That depends on what you are using the streams for.
For most client server applications, you will need a stream per client to maintain independent communications. Of course, there are applications where using multicasting is the right approach, such as live video streaming. In such a case, you would not want to overwhelm your network while streaming the same data to multiple clients. Of course, even in this case there will typically be a single control channel of some sort between each client and server.

Categories