My Introduction to Liberty and WebSockets

Recently, I’ve been turned on to IBM WebSphere Libertysuper fast and highly configurable Application Server Runtime.  The runtime requires Java 7.0 to get access to the latest features to build web applications, OSGi applications and EJBs.

Two features caught my eye were Java Servlet 3.1 and Java API for WebSocket 1.0.  The WebSocket component (JSR356) in combination with the Servlet 3.1 component offer a super foundation for realtime web applications.  The WebSocket is superbly interesting as it’s “full duplex, long-lived” (per the blog).   Make that 3 features, I forgot the JSON-P feature

I just had to play around and investigate the websockets component. I setup the Eclipse environment with the WebSphere Liberty Profile. I then setup a Maven Project for Liberty.

Click File > New Maven Project
Select Use Default Workspace Location
Click Next
Select the http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/maven/repository Catalog
Select the com.ibm.tools.archetype webapp-jee7-liberty
Click Next

Maven Achetype
Maven Achetype

Enter a Group Id: com.ibm.ess.appdev.liberty
Enter a Artifact Id: demo
Enter Package: com.ibm.ess.appdev.liberty
Click Finish

Archetype Parameters
Archetype Parameters

If you find an error after creating the project, such as:

ArtifactDescriptorException: Failed to read artifact descriptor for com.ibm.tools.target:was-liberty:pom:LATEST: VersionResolutionException: Failed to resolve version for com.ibm.tools.target:was-liberty:pom:LATEST: Could not find metadata com.ibm.tools.target:was-liberty/maven-metadata.xml in local (/Users/paulbastide/.m2/repository)
pom.xml error
pom.xml error

Open the pom.xml
Copy the following snippet to the pom.xml
Click Save

 <repositories>
 <repository>
 <id>maven online</id>
 <name>maven repository</name>
 <url>https://repo1.maven.org/maven2/</url>
 </repository>
 <repository>
 <id>liberty maven online</id>
 <name>liberty maven repository</name>
 <url>http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/maven/repository/</url>
 </repository>
 </repositories>

Right Click on the demo project, and go to Run As -> Run on Server

Select Manually define a new server
Expand IBM
Select WebSphere Application Server Liberty Profile
18015657

Click Next
Select Install from an archive or a repository
Leave the default JRE selected
Click Next

Runtime Environment
Runtime Environment

Enter a Destination Path, such as /Users/paulbastide/Desktop/liberty
Select Download and Install a New Runtime Environment from Liberty Repository
Select Liberty Profile Beta Runtime
Click Next

Install the Runtime
Install the Runtime

Click Next

Select I accept the terms of all the license agreements

Click Next

Leave the defaults
Click Next

You should see demo under configured
Click Finish (It could take a few minutes to download the entire profile)

Once complete you’ll see the notice that it was installed successfully.

Success
Success

Let’s setup the server part.

Click on the Servers tab
Expand WebSphere Application Server Liberty Profile at localhost
Double Click on Server Configuration

Configuration
Configuration

Click Source
Add Children to the Feature Manager
<feature>servlet-3.1</feature>
<feature>websocket-1.0</feature>

Feature Manager
Feature Manager

Click File > Save

The server is setup to host our WebSockets.

Expand Java Resources > src/main/java > com.ibm.ess.appdev.liberty
Right Click the Package
Create a new Java Class (extending java.lang.object) – DemoEndpoint.java

Add the Framework for the Annotations

 @ServerEndpoint sets the path at which the websocket is hosted, and can contain a macro/text replacement like common JAX-RS code
 @OnOpen - start of the session
 @OnMessage - when there is a message in the session
 @OnClose - when the session is closed
 @OnError - when there is an error related to the ongoing session
 @ServerEndpoint(value = "/DemoEndpoint/{channel}")
 public class DemoEndpoint {
@OnOpen
 public void open(Session session, @PathParam("channel") String channel) {
}
@OnMessage
 public String message(String message, Session session, @PathParam("channel") String channel) {
 String result = "";
return result;
 }
@OnClose
 public void close(Session session, CloseReason reason) {
}
@OnError
 public void error(Throwable t) {
 t.printStackTrace();
 }
 }

I’m not going to extend open/error or close, and just going to focus on the message part.

Let’s do a simple channel based echoing.

Replace the method – message with the following java

 String result = "" + channel + " " + message;
 System.out.println("Message: " + message);
 return result;

Expand src > webapp
Right Click on webapp
Create a new HTML Page – demo.html

Replace the HTML page with the following Content

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8">
 <title>Insert title here</title>
 <script type="text/javascript">
 var socket = new WebSocket("ws://localhost:9080/demo/DemoEndpoint/vampire");
function sendMessage(){
 socket.send("example data");
 }
socket.onmessage = function (event) {
 document.getElementById('content').innerHTML = document.getElementById('content').innerHTML
 + "<br/>"
 + event.data;
 }
</script>
 </head>
 <body>
 <button onClick="javascript:sendMessage()">Send Sample Content to Channel
 </button>
 <div id="content">
 </div>
 </body>
 </html>

Navigate to http://localhost:9080/demo/demo.html
Click Send Sample Content to Channel

Demo
Demo

I plan on playing around with the code more, and see what I can really do with WebSockets, they offer a lot of potential (specifically with Handlers).

I am going to have to play around with error handling and sending messages across multiple sessions/users/authentication.

Some good reference articles are:

WebSphere Liberty – WebSockets Maven and WebSphere WebSocket Sample
WASDev Planning Poker WebSockets Sample WebSockets Overview WebSockets Overview From Mozilla
StackOverflow Maven Repositories Question Derby WebSockets Java Code
Configure Liberty Profile WebSockets and Liberty Overview WebSocket Cookbook