Extend jWebSocket by a Plug-In

This section describes how to create your first server-side jWebSocket Plug-in. Plug-ins extend the jWebSocket Server functionality by providing methods to process incoming messages from the clients as well as other events like client connected or client disconnected. Incoming messages are filtered by the jWebSocket filter chain and thus provided the same level of security like the listeners do.

Plug-ins can either be loaded programmatically by your code (especially for development purposes) or dynamically at run-time by simply including it into the jWebSocket.xml file (recommended for production environments or if you want to distribute your plug-ins).

Usually plug-ins are supposed to implement rather general than application specific logic. To implement proprietary logic please have a look at how to use the jWebSocket listeners. However, of course, you are free to implement any logic in plug-ins as it matches your requirements best. Unlike the listeners which usually are closely embedded in your application, the main benefit of plug-ins is that they are treated as separate self-sufficient pieces of software which can even be distributed separately or shared across multiple applications.

Creating your first plug-in and providing its functions to your web site is quite a simple process.

  1. Create a server side plug-in
  2. Add your plug-in to the jWebSocket Server
  3. Create a client side plug-in (recommended to keep modules and namespaces clean)
  4. Use the plug-ins in your web pages

In the Sources Package in download area you will find the jWebSocketSamples module. It contains a sample plug-in for the Server as well as for the client. It accepts a requestServerTime token and simply returns the current system time of the host system.

Create a Server Side Plug-in

The first step to extend the functionality of the jWebSocket Server is to create a server side plug-in. Please refer to our Plug-ins page to learn how plug-ins work in general. A plug-in usually is implemented as a descendant of the TokenPlugIn class which is included in jWebSocket. To develop your own plug-ins we recommend to create them in separate packages. This will make it easier to distribute them later as single .jars which can be added to each jWebSocket Server instance.

The following listing shows you a simple Plug-in with a single requestServerTime "command".

public class SamplePlugIn extends TokenPlugIn {

  private static Logger log = Logging.getLogger(SamplePlugIn.class);
  // if namespace changed update client plug-in accordingly!
  private static String NS_SAMPLE = JWebSocketConstants.NS_BASE + ".plugins.sample";
  private static String SAMPLE_VAR = NS_SAMPLE + ".started";

  public SamplePlugIn() {
    if (log.isDebugEnabled()) {
      log.debug("Instantiating sample plug-in...");
    }
    // specify default name space for sample plugin
    this.setNamespace(NS_SAMPLE);
  }

  @Override
  public void connectorStarted(WebSocketConnector aConnector) {
    // this method is called every time when a client
    // connected to the server
    aConnector.setVar(SAMPLE_VAR, new Date().toString());
  }

  @Override
  public void connectorStopped(WebSocketConnector aConnector, CloseReason aCloseReason) {
    // this method is called every time when a client
    // disconnected from the server
  }

  @Override
  public void engineStarted(WebSocketEngine aEngine) {
    // this method is called when the engine has started
    super.engineStarted(aEngine);
  }

  @Override
  public void engineStopped(WebSocketEngine aEngine) {
    // this method is called when the engine has stopped
    super.engineStopped(aEngine);
  }

  @Override
  public void processToken(PlugInResponse aResponse, WebSocketConnector aConnector, Token aToken) {

    // get the type of the token
    // the type can be associated with a "command"
    String lType = aToken.getType();

    // get the namespace of the token
    // each plug-in should have its own unique namespace
    String lNS = aToken.getNS();

    // check if token has a type and a matching namespace
    if (lType != null && lNS != null && lNS.equals(getNamespace())) {

      // get the server time
      if (lType.equals("requestServerTime")) {
        // create the response token
        // this includes the unique token-id
        Token lResponse = createResponse(aToken);

        // add the "time" and "started" field
        lResponse.put("time", new Date().toString());
        lResponse.put("started", aConnector.getVar(SAMPLE_VAR));

        // send the response token back to the client
        sendToken(aConnector, lResponse);
      }
    }
  }

}

Your first jWebSocket Plug-In

Add your Plug-in to the jWebSocket Server

The following listing demonstrates how to add your new plug-in to the plug-in chain of the jWebSocket Server.

// start the jWebSocket server sub system
JWebSocketFactory.start( ... );

// add your plug-in to the plug-in chain of the jWebSocket Server 
TokenServer lTS = (TokenServer)JWebSocketFactory.getServer("ts0");
SamplePlugIn lSP = new SamplePlugIn();
lTS.getPlugInChain().addPlugIn(lSP);

Instantiating your Plug-in

