3

I am trying to create a Jetty servlet that allows clients (web browsers, Java clients, ...) to get broadcast notifications from the web server.

The notifications should be sent in a JSON format.

My first idea was to make the client send a long-polling request, and the server respond when a notification is available using Jetty's Continuation API, then repeat.

The problem with this approach is that I am missing all the notifications that happen between 2 requests.

The only solution I found for this, is to buffer the Events on the server and use a timestamp mechanism to retransmit missed notifications, which works, but seems pretty heavy for what it does...

Any idea on how I could solve this problem more elegantly?

Thanks!

Robin Green
  • 32,079
  • 16
  • 104
  • 187
nbarraille
  • 9,926
  • 14
  • 65
  • 92

4 Answers4

3

Sorry for bumping this up, yet I believe numerous people will come across this thread and the accepted answer, IMHO, is at least outdated, not to say misleading.

In order of priority I'd put it as following:

1) WebSockets is the solution nowadays. I've personally had the experience of introducing WebSockets in enterprise oriented applications. All of the major browsers (Chrome, Firefox, IE - in alphbetical order :)) support WebSockets natively. All major servers/servlets (IIS, Tomcat, Jetty) are the same and there are quite a number of frameworks in Java implementing JSR 356 APIs. There is a problem with proxies, especially in cloud deployment. Yet there is a high awareness of the WebSockets requirements, so NginX supported them already 1.5 year ago. Anyway, secured 'wss' protocol solves proxy problem in 99.9% (not 100% just to be on the safe side, never experienced that myself).

2) Long Polling is probably the second best solution, and the 'probably' part is due to 'short polling' alternative. When speaking of long polling I mean the repeated request from client to server, which responses as soon as any data available. Thus, one poll can finish in a few millis, another one - till the max wait time. Be sure to limit the poll time to something lesser than 2mins since usually otherwise you'll need to manage timeout error in you client side. I'd propose to limit the poll time to something like tens of seconds. To be sure, once poll finished (timely or before that) it is immediately repeated (yet better to establish some simple protocol and give to your server a chance to say to the client - 'suspend'). Cons of the long polling, which IMHO justifies the continuation of the list, is that it holds one of just a few (4, 8? still not that many) allowed connections, that browser allows each page to establish to a server. So that is can eat up ~12% to ~25% of your website's client traffic resource.

3) Short polling not that much loved by many, but sometimes i prefer it. The main Cons of this one, is, of course, the high load on the browser and the server while establishing new connections. Yet, i believe that if connections pools are used properly, that overhead much lesser than it look like on the first glance.

4) HTTP streaming, either it be page streaming via IFrame or XHR streaming, is, IMHO, highly BAD solution since it's like an accumulation of Cons of all the rest and more:

  • you'll hold the connections opened (resources of browser and server);

  • you'll still be eating up from total available client traffic limit;

  • most evil: you'll need to design/implement (or reuse design/implementation) the actual content delivery in order to be able to differentiate the new content from the old one (be it in pushing scripts, oh my! or tracking the length of the accumulated content). Please, don't do this.

Update (20/02/2019)

If WebSockets are not an option - Server Sent Events is the second best option IMHO - effectively browsers implemented HTTP streaming for you here at the lower level.

GullerYA
  • 1,320
  • 14
  • 27
  • I don't understand your answer for `HTTP Streaming`. Can you please be more explicit about the pro/con cases for this option? It seems to be the equivalent of a single long-polling connection (versus multiple connections) so if anything it sounds better than long-polling. – Gili Mar 19 '19 at 13:18
  • HTTP streaming, roughly, works as following: open some GET request from client, hold a Response's output stream in the server and just write into it from time to time. How it looks to client side: you'll be listening and processing progress event. Each time there is a progress you'd like to know what the newcoming data is. It's NOT possible to directly ask that question, but you'll need to hold all the data so far (which you also can't clean) and each progress event compute the diff between the data's last state and the current state. From time to time you'll need to reset all to clean memory. – GullerYA Mar 20 '19 at 14:31
  • In the long polling flavor there is no concurrent multiple connections, but yes, you are re-opening connection each server side message iteration (each time the connection has been 'consumed', if you'd like it). Still, looks much cleaner to me from both client and server perspective in terms of code cleanness and maintainability. BTW, if WebSockets are not an option - Server Sent Events is the second best option IMHO - effectively browsers implemented HTTP streaming for you here at the lower level. – GullerYA Mar 20 '19 at 14:45
  • It doesn't sound to me like HTTP streaming (chunked encoding) has to be implemented the way you described. You could implement an idempotent protocol on top of it so that any events you receive contain absolute values. This way you don't have to retain any state and calculate the diff between the data's last state and the current state. – Gili Mar 21 '19 at 03:35
  • If you mean by your "on top of it", that can write your self some low level library abstracting aware the whole 'get full body from the beginning, remove from it the previously known data and give out the diff only' - fine. Yet, you'll still be writing this stuff somewhere. And if you mean that it might be implemented altogether differently - you are welcome to hack around and enlight me and probably others how to do that :) – GullerYA Mar 24 '19 at 16:55
3

HTTP Streaming is most definitely a better solution than HTTP long-polling. WebSockets are an even better solution.

WebSockets offer the first standardised bi-directional full-duplex solution for realtime communication on the Web between any client (it doesn't have to be a web browser) and server. IMHO WebSockets are the way to go since they are a technology that will continue to be developed, supported and in demand and will only grow in usage and popularity. They're also super-cool :)

There appear to be a few WebSocket clients for Java and Jetty also supports WebSockets.

leggetter
  • 15,248
  • 1
  • 55
  • 61
  • @leggeter: I agree that WebSockets would have been perfect for the job, unfortunately I can't really afford their limited browser support at the moment. I'll take a look at HTTP Streaming though. Thanks! – nbarraille Sep 15 '11 at 08:15
  • I highly recommend that you read @katana's excellent answer about [WebSocket readiness](http://stackoverflow.com/questions/6434088/why-isnt-bosh-more-popular-especially-as-an-alternative-to-websockets-and-long/6442488#6442488). WebSockets, with fallback, mean that 99% of web browsers can use a WebSocket connection. – leggetter Sep 15 '11 at 17:19
  • Web sockets are not well supported by proxies. If you have a proxy between your client and the server you may require a fallback method. – ijw Jun 13 '12 at 12:35
  • If you use an SSL (wss://) WebSocket connection then, in my experience as dealing with a large amount of Pusher's support calls, the connection will be established. I believe the main reasons for the understanding that WebSockets don't work well with proxies is because developers don't use an SSL connection when developing and therefore don't check to see if it resolves the problem. Unfortunately I can't prove this yet. – leggetter Jun 14 '12 at 15:50
2

I have done this before using Http Streaming via Atmosphere framework and it worked fine.

Visit Comet, Streaming

if you see the atmosphere tutorial they have given multiple examples

1

You may want to check how they implemented this in CometD: http://cometd.org . Or you may even consider to use that tool, without having to reinvent the wheel.

perissf
  • 15,979
  • 14
  • 80
  • 117