Interact with Kaazing Gateway Using the WebSocket API

If you are looking for Android development information, see the Kaazing Android SDK topics in the table of contents.

This procedure describes how you can use the WebSocket API provided by the Kaazing Java WebSocket client library in Java. This API allows you to take advantage of the WebSocket standard as described in the HTML5 specification. For example, you can create a stand-alone Java application that uses the Java HTML5 Communications client library to interact directly with a back-end server. The support for WebSocket is provided by the WebSocket class and its supporting classes.

This topic covers the following information:

Refer to the Java API documentation for a complete description of all the available methods.

Before You Begin

This procedure is part of Checklist: Build Java WebSocket Clients.

Note: Learn about supported browsers, operating systems, and platform versions in the Release Notes.

To Use the WebSocket API in Java

  1. Add the necessary import statements:
    import com.kaazing.net.http.HttpRedirectPolicy;
    import com.kaazing.net.ws.WebSocket;
    import com.kaazing.net.ws.WebSocketFactory;
    import com.kaazing.net.ws.WebSocketMessageReader;
    import com.kaazing.net.ws.WebSocketMessageType;
    import com.kaazing.net.ws.WebSocketMessageWriter;
    
  2. Create a WebSocket object and connect to a server:
    wsFactory = WebSocketFactory.createWebSocketFactory();
    wsFactory.setDefaultRedirectPolicy(HttpRedirectPolicy.ALWAYS);
    webSocket = wsFactory.createWebSocket("wss://demos.kaazing.com/echo");
    webSocket.connect(); // This will block or throw an exception if failed.
    
  3. To send messages, add a WebSocketMessageWriter object:
    WebSocketMessageWriter messageWriter = webSocket.getMessageWriter();
    String text = "Hello WebSocket!";
    messageWriter.writeText(text);
    
  4. To receive or consume messages, add WebSocket and WebSocketMessageReader objects:
    wsFactory = WebSocketFactory.createWebSocketFactory();
    ws = wsFactory.createWebSocket(URI.create("wss://demos.kaazing.com/echo"));
    ws.connect(); // This will block or throw an exception if failed.
    
    WebSocketMessageReader reader = ws.getMessageReader();
    WebSocketMessageType type = null; // Block till a message arrives
      // Loop till the connection goes away
      while ((type =  reader.next()) != WebSocketMessageType.EOS) {
        switch (type) { // Handle both text and binary messages
          case TEXT:
            CharSequence text = reader.getText();
            log("RECEIVED TEXT MESSAGE: " + text.toString());
            break;
          case BINARY:
            ByteBuffer buffer = reader.getBinary();
            log("RECEIVED BINARY MESSAGE: " + getHexDump(buffer));
            break;
        }
    }
    

    Note: The WebSocket connection above is created for sending and receiving messages. These examples are used because most clients will either send or receive messages. If your client both sends and receives messages, you would only need to create a single WebSocket connection.

    Here is an example using a for loop to alternate between text and binary messages, and the code is placed within try catch blocks:

    try {
        // Create a new WebSocket object
        wsFactory = WebSocketFactory.createWebSocketFactory();
        ws = wsFactory.createWebSocket(URI.create("wss://demos.kaazing.com/echo"));
        ws.connect(); // This will block or throw an exception if failed.
      
         /* Use the WebSocketMessageWriter class method getMessageWriter() 
         to send text and binary messages */ 
         WebSocketMessageWriter writer = ws.getMessageWriter();
    
         // Send messages using a for loop to alternate between text and binary messages
         for (int i = 0; i < 100; i++) {
             String text = "Hello WebSocket - " + i;
             // For even numbered loops, send text
             if (( i %2) == 0) {
                 writer.writeText(text);   // Send text message
             }
             else {
                 // For odd numbered loops, send binary
                 ByteBuffer buffer = ByteBuffer.wrap(text.getBytes());
                 writer.writeBinary(buffer);   // Send binary message
             }
         }    
         ws.close();
     }
    catch (Exception ex) {
        ex.printStackTrace();
    }
    

    Here is how to receive messages on the consumer side using a while loop and switch statement:

    try {
        // Create a new WebSocket object
        wsFactory = WebSocketFactory.createWebSocketFactory();
        ws = wsFactory.createWebSocket(URI.create("wss://demos.kaazing.com/echo"));
        ws.connect(); // This will block or throw an exception if failed.
    
         // Use the getMessageReader() method    
         WebSocketMessageReader reader = ws.getMessageReader();
    
         WebSocketMessageType type = null; // Block until a message arrives
         while ((type =  reader.next()) != WebSocketMessageType.EOS) { // Loop until the connection is closed
             switch (type) {
                 // Run if type is TEXT
                 case TEXT:
                     CharSequence text = reader.getText();
                      log("RECEIVED TEXT MESSAGE: " + text.toString());
                      break;
    
                 // Run if type is BINARY
                 case BINARY:
                     ByteBuffer buffer = reader.getBinary();
                      log("RECEIVED BINARY MESSAGE: " + getHexDump(data)); // see getHexDump() below
                      break;
             }
         }
         ws.close();
     }
    catch (Exception ex){
       ex.printStackTrace();
    }
    
    private String getHexDump(ByteBuffer buf) {
        if (buf.position() == buf.limit()) {
            return "empty";
        }
    
        StringBuilder hexDump = new StringBuilder();
        for (int i = buf.position(); i < buf.limit(); i++) {
            hexDump.append(Integer.toHexString(buf.get(i)&0xFF)).append(' ');
        }
        return hexDump.toString();
    }
    
    

