Contents

  1. Introduction
  2. Websockets concepts
  3. demo.js

Introduction

In previous parts, you have seen how to interact with evQueue from client side using a PHP proxy. Since version 3.0, evQueue provides an integrated Websockets server that allows client side Javascript to directly connect to core engine. The main advantage of this approach is that it is event driven and requires no active polling.

This approach however has a main drawback : credentials have to be put in client side files. Furthermore, clients have access to evQueue engine using Websocketsn which might be a major security breach.

You can moderate this by using a special user with very restricted privileges. However, we recommand using this only in secured environment (like backoffice).

A full demonstration project is available on our github sample projet repository.

Also have a look at the Websockets Javascript class.

Websockets concepts

You might already by familiar with websockets, but just in case here is a short brief : this is a bidirectional, event-driven connection between client-side javascript and a Websockets server.

Once established, the connection can stay up as long as the tab is opened in the browser. The main advantage is that the server can "push" events to the client at anytime. As evQueue is already event-drivent, this is a really nice solution for data exchange between a client application and the core engine.

Once connected, the client can ask the server to receive the result of an API command when a specific event occurs. This is called subscription. You can find here a list of all available events.

Let's imagine you want to display a list of the last 30 terminated instances. In pure AJAX, you would make requests to the server at a specific interval and get the list. If nothing happens, you will make a lot of requests for nothing. Furthermore, this list is not refreshed when an instance is terminated, but at fixed intervals.

Using evQueue subscription, you will subscribe the INSTANCE_TERMINATED event, and get the list of terminated instances each time an instance is terminated. So if nothing happens your code does nothing, but as soon as an instance is terminated, the list gets updated.

demo.js

Here is a step by step guide on how this demo works.

As said in the introduction, credentials have to be stored client-side. In fact we only need a hash of the password to be put in local storage. You can see here the basic configuration, including credentials :

	// Configuration data
	let node = 'ws://localhost:5001';
	let user = 'admin';
	let password = CryptoJS.SHA1('admin').toString(CryptoJS.enc.Hex);
	
	// Store crendentials in local storage
	window.localStorage.setItem('user',user);
	window.localStorage.setItem('password',password);
		

Next we need to instanciate a connection to evQueue API to launch workflows. This connection will also be made through Websockets :

	// Instanciate API connection
	let evqueue_api = new evQueueCluster([node]);
		

This is pretty similar as the project using PHP proxy. Now is the essential difference. We instanciate a new evQueueCluster class in events mode by using a callback function :

	// Instanciate events connection and set events handler
	let evqueue_events = new evQueueCluster([node], (data) => {
		// Reset initial state
		document.getElementById('status').style.backgroundColor = '#ffffff';
		document.getElementById('status').innerHTML = '';
		document.getElementById('launch').removeAttribute('disabled', false);
		
		// Unsubscribe events
		evqueue_events.UnsubscribeAll();
	});
		

This callback function will be called one per event. In our case we will only monitor on type of event so the code is pretty simple, we just put user interface in original state. In more complexe cases, we would have different code, depending on event data.

On click event, we launch a new instance of a test workflow named 'sleep'. This can be any worklow. We have tested with a simple "sleep 10" command to see what is happening.

We are using the API to launch a new instance and get its ID. Then we ask the engine to notify us when the instance is terminated (the API command is not very important as we do not use the result). Once the workflow instance is terminated, the previous callback will be called.

	// Launch new instance
	evqueue_api.API({
		group: 'instance',
		action: 'launch',
		attributes: {name: 'sleep'}
	}).then( (data) => {
		let instance_id = data.documentElement.getAttribute('workflow-instance-id');
		evqueue_events.Subscribe('INSTANCE_TERMINATED', {group: 'instances', action: 'list'}, false, instance_id);
		document.getElementById('status').innerHTML = instance_id;
	});