Notes on WebSockets and Atmosphere

advertisement
Notes on WebSockets and Atmosphere
Created 04/20/14
Updated 06/12/14, Updated 10/29/14, Updated 01/17/15, Updated 01/29/15, Updated 02/26/15
Introduction to WebSockets
WebSocket is a protocol providing full-duplex communications channels over a single TCP connection. The
WebSocket protocol was standardized by the IETF as RFC 6455 in 2011, and the WebSocket API in Web IDL is being
standardized by the W3C.
WebSocket is designed to be implemented in web browsers and web servers, but it can be used by any client or server
application. The WebSocket Protocol is an independent TCP-based protocol. Its only relationship to HTTP is that
its handshake is interpreted by HTTP servers as an Upgrade request. The WebSocket protocol makes more interaction
between a browser and a web site possible, facilitating live content and the creation of real-time games. This is made
possible by providing a standardized way for the server to send content to the browser without being solicited by the
client, and allowing for messages to be passed back and forth while keeping the connection open. In this way a twoway (bi-directional) ongoing conversation can take place between a browser and the server. A similar effect has
been achieved in non-standardized ways using stop-gap technologies such as Comet.
[1]
In addition, the communications are done over TCP port number 80, which is of benefit for those environments
which block non-web Internet connections using afirewall. The WebSocket protocol is currently supported in most
major browsers including Google Chrome, Internet Explorer, Firefox, Safari and Opera. WebSocket also requires web
applications on the server to support it.
How to test if your browser supports websockets: go to www.websocket.org/echo.html
Using websockets in Tomcat
http://www.tomcatexpert.com/blog/2012/05/01/how-apache-tomcat-implemented-websocket This is a link that
describes new facilities in Tomcat to implement web sockets. Basically you extend WebSocketServlet class,
which has the following methods:
createWebSocketInbound
WebSocket messages can come in binary form, onBinaryData, or text form, onTextData, and your application may
choose to utilize one or both of these methods. Once you’ve created a class that implements both these methods
your application is ready to receive messages.
Your code that implements the createWebSocketInbound method would typically create a subclass of
MessageInbound, which will live for as long as the connection is active.
An example implementation would look like this (only text data)
private final class ChatMessageInbound extends MessageInbound {
@Override
protected void onBinaryMessage(ByteBuffer message) throws IOException {
//this application does not expect binary data
throw new UnsupportedOperationException("Binary message not supported.");
}
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
String msg = message.toString();
//modify the message by adding a timestamp
msg = “(“ + System.currentTimeMillis()+”) “+ msg;
broadcast(msg);
}
Page 1
private void broadcast(String message) {
//write some code to process the message
}
}
Writing data is pretty straightforward. Your StreamInbound implementation will have a reference to the sender
component, WsOutbound. You simply retrieve it by calling
myStreamInbound.getWsOutbound()
at that point you can send either binary
public void writeBinaryData(int b);
public void writeBinaryMessage(ByteBuffer msgBb);
or textual data to the client
public void writeTextData(char c);
public void writeTextMessage(CharBuffer msgBb);
So why do we have two methods for sending textual and two methods for sending binary data? The answer is one of
them is streaming, the other is to send a buffered message. When streaming messages, meaning you are using one of
these two methods
public void writeTextData(char c);
public void writeBinaryData(int b);
These methods are mutually exclusive. Don’t call both of these methods and expect both binary and textual data to
be sent. When you’re done streaming, simply call
public synchronized void flush() throws IOException;
If you previously called writeTextData(char c) you can switch to binary data after calling flush(). Calling flush()
completes the WebSocket message. A message can be sent down to the client in multiple frames (or fragments), a
frame being a WebSocket defined set of data. When you use the
public void writeTextMessage(CharBuffer msgBb);
public void writeBinaryMessage(ByteBuffer msgBb);
methods each set of data gets transferred as a message.
In the Apache Tomcat WebSocket Chat example, each time a message is received, it broadcasts that message to the
other clients as a separate message.
private void broadcast(String message) {
for (ChatMessageInbound connection : connections) {
try {
CharBuffer buffer = CharBuffer. wrap(message);
connection.getWsOutbound().writeTextMessage(buffer);
}
catch (IOException ignore)
// Ignore
}
}
}
Suggestions for content format
Basically you should use JSON, and binary pack it.
Page 2
WebSockets Questions
What application server support is needed? Tomcat version 7.0.27 (released in 2012) is the first one to provide this.
How does this compare to message transfer protocols such as TIBCO Rendezvous? It appears that the main
difference is that you can’t carry out wildcard subscribing, efficient distribution to lots of clients, any higher quality
of service, or any content-neutral wire formats (essentially JSON has taken the place in today’s industry that TIBCO
Rendezvous Messages used to provide).
Introduction to Atmosphere
Real Time Client Server Framework for the JVM, supporting WebSockets and Cross-Browser Fallbacks Support
It contains a server-side library (a Java jar file) for one side, and a client side library (a .js) file for the client.
The result is that one doesn’t have to deal with lower-level HTTP details of using WebSockets.
Resources
Source code at https://github.com/Atmosphere
Tutorial at http://async-io.org/tutorial.html
Why Async-IO.org?
Async-IO.org is the company behind the Atmosphere Framework! The Atmosphere Framework is the most popular
asynchronous application development framework for enterprise Java. The Atmosphere Framework provides the
enterprise features required to build massive scalable and real time asynchronous applications using transports like
WebSocket, Server Side Events and traditional Ajax Techniques.
It's been proven in production: Reverb, Wall Street Journal, GameDuell, VMWare, Atlassian and many more.
Easy to write portable and asynchronous applications with a really simple API for both client and server
 Supports WebSockets and fallback transports transparently
 Proven to scale
 Cloud Enabled!
