EZ Websocket

Content Type: Module
Categories: Utility,User Interface

Overview

Allow for real-time server to client communication using websockets without external dependencies or runtime configuration.

Includes listener widgets for both web and native.

Documentation

https://youtu.be/izg8a6bgMoc
<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">EZWebSocket</h1><a id="user-content-ezwebsocket" class="anchor" aria-label="Permalink: EZWebSocket" href="#ezwebsocket"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Allow for real-time server to client communication using websockets without external dependencies or runtime configuration</p> <div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Features</h2><a id="user-content-features" class="anchor" aria-label="Permalink: Features" href="#features"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li> <p dir="auto">✅ Easily set up 1 or more websocket servers</p> </li> <li> <p dir="auto">✅ Configure 1 or more client-side actions</p> </li> <li> <p dir="auto">✅ Configure either limited or unlimited sessiontimeout</p> </li> <li> <p dir="auto">✅ Configure action to perform on sessiontimeout</p> </li> <li> <p dir="auto">✅ Configure action to perform on user navigating away</p> </li> <li> <p dir="auto">✅ <strong>v1.1.0 update</strong> Configure server-side microflow to be fired on websocket close</p> </li> <li> <p dir="auto">✅ <strong>v1.3.0 update</strong> Added listener widget for native</p> </li> <li> <p dir="auto">✅ <strong>v1.4.0 update</strong> Added message feature</p> </li> <li> <p dir="auto">✅ <strong>v1.4.2 update</strong> Added multi-instance support as a separate addon module <a href="https://marketplace.mendix.com/link/component/227663" rel="nofollow">link</a></p> </li> <li> <p dir="auto">✅ <strong>v2.0.0 ping/pong update</strong></p> <ul dir="auto"> <li>Added keepalive using websockets native ping/pong mechanism</li> <li>Removed sessionTimeout parameter from easy websocket initialization for even easier websocket initialization</li> <li>Added advanced websocket initialization for tweaking session timing parameters</li> </ul> </li> <li> <p dir="auto">✅ <strong>v3.0.0 scalability improvements</strong></p> <ul dir="auto"> <li>Solved concurrency/scaling issues</li> <li>Reworked session validation</li> <li>Upgraded app base to Mx 10.24.0</li> </ul> </li> </ul> <div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Usage</h2><a id="user-content-usage" class="anchor" aria-label="Permalink: Usage" href="#usage"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Initialize webserver</h3><a id="user-content-initialize-webserver" class="anchor" aria-label="Permalink: Initialize webserver" href="#initialize-webserver"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ol dir="auto"> <li> <p dir="auto">Add one of the <code>JA_AddWebsocketEndpoint_XXX</code>-actions to your afterstartup flow</p> <blockquote> <p dir="auto">See the documentation tab of the Java actions' properties to check which one fits your usecase</p> </blockquote> </li> <li> <p dir="auto">Create a websocketidentifier, this will also be the path to the websocketserver</p> <blockquote> <p dir="auto">I recommend storing this inside a constant with client exposure for reuse in notify action and the websocket client widget</p> </blockquote> </li> </ol> <p dir="auto">If you initialize the websocket with one of the <code>JA_AddWebsocketEndpoint_XX_CallMicroflowOnDisconnect</code> actions you will need to configure the following as well:</p> <ol start="4" dir="auto"> <li> <p dir="auto">Select the <code>onCloseMicroflow</code>, the microflow can contain one string parameter</p> </li> <li> <p dir="auto">Fill in the name of the string parameter inside <code>onCloseMicroflowParameterKey</code></p> </li> </ol> <div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Setup client connection</h3><a id="user-content-setup-client-connection" class="anchor" aria-label="Permalink: Setup client connection" href="#setup-client-connection"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">General tab</h4><a id="user-content-general-tab" class="anchor" aria-label="Permalink: General tab" href="#general-tab"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ol dir="auto"> <li> <p dir="auto">Place the EZ Websocket client widget inside a context entity</p> </li> <li> <p dir="auto">Configure the object Id</p> </li> </ol> <blockquote> <p dir="auto">Note that the object database id is not available here, you will have to provide your own unique object id</p> </blockquote> <ol start="3" dir="auto"> <li> <p dir="auto">Fill the websocket identifier with the same identifier from the websocket initialization</p> </li> <li> <p dir="auto">Configure one or more trigger/action combination(s)</p> </li> </ol> <div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Message handling tab</h4><a id="user-content-message-handling-tab" class="anchor" aria-label="Permalink: Message handling tab" href="#message-handling-tab"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto"><strong>Message attribute</strong>: Configure attribute to receive messages sent directly from the notify action on</p> <div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Websocket close behaviour tab</h4><a id="user-content-websocket-close-behaviour-tab" class="anchor" aria-label="Permalink: Websocket close behaviour tab" href="#websocket-close-behaviour-tab"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto"><strong>Timeout action</strong>: If you configured a sessiontimeout during the initialization you can configure the action to perform on sessiontimeout here</p> <blockquote> <p dir="auto">Note that you might need to use the advanced websocket initialization to turn off the keepalive mechanisim</p> </blockquote> <p dir="auto"><strong>Navigate action</strong>: Executes action when the websocket component unrenders, examples of this are:</p> <ul dir="auto"> <li> <p dir="auto">User navigates away from the page</p> </li> <li> <p dir="auto">User closes the page</p> </li> <li> <p dir="auto">The component becomes invisible</p> </li> </ul> <blockquote> <p dir="auto">This does not get fired if the user closes the tab or the browser, use the onCloseMicroflow functionality instead</p> </blockquote> <p dir="auto"><strong>On close MF parameter</strong>: Only use this if the websocket is initialized using one of the <code>JA_AddWebsocketEndpoint_XX_CallMicroflowOnDisconnect</code> actions</p> <ul dir="auto"> <li>This is the string parameter that will be passed to the on close microflow</li> </ul> <div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Notify all subscribers</h3><a id="user-content-notify-all-subscribers" class="anchor" aria-label="Permalink: Notify all subscribers" href="#notify-all-subscribers"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ol dir="auto"> <li> <p dir="auto">Add <code>JA_Notify</code> action to your microflow</p> </li> <li> <p dir="auto">Configure the object Id of which you want to notify the subscribers of</p> </li> <li> <p dir="auto">Fill the websocket identifier with the same identifier from the websocket initialization</p> </li> <li> <p dir="auto">Configure the action trigger configured in the client widget</p> </li> </ol> <p dir="auto"><strong>and/or</strong></p> <ol start="5" dir="auto"> <li>Add a message you want to send to the clients</li> </ol> <blockquote> <p dir="auto">Note that the message attribute gets set before the action is executed so that the message is directly available inside the action</p> </blockquote> <div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Issues, suggestions and feature requests</h2><a id="user-content-issues-suggestions-and-feature-requests" class="anchor" aria-label="Permalink: Issues, suggestions and feature requests" href="#issues-suggestions-and-feature-requests"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto"><a href="https://github.com/nathan-JJRplus/EZWebsocket/issues">Issues</a></p> </article></div>

