Make everything as simple as possible, but not simpler. -Albert Einstein 

formats

Getting Started With WebSockets

websocket
Summary:  WebSockets represent a significant advancement in client-server web technology.  It is a protocol which provides  communication between a client and the server endpoint utilizing a single TCP connection.  WebSockets have a significant advantage over HTTP because the protocol allows for  persistent, bi-directional communication.   The WebSocket protocol enables development of real time analytic and multi-user applications.

Prerequisites: If you would like to obtain this article’s complete sample, it may be obtained from our GitHub repository.  All samples are Maven based java projects.  In addition, this article will require:

Lets Get Started: 

The life cycle of how a WebSocket can be summarized a follows:

  1.  The client sends an HTTP header requesting to  communicate over a WebSocket connection.
  2.  If the server supports the WebSocket protocol,  it will respond with another HTTP header as  confirmation to switch to a WebSocket connection.
  3. Finally,  a connection is established between client and server.  Both are able to  send messages to each other until the connection is closed.

NOTE:  WebSockets’ header information is much smaller in comparison to HTTP allowing for more efficient communication.

Client API:

The WebSocket specification defines an API for creating WebSocket connections between a web browser and a server.

Listing 1.0 represents the client side of WebSocket communication.

In  line 21, a  WebSocket is created by supplying a URL in the format of:

ws://<hostname>:port/<path name>

NOTE:  In this example, we have chosen to configure Apache Tomcat’s port on ‘8180’.

Next, lines 31-46 declare four WebSocket event handlers.

The onopen event  handler is invoked when a socket connection is established.

The onmessage event handler is invoked when the client receives data from the server.

The onerror  event handler is invoked when an error occurs during communication.

The onclose event handler is invoked when the connection is closed.

In lines 53-58, we define a function doSendMessage()‘  to allow the client to send a message to server using our WebSocket we previously created.

In lines 76-78, we define a function doCloseConnection()‘  to allow the client to terminate the the existing connection.

Listing 1.0:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>WebSocket: Sample 1</title>
</head>
<body>
 <form>
  <fieldset>
    <legend>Echo</legend>
    <input id="txtMessage" type="text"><br>
    <input onclick="doCloseConnection();" value="Disconnect" type="button">
    <input onclick="doSendMessage();" value="Send" type="button">
    <br>
    <textarea  id="txtAreaEcho" rows="5" cols="30">
    </textarea>
  </fieldset>
</form> 
<script type="text/javascript">

var webSocket = new WebSocket("ws://localhost:8180/websocket-sample1/myechoendpoint");

var txtAreaEcho = document.getElementById("txtAreaEcho");

txtAreaEcho.value = "";


var msg = document.getElementById("txtMessage");


webSocket.onopen = function(msgEvent)
                   { 
                      txtAreaEcho.value += "Connected ... \n";
                   };
webSocket.onmessage = function(msgEvent)
                     { 
                       txtAreaEcho.value += "Server : " + msgEvent.data + "\n";
                     };
webSocket.onclose = function(msgEvent)
                     {
                      txtAreaEcho.value += "Disconnect ... \n";
                     };
webSocket.onerror = function(msgEvent)
                      { 
                        txtAreaEcho.value += "Error ... \n";
                      };


/**
 *  Send Message
 */
function doSendMessage()
{
    webSocket.send(msg.value);
    txtAreaEcho.value += "Client : " + msg.value + "\n";
    msg.value = "";
}

/**
 *  Close Connection
 */
function doCloseConnection(){
    webSocket.close();
}
</script>
</body>
</html>

Server API: Java WebSocket 1.1

Apache Tomcat implements the Java WebSocket 1.1 API defined in  JSR-356.

In order implement our server endpoint we will apply annotations to an existing POJO called ‘EchoEndpoint’.

The annotations we will use from the Java WebSocket API 1.1  include :

  • @ServerEndpoint (javax.websocket.server.ServerEndpoint)
  • @OnOpen (javax.websocket.OnOpen)
  • @OnClose (javax.websocket.OnClose)
  • @OnMessage (javax.websocket.OnMessage)
  • @OnError (javax.websocket.OnError)

Listing 2.0: EchoEndpoint represents the server side of WebSocket communication.

In line 18, the @ServerEndpoint(“myechoendpoint”) is used to turn our POJO into a WebSocket server endpoint.   It provides the relative name for the endpoint.  As mentioned earlier, the endpoint will be accessed via  ws://localhost:8180/websocket-sample1/myechoendpoint. “myechoendpoint” is the address to access this class from the server.

In line 27, the @OnOpen  allows our method to be notified when a WebSocket connection is created.

In line 43, the @OnClose  allows our method to be notified when a WebSocket connection is closed.

In line 52, the @OnMessage allows our method to be notified when client send a message to our server endpoint.  The Session (javax.websocket.Session) class allows us to send a message back to the client.

In line 67, the @OnError allows our method to be notified when a communication error occurs.


package techbysample.websocket.sample1;

import java.io.IOException;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.Session;

/**
*
* @author TechBySample.com
*
*/

@ServerEndpoint("/myechoendpoint")
public class EchoEndpoint {

/**
*
*  Method is called when a connection is established.
*
* @param session
*/
@OnOpen
public void onOpen(Session session){
System.out.println(session.getId() + " has opened a connection");
try {
session.getBasicRemote().sendText("Connection Established");
} catch (IOException ex) {
ex.printStackTrace();
}
}


/**
* Method is called when user closes the connection.
*
* Note: You cannot send messages to the client from this method
*/
@OnClose
public void onClose(Session session){
System.out.println("Session " +session.getId()+" has ended");
}

/**
* Method is called when a user sends a message to this server endpoint.
* Method intercepts the message and allows us to react accordingly.
*/
@OnMessage
public void onMessage(String message, Session session){
System.out.println("Message from " + session.getId() + ": " + message);
try {
session.getBasicRemote().sendText(message);
} catch (IOException ex) {
ex.printStackTrace();
}
}

/**
*  Method is called when an error occurs.
*
* @param e
*/
@OnError
public void onError(Throwable e){
e.printStackTrace();
}

}

Let’s Deploy and Run our sample:

Change directory to the project’s root folder.

Follow these steps:

1.  Type:

      mvn package

2. Next, start Apache Tomcat.

3. Next, simply copy the  websocket-sample1.war  file to Apache Tomcat’s  webapps folder.

4. Open a web browser and navigate to http://localhost:8180/websocket-sample1/echo.html

 

Please be sure to enter the ‘port’ that corresponds to your local Apache Tomcat configuration.

When the page is opened, the client will attempt to establish a WebSocket connection with the server endpoint.

You should see the following in your  web browser below:

 

websocket-sample-1a

In the Apache Tomcat console window, you should also see the connection is established.

websocket-sample-1b

Next, Enter “Hello” in the textfield  and click ‘Send’.

You will see the phrase “Hello”   displayed in Apache Tomcat console window.

websocket-sample-1c

The server endpoint will also send the phrase  “Hello” back to the client.

Both client and server “Hello” phrase are displayed  in the textarea.

websocket-sample-1d

Finally, click ‘Disconnect’, in order to terminate the WebSocket connection.

The user’s browser and Apache Tomcat console will display a message indicating the communication has been closed.

websocket-sample-1e

websocket-sample-1f

 

References: 

https://tools.ietf.org/html/rfc6455

 

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 
© Techbysample.com, all rights reserved.