Article
Robert Cemper · May 14, 2020 4m read

WebSocket Client JS with IRIS Native API as Docker Micro Server

 

This is a coding example working on IRIS 2020.2 
It will not be kept in synch with new versions 
It is also NOT serviced by InterSystems Support !

My demo video is now also available to watch the demo in operation.
https://youtu.be/dSV-0RJ5Olg

 

Hi folks,
It's time now for a Micro Service Demo with a total fresh IRIS Image and an image that you both PULL with
docker  and run with only 4 lines of docker commands. 
June 1st, 2020 - rcc

There is now a compact All-in-1 version available that combines all parts in a single container image.
For details see: IRIS-NativeAPI-Nodejs-compact
May 24, 2020 - rcc

I have added a simplified installation using Docker, see context
May 25, 2020 - rcc

There are enhanced scripts suitable & tested for Linux & Windows available here
https://github.com/rcemper/WSockClientMicroSV/blob/master/READMEwindows.MD
May 26, 2020 - rcc

This demo is a redesign of the WebSocket Client based on Node.js existing already for Caché. The major changes:

  • use of the new IRIS Native API for Node.js  especially Working with Global Arrays
  • change from a directly triggered client to a server design
  • put the result into a separate docker image as an example for a MicroService / MicroServer
  • add a simple interface in IRIS to control the MicroService execution.

Instead of a utility,  you call directly on you IRIS host you now send a work-packages 
to the MicroService as would typically do with System Interoperability (aka.ENSEMBLE):
Of course, you have the option of more than one WebSocket Server.
Once the WebSocket Client Service has done its job you get back the result from it.

The advantage over the built-in WebSocket Client is, that all Network, Security,
Firewall issues are kept away from the core data server. Not to talk about the
experience and quality Node.js has in this arena.

The demo uses wss://echo.websocket.org/ as default EchoServer
Next, you enter some lines of text.
At any point, you can add "Lorem Ipsum" text for more content between your own text.
Next, you sent it to the service and wait for the echo.
There is also the option to change your text before sending
as Exit the control program or Stop the service.

All this processing runs asynchronously.
Instead of waiting for completion, the Listener displays periodically
what was received from the echo server so far.

To install it you need a

  • docker image for IRIS ( intersystems/iris-community:2020.2.0.199.0 )
  • docker image for the WebSocket MicroServer (docker pull rcemper/rcc:demoJS)
  • simplified init: just run this docker command for init
      docker run --name ini1 --init -it --rm \
        -privileged -v $(pwd):/external \
        rcemper/rcc:demoJS bash /rcc/init.sh   
    ### The original approach is still valid but not required. ###
  • WSockClientMicroSV.tar.gz from Open Exchange or here to make use of IRIS-Docker-micro-Durability
  • check directory demo:  set  protection to rwx (chmod 777) as Docker Image is a nobody at your level. ###

To run it start IRIS first (either -d or -it to observe the behavior) from directory demo (!)

docker run --name iris1 --init --rm -d \
-p 52773:52773 -p 51773:51773 \
-v $(pwd):/external \
intersystems/iris-community:2020.2.0.199.0 \
-b /external/pre.copy

Next, the MicroServer

docker run --name rcc1 --init -it --rm \
rcemper/rcc:demoJS /usr/bin/node /rcc/nodejs/WSockIris.js $(hostname -I)

. As you started it with -it you see

platform = linux: ubuntu  

    *****************************  
    Connect to IRIS on: 192.168.0.23  
Successfully connected to InterSystems IRIS.  
    *** wait 3sec for request ***  
    ******* Startup done ********  

    *** wait 3sec for request ***  
    *** wait 3sec for request ***  

then the control application in a new Linux terminal

docker exec -it iris1 iris session iris ZSocket  

and you see

*** Welcome to WebSocket Micoservice demo ***  
Known Hosts (*=Exit) [1]:  
1  wss://echo.websocket.org/  
2  --- server 2 ----  
3  --- server 3 ----  
select (1):  ==> wss://echo.websocket.org/  
#
Enter text to get echoed from WebSocketClient Service
Terminate with * at first position
or get generated text by %
or append new text with @

1    hello socket microServer
2    now you got 2 lines
3    *

Select action for WebClient Service
New EchoServer (E), Send+Listen(S),New Text(N),Exit(X), Exit+Stop Client(Z) [S]s
%%%%%%%%%%%%%%%%%%%%%%%%%%

