The American Dream Realized: NYC-based Java Consultant. Author of Play Framework Mods Elastic Search, RabbitMQ. JavaLobby Featured MVB Writer. I blog at http://geeks.aretotally.in and tweet at http://twitter.com/_felipera. Felipe is a DZone MVB and is not an employee of DZone and has posted 13 posts at DZone. View Full User Profile

WebSockets in Action with Play! Framework 1.2!

05.01.2011
| 10354 views |
  • submit to reddit

WebSockets is a game-changing technology, available on newer browsers (Chrome 4, Safari 5, Firefox 4, etc), that allows bi-directional, full-duplex communication between the client (Web Browser) and the server (Web Server) over TCP. Actually the client doesn’t necessarily need to be a Web Browser but let’s focus on that since that’s really that side of the story that hasn’t been possible up to this point in time. In simple terms, it means the browser can maintain a connection to the server while the page is opened and can use that connection to send and receive data; the server can also send and receive data obviously (duh!).

WebSockets are also reached by an url, like regular Web Pages, but it introduces a new protocol, a couple actually if you include SSL, that’s ws:// and wss://. For example that’s the url for the WebSocket that I created for the demo I will show you just now: ws://mashup.fm:9002/livesearches.

So what does that mean for us developers? We can use to create those “real-time” web applications you started to hear about. So enough talk, I saw let’s get down to business, shall we?

Last week I created a demo showcasing how awesome and simple it is to do Ajax with Play! and Sammy.js, a very simple app that uses Github’s API. Live demo is available here. As Play! added WebSockets support to the recent 1.2 release, I decided to add it to the demo.

On the homepage I added a “Latest Searches” section which will list searches as they happen, from any user. Here’s how I did it:

First I created a class that has an EventStream, from their new play.libs.F library, and a controller extending the new WebSocketController. By the way, I went through play.libs.F and although the documentation is not very complete which was good, it forced me to spend some time and go through the source code and it is awesome! I will write an article about it later, there’s so much code I want to re-write with it! Here’s how it looks like:

public class LiveSearches {

	/** The live stream. */
	public static play.libs.F.EventStream liveStream = new play.libs.F.EventStream();

	/**
	 * The Class WebSocket.
	 */
	public static class WebSocket extends WebSocketController {

		/**
		 * Live searches.
		 */
		public static void stream() {
			while (inbound.isOpen()) {
				try {
					Logger.info("Waiting for next search...");
					String search = await(liveStream.nextEvent());
					if (search != null) {
						Logger.info("Publishing Live Search %s to Outbound Subscribers", search);
						outbound.send(search);
					}

				} catch (Throwable t) {
					Logger.error(ExceptionUtil.getStackTrace(t));
				}
			}
		}
	}

}

On the search controller I do LiveSearches.stream.publish(String s) to make the search term available. Then the stream() function is watching that EventStream, as soon as a search term gets published, it gets the value (await(liveStream.nextEvent())) and publishes to whoever is connected to that WebSocket (outbound.send(String s)). You might notice I didn’t define an await function, that’s provided by Play!’s awesome Async over HTTP features. You can read more about it here. This latest release also provided a major improvement since it knows where it had left off when the await happened, the beatiful part of it is that it doesn’t block the thread until a new search term gets published to the stream.

Then on the client-side it’s very simple, see it for yourself:

var socket = new WebSocket('@@{LiveSearches.WebSocket.stream()}');

    var display = function(event) {
        $('#thread').append('
' + event + ''); } socket.onmessage = function(event) { display(event.data); } 

Whenever the controller calls outbound.send(), the client receives the message with a call to socket.onmessage, then it’s regular JavaScript to display the value.

Simple huh?

The live demo is available here. Open two tabs for you to see it work, first open the home page, then on another tab open a search page. After you the hit search watch the search term popping up automatically under “Live Searches”.

The source code for the whole thing is available on Github, please feel free to fork the code, hopefully it will be helpful to you in anyway.

Now Go Play!



Read the original article  here.
Published at DZone with permission of Felipe Oliveira, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)