a short explanaition of what i have.
I have a Server and a Client
Client makes GET Request
The stream of the GET Request is used as Push Stream
Server pushes messages to client via this stream in a single thread
The Problem is that when i don't sent data for 30 sec the Client seems to close the Stream automaticly.
I've already set the Timout from 30 sec to LONG.MAX_VALUE with:
stream.setIdleTimeout(Long.MAX_VALUE);
For now I've implemented a "Heartbeat-Workaround" that pushes a simple String every 20sec so i elude the timeout.
I just want to know if this is the only way to do it. Or if I have to change some Settings i didn't found.
Thank you for every answer.
Regards!
Seems you are doing reverse HTTP long-polling, which does require a "heart-beat" to avoid that streams or connections are closed by an idle timeout.
It is normally better to do regular HTTP long polling (i.e. the client sends the heart-beat), because it allows the server to detect disconnected clients much quicker.
However, you are better off using solutions like CometD if you want to perform server-push messaging.
Related
Currently I got a situation which client will totally disconnect without sending an EOF(Such as the client is a phone and suddenly change network for wifi to 4G), but my server will still send message to this client. This will take at least 10 mins until server found out the peer is unreachable.
So is there an option in Java to reduce sending timeout, just like the SO_SNDTIMEO in C?
Android docs are pretty much straightforward with what they have: https://developer.android.com/reference/java/net/SocketOptions.html
SO_TIMEOUT is among the list, but it applies to reading operations only. Send operation completion usually doesn't indicate that a packet has been received by the remote host, but rather indicates that the packet has been accepted by kernel's network queue and will be sent "soon".
I won't blame Android team for not having (or at least not advertising) a socket option for sending timeout, because you don't get much information from completion of a send. It's actually up to the application level to detect disconnects. Enhance your protocol, introduce app level keepalives, try non-blocking socket mode to avoid long operations, keep track of what was actually received by a remote host - send is not enough. This will result in a much more robust application.
I tried reading some articles, but not so clear on this topic.
Would someone like to explain me below points:
Why use websocket over http
what is full duplex communication
what do you mean by lower latency interaction
Why use websocket over http?
A webSocket is a continuous connection between client and server. That continuous connection allows the following:
Data can be sent from server to client at any time, without the client even requesting it. This is often called server-push and is very valuable for applications where the client needs to know fairly quickly when something happens on the server (like a new chat messages has been received or a new price has been udpated). A client cannot be pushed data over http. The client would have to regularly poll by making an http request every few seconds in order to get timely new data. Client polling is not efficient.
Data can be sent either way very efficiently. Because the connection is already established and a webSocket data frame is very efficiently organized (mostly 6 extra bytes, 2 bytes for header and 4 bytes for Mask), one can send data a lot more efficiently than via a HTTP request that necessarily contains headers, cookies etc...
what is full duplex communication?
Full duplex means that data can be sent either way on the connection at any time.
what do you mean by lower latency interaction
Low latency means that there is very little delay between the time you request something and the time you get a response. As it applies to webSockets, it just means that data can be sent quicker (particularly over slow links) because the connection has already been established so no extra packet roundtrips are required to establish the TCP connection.
For a comparison in what's involved to send some data via an http request vs. an already established webSocket connection see the steps listed in this answer: websocket vs rest API for real time data?
These other references may also be useful:
Server-push whenever a function is called: Ajax or WebSockets
For a push notification, is a websocket mandatory?
HTML5 WebSocket: A Quantum Leap in Scalability for the Web
I'm using Netty's IdleStateHandler in my client/server communication to send heartbeats (server to client) and detect timeouts on the client. This works fine expect for rare cases when the transfer of large messages takes longer than the configured read timeout.
I my case these large messages only happen at the client's startup (baseline), during normal operation the messages are small, hence I'm reluctant to increase the overall read timeout on the client.
Is there a way for prevent the IdleStateHandler from firing idle state events while it's actually receiving data? Or am I doing something wrong?
Thanks,
Thomas
Add the IdleStateHandler as first handler to the 'ChannelPipeline' solved my problem. This ensures the timestamp of the last received data is updated as often as possible.
I have a typical client server communication - Client sends data to the server, server processes that, and returns data to the client. The problem is that the process operation can take quite some time - order of magnitude - minutes. There are a few approaches that could be used to solve this.
Establish a connection, and keep it alive, until the operation is finished and the client receives the response.
Establish connection, send data, close the connection. Now the processing takes place and once it is finished the server could establish a connection to the client to send the data.
Establish a connection, send data, close the connection. Processing takes place. client asks server, every n minutes/seconds if the operation is finished. If the processing is finished the client fetches the data.
I was wondering which approach would be the best way to use. Is there maybe some "de facto" standard for solving this problem? How "expensive" is opening a socket in Java? Solution 1. seems pretty nasty to me, but 2. and 3. could do. The problem with solution 2. is that the server needs to know on which port the client is listening, while solution 3. adds some network overhead.
is good enought
will not work at many situations, for example wne client is under firewall, NAT, and so on. Server usually accepts incoming connections from everywhere, desktops usualy not
better than 1 just because you will haven't problems when connection is lost
solutions 1+3 - make long waiting connections, with periodical sleep and reconnect after. I mean: connect to server, wait 30 sec for data, if no data received, sleep for 10 sec, loop.
Opening sockets is sometimes expensive, but not so expensive that your data processing.
I see an immediate problem with option 2. If the client is behind a firewall, he might very well be allowed to connect and do the request, but the server might be prevented to connect back to the cilent.
As you say, option 1 looks a bit nasty (not too nasty though, could work well), so among the options listed, I would go for option 3. Perhaps the server could estimate the time that's left of the processing, and hint the client, in each poll, of when it's about time to check back.
I have a J2ME app running on my mobile phone(client),
I would like to open an HTTP connection with the server and keep polling for updated information on the server.
Every poll performed will use up GPRS bytes and would turn out expensive in the long run, as GPRS billing is based on packets sent and received.
Is there a byte efficient way of polling using the HTTP protocol?.
I have also heard of long polling, But I am not sure how it works and how efficient it would be.
Actually the preffered way would be for the Server to tell the phone app that new data is ready to be used that way polling won't be needed to be done, however I don't know of these techniques especially in J2ME.
If you want solve this problem using HTTP only, long polling would be the best way. It's fairly easy. First you need to setup an URL on server side for notification (e.g. http://example.com/notify), and define a notification protocol. The protocol can be as simply as some text lines and each line is an event. For example,
MSG user1
PHOTO user2 album1
EMAIL user1
HEARTBEAT 300
The polling thread on the phone works like this,
Make a HTTP connection to notification URL. In J2ME, you can use GCF HttpConnection.
The server will block if no events to push.
If the server responds, get each line and spawn a new thread to notify the application and loopback to #1.
If the connection closes for any reason, sleep for a while and go back to step 1.
You have to pay attention to following implementation details,
Tune HTTP timeouts on both client and server. The longer the timeout, the more efficient. Timed out connection will cause a reconnect.
Enable HTTP keepalive on both the phone and the server. TCP's 3-way handshake is expensive in GPRS term so try to avoid it.
Detect stale connections. In mobile environments, it's very easy to get stale HTTP connections (connection is gone but polling thread is still waiting). You can use heartbeats to recover. Say heartbeat rate is 5 minutes. Server should send a notification in every 5 minutes. If no data to push, just send HEARTBEAT. On the phone, the polling thread should try to close and reopen the polling connection if nothing received for 5 minutes.
Handling connectivity errors carefully. Long polling doesn't work well when there are connectivity issues. If not handled properly, it can be the deal-breaker. For example, you can waste lots of packets on Step 4 if the sleep is not long enough. If possible, check GPRS availability on the phone and put the polling thread on hold when GPRS is not available to save battery.
Server cost can be very high if not implemented properly. For example, if you use Java servlet, every running application will have at least one corresponding polling connection and its thread. Depending on the number of users, this can kill a Tomcat quickly :) You need to use resource efficient technologies, like Apache Mina.
I was told there are other more efficient ways to push notifications to the phone, like using SMS and some IP-level tricks. But you either have to do some low level non-portable programming or run into risks of patent violations. Long polling is probably the best you can get with a HTTP only solution.
I don't know exactly what you mean by "polling", do you mean something like IMAP IDLE?
A connection stays open and there is no overhead for building up the connection itself again and again. As stated, another possible solution is the HEAD Header of a HTTP Request (forgot it, thanks!).
Look into this tutorial for the basic of HTTP Connections in J2ME.
Pushing data to an application/device without Push Support (like a Blackberry) is not possible.
The HEAD HTTP request is the method that HTTP provides if you want to check if a page has changed or not, it is used by browsers and proxy servers to check whether a page has been updated or not without consuming much bandwidth.
In HTTP terms, the HEAD request is the same as GET without the body, I assume this would be only a couple hundred bytes at most which looks acceptable if your polls are not very frequent.
The best way to do this is to use socket connection. Many application like GMail use them.