The JWebSocketFactory class loads and starts the jWebSocket Server including all its required libraries, default plug-ins and filters. First the TokenServer is obtained by its id, which is configured in the jWebSocket.xml Configuration file. Next your new plug-in is instantiated and finally added to the plug-in chain of the TokenServer. That's it, all functions of your new plug-in are now available to your clients.

Create a Client Side Plug-in

In general there are two ways of accessing the server side plug-in. First you can simply use the sendToken method of the jWebSocket.js JavaScript library and implement a listener to its OnMessage method. For details please refer to the Hello World page.

However, we like to encourage you to provide a separate JavaScript file as a client side plug-in to keep the module and API clean and make it easier to distribute your package later in two files (a server side and a client side plug-in).

The following listing shows how you can create a client jWebSocket plug-in. It provides the method requestServerTime to the JavaScript jWebSocketTokenClient - and thus to the descending jWebSocketJSONClient class as well by inheritance.

 

jws.SamplesPlugIn = {

  // namespace for shared objects plugin
  // if namespace is changed update server plug-in accordingly!
  NS: jws.NS_BASE + ".plugins.samples",

  processToken: function( aToken ) {
    // check if namespace matches
    if( aToken.ns == jws.SamplesPlugIn.NS ) {
      // here you can handle incomimng tokens from the server
      // directy in the plug-in if desired.
      if( aToken.reqType == "requestServerTime" ) {
        // this is just for demo purposes
        // don't use blocking call here!
        alert( "jWebSocket Server returned: " + aToken.time );
      }
    }
  },

  requestServerTime: function( aOptions ) {
    var lRes = this.createDefaultResult();
    if( this.isConnected() ) {
      var lToken = {
        ns: jws.SamplesPlugIn.NS,
        type: "requestServerTime"
      };
      this.sendToken( lToken,  aOptions );
    } else {
      lRes.code = -1;
      lRes.localeKey = "jws.jsc.res.notConnected";
      lRes.msg = "Not connected.";
    }
    return lRes;
  }

}

// add the jWebSocket Samples PlugIn into the TokenClient class
jws.oop.addPlugIn( jws.jWebSocketTokenClient, jws.SamplesPlugIn );

Creating a corresponding jWebSocket Client Plug-in

Use the Plug-ins in your Web Pages

The final action to make the plug-in capabilities available to your application is to add a link to your new client plug-in into your web page(s) as shown below.

 



Embedding the jWebSocket Client Plug-in into your web page

Adding version, vendor and license information to your plug-in

You can distribute your jWebSocket plug-ins under your personal license. All plug-ins in jWebSocket have their own set of information which is displayed in the logs or in the console during the server startup.

public class MyPlugIn extends TokenPlugIn {

	public static final String NS_MYPLUGIN = JWebSocketServerConstants.NS_BASE + ".plugins.myplugin";
	:
	private final static String VERSION = "1.0.0";
	private final static String VENDOR = "Your company or personal name";
	private final static String LABEL = "Your plug-in name";
	private final static String COPYRIGHT = "(C) Copyright  your company or personal name"; 	private final static String LICENSE = "Your selected license"; 	private final static String DESCRIPTION = "The detailed description of your plug-in."; 	: 

Now you overwrite the following methods from the BasePlugIn class:

	@Override
	public String getVersion() {
		return VERSION;
	}

	@Override
	public String getLabel() {
		return LABEL;
	}

	@Override
	public String getDescription() {
		return DESCRIPTION;
	}

	@Override
	public String getVendor() {
		return VENDOR;
	}

	@Override
	public String getCopyright() {
		return COPYRIGHT;
	}

	@Override
	public String getLicense() {
		return LICENSE;
	}

In the log file or in the console then you will find the following line during the server start-up:

2013-02-28 12:55:37,259 INFO  - JWebSocketXmlConfigInitializer: Plug-in 'jws.sample' successfully instantiated, Your plug-in name 1.0.0, (C) Copyright [year] your company or personal name, Your selected license

The default for instance of the jWebSocket SystemPlugIn looks like this:

2013-02-28 12:55:36,636 INFO  - JWebSocketXmlConfigInitializer: Plug-in 'jws.system' successfully instantiated, jWebSocket SystemPlugIn 1.0.0, (C) 2010-2013 Innotrade GmbH (jWebSocket.org), Germany (NRW), Herzogenrath, Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
Publications

Learn more about WebSockets in general, get background information and gain deeper insight!

Join jWebSocket

Wether developer, designer or translator – join the jWebSocket team and grow together with our success!

Copyright © 2013 Innotrade GmbH. All rights reserved.