Skip to main content
Woohoo! Qlik Community has won “Best in Class Community” in the 2024 Khoros Kudos awards!
Announcements
Join us at Qlik Connect for 3 magical days of learning, networking,and inspiration! REGISTER TODAY and save!
cancel
Showing results for 
Search instead for 
Did you mean: 
rbartley
Specialist II
Specialist II

Using Enigma to connect to QIX from remote machine

Hello everyone,

Up until now, I have developed mashups and extensions directly on a Qlik Sense Enterprise server using the dev-hub. However, I would like to use Visual Studio from my own PC where I have no Qlik Sense elements installed.  So far, I have installed Node.js and Enigma.js on my PC and have followed the example here https://github.com/qlik-oss/enigma.js/ 

 

 

const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');

// create a new session:
const session = enigma.create({
  schema,
  url: 'ws://localhost:9076/app/engineData',
  createSocket: url => new WebSocket(url),
});

// bind traffic events to log what is sent and received on the socket:
session.on('traffic:sent', data => console.log('sent:', data));
session.on('traffic:received', data => console.log('received:', data));

// open the socket and eventually receive the QIX global API, and then close
// the session:
session.open()
  .then((/*global*/) => console.log('We are connected!'))
  .then(() => session.close())
  .then(() => console.log('Session closed'))
  .catch(err => console.log('Something went wrong :(', err));

 

 

I replaced the localhost in the code above with the hostname of the Qlik Sense Enterprise server , but when I run the code I receive a timeout error:

 

Something went wrong 😞 ErrorEvent {
  [Symbol(kTarget)]: WebSocket {
    _events: [Object: null prototype] {
      open: [Function],
      close: [Function],
      error: [Function],
      message: [Function]
    },
    _eventsCount: 4,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 3,
    _receiver: null,
    _sender: null,
    _socket: null,
    _bufferedAmount: 0,
    _isServer: false,
    _redirects: 0,
    _url: 'ws://xxx.xxx.aws.cloud.tech.ec.europa.eu:9076/app/engineData',
    _req: null,
    [Symbol(kCapture)]: false
  },
  [Symbol(kType)]: 'error', 
[Symbol(kError)]: Error: connect ETIMEDOUT XX.XXX.XXX.XX:9076
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1300:16) {
    errno: -4039,
    code: 'ETIMEDOUT',
    syscall: 'connect',
    address: 'XX.XXX.XXX.XX',
    port: 9076
  },
  [Symbol(kMessage)]: 'connect ETIMEDOUT XX.XXX.XXX.XX:9076'

 

 

Is this an authentication issue or is it just not possible to do what I am attempting? 

 

 

 

 

 

 

Labels (1)
  • API

2 Solutions

Accepted Solutions
alex_colombo
Employee
Employee

Hey @rbartley, that error happens because you are trying to run server side code on a client side. If you want to use enimga.js from a client I'd suggest to change apporach. First you have to change your authentication method. You could use ticket or JWT authentication. For both of them you need a server side component which will generate ticket or sign the JWT token. Then you can attach ticket or JWT token to websocket connection created by enigma.js on client side.

View solution in original post

alex_colombo
Employee
Employee

@rbartley there is no specific documentation this, and the reason is that it's a topic on pure dvelopments, indipendet from QlikSense. If you want to run mashup code outside dev-hub you need a local web server to run your code. An example could be to use a JS framework such as VueJs or React where you can their cli for running a project and a local webserver.

View solution in original post

5 Replies
rbartley
Specialist II
Specialist II
Author

It seems as though authentication is required.  I installed the pem certificates in my user folder and created a file based on the code here: https://github.com/qlik-oss/enigma.js/tree/master/examples/authentication/sense-using-certificates 

This communicates on port 4747 rather than 9076, so as soon as 4747 had been opened, I was able to connect, create a session and retrieve the list of apps available to my user.

 

rbartley
Specialist II
Specialist II
Author

I have tried to do the same through a browser using the code below:

<script src="https://unpkg.com/enigma.js/enigma.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.min.js"></script>
<script>
const path = require('path');
const fs = require('fs');


	// The Sense Enterprise-configured user directory for the user you want to identify
// as:
const userDirectory = 'xxxx';

// The user to use when creating the session:
const userId = 'xxxx';
const readCert = (filename) => fs.readFileSync(path.resolve(__dirname, certificatesPath, filename));

 fetch('https://unpkg.com/enigma.js/schemas/12.34.11.json')
    .then(response => response.json())
    .then(schema => {
      const session = enigma.create({
        schema,
        // Change the url to point to your QIX instance
        url: 'wss://xxxxx.s4dad.aws.cloud.tech.ec.europa.eu:4747/app/engineData',
        createSocket: url => new WebSocket(url,{
			ca: [readCert('root.pem')],
			key: readCert('client_key.pem'),
			cert: readCert('client.pem'),
			headers: {
			  'X-Qlik-User': `UserDirectory=${encodeURIComponent(userDirectory)}; UserId=${encodeURIComponent(userId)}`,
			},
		  })
      })

      session.open()
        .then(global => global.engineVersion())
        .then(result => document.body.innerHTML = result.qComponentVersion)
        .then(() => session.close())
    });

</script>

 

but haven't been able to figure out yet how to pass the certificate parameter.  The code above generates an error:

Uncaught Error: Module name "path" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded
    at makeError (require.min.js:1:1067)
    at Object.o [as require] (require.min.js:1:11053)
    at requirejs (require.min.js:1:14737)
    at index.html:4:14

 

 

alex_colombo
Employee
Employee

Hey @rbartley, that error happens because you are trying to run server side code on a client side. If you want to use enimga.js from a client I'd suggest to change apporach. First you have to change your authentication method. You could use ticket or JWT authentication. For both of them you need a server side component which will generate ticket or sign the JWT token. Then you can attach ticket or JWT token to websocket connection created by enigma.js on client side.

rbartley
Specialist II
Specialist II
Author

Hi @alex_colombo ,

Thanks for your reply.  I am looking at ways of developing lighter-weight  mashups (using enigma and nebula rather than Capability API) on a local PC rather than directly through the dev-hub on one of our Qlik Sense Enterprise servers.  All of the examples I have seen seem to be based on the assumption that the development is being carried out on the server or where Qlik Sense Desktop is installed.  I would like to code in Visual Studio rather than the dev-hub.

Could you point me towards any documentation that provides an end-to-end example of how to achieve this?

 

alex_colombo
Employee
Employee

@rbartley there is no specific documentation this, and the reason is that it's a topic on pure dvelopments, indipendet from QlikSense. If you want to run mashup code outside dev-hub you need a local web server to run your code. An example could be to use a JS framework such as VueJs or React where you can their cli for running a project and a local webserver.