WebSocket and WsURLConnection

The Kaazing Gateway Java WebSocket API offers two options for creating and using WebSocket connections to enable developers to leverage their java.net Socket or URL experience:

WebSocket Class

The WebSocket class is demonstrated in the Build the Java API Client Demo example, but there are some additional elements to be aware of such as methods for text and/or binary WebSocket messages. These methods are described in Methods for Text and Binary Messages.

WsURLConnection

The WsURLConnection class is provided for developers accustomed to creating an URLConnection object and then using java.io.InputStream and java.io.OutputStream classes from java.io to receive and send data. The WsURLConnection extends URLConnection to enable you to use WebSocket-specific features and provide bidirectional communication.

The following example demonstrates how WsURLConnection enables you to create a URLConnection object for a WebSocket URL:

URL location = URLFactory.createURL("wss://demos.kaazing.com/echo");
URLConnection urlConn = location.openConnection();
InputStream inStream = urlConn.getInputStream();

There are two important things to note in this example:

With WsURLConnection and URLFactory, you can continue to create URLConnection objects as you have previously and simply use WebSocket to take advantage of additional methods provided by WsURLConnection.

URLFactory

The URLFactory class is included to support custom protocols and schemes not supported by java.net.URL. Namely, the WebSocket protocol’s ws:// and wss:// schemes. java.net.URL supports http, https, ftp, file, and jar protocols only and the java.net.URLStreamHandlerFactory class registration is not extensible. After importing the URLFactory class, one of the createURL() methods is used to create a WebSocket URL object from either:

For more information about the URLFactory class, see the Kaazing Gateway Java WebSocket API.

Setting and Overriding Defaults on the WebSocketFactory

You can set a default redirect-policy on the WebSocketFactory. All the WebSockets created using that factory automatically inherit the default. You can then override the defaults on an individual WebSocket, if desired. Unlike the HttpURLConnection in the Java SDK that uses the boolean InstanceFollowRedirects method to specify whether the WebSocket follows redirects automatically, the Kaazing Gateway Java WebSocket API also provides the following options:

Option Description
NEVER Do not follow HTTP redirects.
ALWAYS Follow the HTTP redirect requests always, regardless of the origin, domain, etc.
SAME_ORIGIN Follow the HTTP redirect only if the origin of the redirect request matches. This implies that both the scheme/protocol and the authority between the current and the redirect URIs should match. The port number should also be the same between the two URIs.
SAME_DOMAIN Follow HTTP redirect only if the domain of the redirect request matches the domain of the current request. For example, URIs with identical domains would be ws://production.example.com:8001 and ws://production.example.com:8002.
PEER_DOMAIN Follow the HTTP redirect only if the redirected request is for a peer-domain. For example, the domain in the URI ws://sales.example.com:8001 is a peer of the domain in the URI ws://marketing.example.com:8002.
SUB_DOMAIN Follow the HTTP redirect only if the request is for sub-domain. For example, the domain in the URI ws://benefits.hr.example.com:8002 is a sub-domain of the domain in the URI ws://hr.example.com:8001.

