Stand-alone Java Client for jWebSocket Server – communicating from Java Client to Web Clients and vice versa over WebSockets

In a previous article, I have discussed the open source jWebSocket Server and a simple installation and configuration (https://technology.amis.nl/blog/14940/first-steps-with-jwebsocket-open-source-java-framework-for-websockets-installation-and-running-samples). Subsequently, I have shown the implementation of a web client for a synchronized Slideshow application, where WebSocket communication is used to perform Client 2 Client push (https://technology.amis.nl/blog/14949/push-based-synchronized-slideshow-web-application-implemented-using-websockets-and-jwebsocket-server-the-open-source-java-websocket-server). In a third article I have explained how jWebSocket server can be integrated with a Java application that can start the server and interact with it (https://technology.amis.nl/blog/14973/implementing-a-java-server-side-component-for-jwebsocket-server-for-websocket-interaction-with-web-clients). Finally in this article I demonstrate how a stand alone Java Client can connect to a ‘remote’ jWebSocket server and open WebSocket interactions with it.

The functionality realized in this article is a simple Java application that listens to slide selection events as pushed from the clients to the WebSocket and that also pushes slide change instructions over WebSockets to the clients. After starting the jWebSocket server and opening one or more clients, running the Java Application created in this article will guide all clients through a sequence of slides.

Image

and a few seconds later:

Image

The steps for implementation using jWebSocket and NetBeans are the following:

1. Create a new Java Application project in NetBeans

Image

2. Add the required libraries to the project

open the libraries node; from the context menu select add JAR/Folder

Image

Browse to the folder JWEBSOCKET_HOME/libs and select the following libraries:

Image

So as to make the following list of libraries

Image

3. Implement the Java Client class

package nl.amis.jwebsocket;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.jwebsocket.api.WebSocketClientEvent;
import org.jwebsocket.api.WebSocketPacket;
import org.jwebsocket.client.token.BaseTokenClient;
import org.jwebsocket.api.WebSocketClientListener;
import org.jwebsocket.kit.RawPacket;
import org.jwebsocket.kit.WebSocketException;
import org.jwebsocket.packetProcessors.JSONProcessor;
import org.jwebsocket.token.Token;

/**
 *
 * @author lucas_j
 */
public class StandaloneJWebSocketJavaClient implements WebSocketClientListener {

    public static void main(String[] args) {
        StandaloneJWebSocketJavaClient c = new StandaloneJWebSocketJavaClient();
        BaseTokenClient client = new BaseTokenClient();
        client.addListener(c);
        try {
            client.open("ws://localhost:8787/jWebSocket");
        } catch (WebSocketException ex) {
            Logger.getLogger(StandaloneJWebSocketJavaClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            client.login(null, null);
        } catch (WebSocketException ex) {
            Logger.getLogger(StandaloneJWebSocketJavaClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        for (int i = 0; i < 30; i++) {
            try {
                // wait for 3 seconds, then move to next slide
                Thread.sleep(3000);
                c.sendPacket(client, i % 5 + 1); // slides 1..5, then back to 1
            } catch (InterruptedException ex) {
            }
        }
    }

Image

There is a lot going on here. A new BaseTokenClient is instantiated. The class itself is added as listener to the client. Subsequently, a connection is opened to the stand alone, potentially remote jWebSocket server at the URL ws://localhost:8787/jWebSocket.

When the connection has been made, the client is logged in to. From that moment on, the callback methods are triggered when messages are received, as we will see a little further on. Additionally, a loop is entered where 30 times a 3 second delay is created followed by an instruction to all connected clients to progress to the slide with a number from 1-5. This instruction is sent through the call to sendPacket().

Image

    public void sendPacket(BaseTokenClient client, int slideNumber) {
        String json = "{'action':'slide','uniqueId':123543,'slideNumber':" + slideNumber + "}";
        try {
            client.broadcastText(json);
        } catch (WebSocketException ex) {
            Logger.getLogger(StandaloneJWebSocketJavaClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

When the slide updated on the Web Client side, an event is published in the client to the WebSocket. These events are pushed to the Java Client and handled in its processPacket callback method:

Image

Clearly this is a very dull way of processing the websocket message. The outcome in this case, resulting from a number of slide selections in the web clients, is as follows:

Image

4. Extend the JavaScript client

it turns out that the message sent by the Java Client has a slightly different layout than the message sent previously by the client itself. The properties action, uniqueId and slideNumber are part of an object that is available as property data in the token that is received in the client. The onToken call back function has been extended a little:

Image

The JavaScript message reception is logged in the browser:

Image

And more importantly, the slide is updated:

Image

Resources

Download the sources discussed in this article: JWebSocketStandAloneJavaClient.zip.