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:
- To Use the WebSocket API in Java
- WebSocket and WsURLConnection
- URLFactory
- Setting and Overriding Defaults on the WebSocketFactory
- Methods for Text and Binary Messages
- Look at the Java WebSocket Client Tutorial App
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
- 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;
- 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.
- To send messages, add a WebSocketMessageWriter object:
WebSocketMessageWriter messageWriter = webSocket.getMessageWriter(); String text = "Hello WebSocket!"; messageWriter.writeText(text);
- 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 - this class and its methods are provided for developers familiar with the Socket class in the java.net package. It implements a socket for stream-based interprocess communication over the Web.
- WsURLConnection - this class is an extension of the URLConnection class in the java.net package. It defines a network connection to an object specified by a URL. WsURLConnection adds WebSocket support to URLConnection, allowing you to create, connect and use WebSocket connections in addition to the default URLConnection subclasses HttpURLConnection and JarURLConnection. You can use all of the methods in URLConnection and the additional methods included in the WsURLConnection extension.
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:
- This example uses the URLFactory class which enables you to instantiate URL objects that support custom protocols and schemes, such as the WebSocket protocol’s ws:// and wss://. java.net.URL has native support for http, https, ftp, file, and jar protocols only.
- The URLConnection object created in the example is an instance of the WsURLConnection class. Since getInputStream() and getOutputStream() methods are available on URLConnection, there was no need to downcast URLConnection to WsURLConnection. However, if you need to access methods that are not available on URLConnection, but are only available on WsURLConnection, you can downcast the urlConn object in the example and then invoke getMessageReader():
URL location = URLFactory.createURL("wss://demos.kaazing.com/echo"); URLConnection urlConn = location.openConnection(); WsURLConnection wsConn = (WsURLConnection) urlConn; // Downcasting to WsURLConnection WebSocketMessageReader msgReader = wsConn.geMessageReader();
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:
- The String representation, by parsing the given specification within a specified context.
- A specified protocol name, host name, and file name.
- A specified protocol name, host name, port number, and file name.
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.- Download or clone the Kaazing Java Tutorials repository at https://github.com/kaazing/java.client.tutorials.
- In Terminal or a command prompt, naviagte to the Java WebSocket Tutorial app folder, java.client.tutorials/j2se/java-ws-demo.
- Build the app by entering the following:
gradle installDist
- Navigate to the built app in java.client.tutorials/j2se/java-ws-demo/build/install/java-ws-demo/bin.
- 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
. - 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.