Releases

Version: 3.0.0
Framework Version: 10.24.0
Release Notes:

Implemented suggestions mentioned in [issue 13](https://github.com/nathan-JJRplus/EZWebsocket/issues/13)

- Solved scalability/concurrency issues when deploying at scale

- Reworked session validation to use mendix' mxSessionId instead of CSRFtoken

- Added more error codes to timeout triggers

- Upgraded base app to Mx 10.24.0

- Updated widget dependencies

Version: 2.1.0
Framework Version: 9.24.34
Release Notes:

Fixed [issue #11](https://github.com/nathan-JJRplus/EZWebsocket/issues/11) where native clients would not automatically reconnect when returning from background after a WebSocket disconnect.

Version: 2.0.1
Framework Version: 9.24.25
Release Notes: Due to popular demand, backported the project to mendix 9.24 LTS
Version: 2.0.0
Framework Version: 10.6.10
Release Notes: - Added keepalive using websockets native ping/pong mechanism
- Removed sessionTimeout parameter from easy websocket initialization for even easier websocket initialization
- Added advanced websocket initialization for tweaking session timing parameters
- ❗This update will break your current ASU initialization
Version: 1.4.2
Framework Version: 10.6.10
Release Notes: - Fixed issue where action could not be performed when parameter came from datasource micro/nanoflow
- Fixed testproject path so that the fixes from 1.4.1 are actually in this release as well
- Updated testproject to 10.6.10 MTS
- Added simple multi-instance solution to be released as an addon
Version: 1.4.1
Framework Version: 9.24.15
Release Notes: Fixed issue where too many user sessions would result in performance issues
Fixed issue where using a messageattribute from a datasource flow would result in incorrect results
Updated testproject to Mendix LTS version 9.24.15
Version: 1.4.0
Framework Version: 9.18.1
Release Notes: New feature
- Added the option to send a message to the clients through the notify action
- Client widgets now have the option to configure an attribute to receive messages on
- Notify action can now send a message, an action or both

Fixes
- Fixed bug where navigate action would not fire in case of a websocketendpoint without microflow
- Removed some leftover debugging logs
Version: 1.3.0
Framework Version: 9.18.1
Release Notes: - Added websocket listener widget for native
- Renamed web widget package, make sure to remove jjr+.EZWebsocket.mpk from your widgets folder and use jjrplus.EZWebsocket.mpk instead
Version: 1.2.1
Framework Version: 9.18.1
Release Notes: Fixed mistake with the activesessions iterator
Version: 1.1.0
Framework Version: 9.18.1
Release Notes: OnClose microflow update:
- Added option to fire a microflow on websocket close, serverside
- Reordered some parameters for consistency