******* 0 Replies *******

******* 2 Replies *******
1    hello socket microServer
2    now you got 2 lines


Select action for WebClient Service

and on MicroService

*** wait 3sec for request ***
echoserver:  wss://echo.websocket.org/
** Lines to process: 1 **
********* next turn *********
* WebSocket Client connected *
****** Client is ready ****** 

Line: 1 text> 'hello socket microServer '
Received: 1 > 'hello socket microServer '

Line: 2 text> 'now you got 2 lines '
Received: 2 > 'now you got 2 lines '

******* lines sent: 2 ******
*** replies received: 2 ****

*** wait 3sec for request ***

Late warning. always check the version of your image!
I just fell into  intersystems/iris-community:2020.2.0.
204.0

NOTICE: ALL SCRIPTS ARE TESTED FOR LINUX ONLY !

110
1 12 373 1

Replies

Is it possible to use your IRIS based WebSocket Server ?
If yes, wow?

InterSystems IRIS provides both server and client WebSocket implementations out of the box.

@Eduard Lebedyuk 
You are perfectly right and I wrote some articles about it. The EchoServer is an implementation with  the IRIS server
My main focus is Micro Service with Docker and  IRIS Native API for Node-js.

(WebSockets was something I just had at hands)

Yes, it runs also with my previous published EchoServer for IRIS.
You just have to add some entries to the server list in  ^ZSocket:

set server(2)="ws://localhost:52773/csp/sys/ZS.csp.cls"
set server(3)="ws://192.168.0.23:52773/csp/sys/ZS.csp.cls"

localhost  gets translated by the app to the  server that the Node aplications is connectesd to.

Attention though: the link is constructed   as:     ws: //<server-ip>:<csp-port>/csp/<namespace>/sevice class
BUT: for namespace %SYS this piece is just sys without leading %   wink  as you see in the code snippet.

You say "All this processing runs asynchronously."   but from what I can tell from the Native Node.js API, they are all synchronous.  

Hi @Rob Tweed 
You are perfectly right. The  IRIS Native API for Node.js is as synchronous as synchronous can be. And as is was for Caché before.

My remark referred to the logic of the control program:

  • It fills a global with server + data to send
  • this information is scanned periodically by the MicroService  (no synchronous trigger)
  • then the MicroService does its job and feeds the result to a different output-global
  • meanwhile,  the control program in IRIS displays periodically what has arrived so far also to show that it is still moving. (as you check your postbox every hour if you wait for your paycheck) smiley

I tried to express that  this is not ping-pong like the echo on a terminal
but ping-ping-ping-ping-ping-   and  pong - - - - pong - pong - - - pong - - - - pong -  pong -  - - -  

added simplified installation today

There are enhanced scripts suitable & tested for Linux & Windows available here
https://github.com/rcemper/WSockClientMicroSV/blob/master/READMEwindows.MD
May 26, 2020 - rcc

This addendum is mainly required to run the demo on
Docker Desktop for Windows.

  • I failed to use continuation lines.
  • In Linux you can get the host's IP-Address by $(hostname -I) I found no suitable equivalent in Windows.  Just runing  ipconfig  and typing in what you see.
  • Assuming this IRIS is the first container to run we can use it in Linux and in Windows 172.17.0.2 as host address.

To get the images:

  • docker pull rcemper/rcc:demoJS       for the NodeJS Service container
  • docker pull store/intersystems/iris-community:2020.2.0.204.0    for our fresh IRIS container

For initialization (only required once)

  • docker run --name ini1 --init -it --rm --privileged -v vol1:/external rcemper/rcc:demoJS bash /rcc/init.sh  a docker volume "vol1" is created and loaded

Start IRIS server first !

  • _docker run --name iris1 --init --rm -d -p 52773:52773 -p 51773:51773 -v vol1:/external store/intersystems/iris-community:2020.2.0.204.0 -b /external/pre.copy

Start NodeJS service container

  • docker run --name rcc1 --init -it --rm rcemper/rcc:demoJS /usr/bin/node /rcc/nodejs/WSockIris.js 172.17.0.2 in Linux thsi works insimilar way docker run --name rcc1 --init -it --rm rcemper/rcc:demoJS /usr/bin/node /rcc/nodejs/WSockIris.js $(hostname -I)

Start control program for IRIS in a new command / terminal  session

  • docker exec -it iris1 iris session iris ZSocket

Enjoy the data going forward and return