You can set the default redirect option on the WebSocket Factory using the setDefaultRedirectPolicy() method and then override it on a WebSocket connection using the setRedirectPolicy() method.

import com.kaazing.net.http.HttpRedirectPolicy;
.
.
.
WebSocket wsFactory = WebSocketFactory.createWebSocketFactory();
wsFactory.setDefaultRedirectPolicy(HttpRedirectPolicy.SUB_DOMAIN);
wsFactory.createWebSocket(location);

Here is an example of the SUB_DOMAIN option overridden on a WebSocket connection:

WebSocket ws;
ws = wsFactory.createWebSocket(location);
ws.setRedirectPolicy(HttpRedirectPolicy.ALWAYS);
ws.connect();

Methods for Text and Binary Messages

Both the WebSocket and WsURLConnection classes offer methods to suit the data types your client will handle.

Text and Binary Clients

Clients using both text and binary messages can use the getMessageReader() and getMessageWriter() methods, available in both the WebSocket and WsURLConnection classes. These methods receive binary and text messages based on the WebSocketMessageType class. The WebSocketMessageType class represents the types of messages that are received by WebSocketMessageReader. There are three types: TEXT, BINARY, and EOS for end–of–stream. For receiving messages, you can use a switch block for the different message types:

Thread messageReceivingThread = new Thread() {
    public void run() {
      WebSocketMessageType type = null;
      try {
          WebSocketMessageReader reader = webSocket.getMessageReader();
          while ((type = reader.next()) != WebSocketMessageType.EOS) {
              switch (type) {
                  case BINARY:
                      ByteBuffer data = reader.getBinary();
                      log("RESPONSE:" + getHexDump(data));
                      break;
                  case TEXT:
                      CharSequence text = reader.getText();
                      log("RESPONSE:" + text.toString());
                      break;
              }                                        
          }                                    
      webSocket.close()
        }
      catch (Exception ex) {
          log("Exception: " + ex.getMessage());
      }
    }
};
Note: In UI-based Java clients, receiving messages should be done on a separate thread to avoid blocking the java.awt EventDispatchThread. Review the example in Build the Java API Client Demo to see a demonstration.

Text-only Clients

Text-only clients can use the getReader() and getWriter() methods, available in both the WebSocket and WsURLConnection classes. If either method is used to receive binary messages, or the methods are invoked before a connection is made, then an IOException is thrown.

Binary-only Clients and I/O Streams

Both WebSocket and WsURLConnection classes support APIs that enable use the use of byte-based data streams as they define getInputStream() and getOutputStream() methods. getInputStream() is used for receiving binary streams and getOutputStream() is used to send binary streams. If either method is used to receive text messages, or the methods are invoked before a connection is made, then an IOException is thrown. Once the connection is closed, a new InputStream or OutputStream must be obtained using the getInputStream() and OutputStream() methods after the connection has been established. Using the old InputStream or OutputStream will result in IOException.

Look at the Java WebSocket Client Tutorial App

The following procedure walks through the steps of building and running the Java WebSocket tutorial app that is available on Github at https://github.com/kaazing/java.client.tutorials/tree/develop/j2se/java-ws-demo. The tutorial app code displays how to use the Java WebSocket API to create a client that creates a WebSocket connection with the Gateway, sends and receives messages, and includes a command-line interface.

Note: You will need Java 1.8 and Gradle 2.10 or higher to build and run the tutorial app.
  1. Download or clone the Kaazing Java Tutorials repository at https://github.com/kaazing/java.client.tutorials.
  2. In Terminal or a command prompt, naviagte to the Java WebSocket Tutorial app folder, java.client.tutorials/j2se/java-ws-demo.
  3. Build the app by entering the following:
    gradle installDist
  4. Navigate to the built app in java.client.tutorials/j2se/java-ws-demo/build/install/java-ws-demo/bin.
  5. Run the app by entering the following:

    ./java-ws-demo (Mac or Linux), java-ws-demo.bat (Windows)

    The Java app automatically connects to wss://demos.kaazing.com/echo.

  6. Type a message and click Enter. The message is sent to the Echo service on the Gateway and echoed back to the Java app, which then displays the message.
    MESSAGE PUBLISHED: Hello WebSocket!
    >>> RESPONSE:Hello WebSocket!

You now have a working WebSocket client using the Kaazing Java API. Congratulations! Using what you’ve learned here, you can now build your own Java clients and leverage the power of WebSocket.