Broadcaster
The Broadcaster object is created to be the server side of a subscription.
A Broadcaster is responsible for delivering messages to its subscribed AtmosphereResources, which are
representing suspended responses. AtmosphereResource can be added
usingaddAtmosphereResource(org.atmosphere.cpr.AtmosphereResource), so
when broadcast(java.lang.Object) is
executed,AtmosphereHandler.onStateChange(org.atmosphere.cpr.AtmosphereResourceEv
ent) will be invoked and the suspended connection will have a chance to write the message available
usingAtmosphereResourceEvent.getMessage().
A Broadcaster will by default use an ExecutorService, and the number of Threads will be computed based
on the number of cores/CPUs of the OS under which the application runs. Thus
invoking broadcast(Object) will be executed asynchronously so this is important to wait for
the Future.get() to awake/unblock to be guaranteed that the operation has completed.
One final word on Broadcaster: by default, a Broadcaster will broadcast using all AtmosphereResource on
which the response has been suspended, e.g. {AtmosphereResource#suspend()} has been invoked. This behavior is
configurable and you can configure it by invoking
the setScope(org.atmosphere.cpr.Broadcaster.SCOPE) ):
Page 3

REQUEST: broadcast events only to the AtmosphereResourceEvent associated with the current request.

APPLICATION: broadcast events to all AtmosphereResourceEvent created for the current web application.

VM: broadcast events to all AtmosphereResourceEvent created inside the current virtual machine.
DefaultBroadcaster
The default Broadcaster implementation.
Broadcast messages to suspended responses using the caller's Thread. This basic Broadcaster use
an ExecutorService to broadcast messages, hence the broadcast operation is asynchronous. Make sure you
block on broadcast(Object).get()} if you need synchronous operations.
Meteor
A Meteor is a simple class that can be used from a Servlet to suspend, broadcast and resume responses.
A Meteor can be created by invoking the build() method.
Meteor.build(HttpServletRequest).suspend(-1);
A Meteor is usually created when an application needs to suspend a response. A Meteor instance can then be cached
and re-used later for either broadcasting a message, or when an application needs to resume the suspended response.
AtmosphereResource
https://github.com/Atmosphere/atmosphere/wiki/Understanding-AtmosphereResource
Atmosphere Questions
Is this Scala specific? No
Page 4
Download