{{announcement.body}}
{{announcement.title}}

Publish Web Socket in the Experience Layer

DZone 's Guide to

Publish Web Socket in the Experience Layer

The main focus of the article is to show you how to publish a web socket for your consumers, in it I will describe what web socket gives us.

· Integration Zone ·
Free Resource

Some time ago, MuleSoft introduced Web Socket Connector. In this article, I briefly describe what web socket gives us in the context of integration. The main focus of the article is to show you how to publish a web socket for your consumers. 

Web Socket

So the first question is what a web socket is. Web socket is a communication protocol over TCP that enables bidirectional communication between client and server.

web socket and HTTP

WebSocket vs HTTP communication

As you can see in the diagram above, the client initiate connection over WebSocket or secure WebSocket (wss), and then the server can send back messages to the client. Unline with HTTP protocol we do not need to do any pulling. Once the connection is established, the server can send as many requests as it likes.

The greatest benefit of using Web Socket instead of HTTP is performance boost as we do not need to establish a new connection. What is more, we do not need to introduce any sort of pulling mechanism.

WebSocket Connector

Exchange Rates Case

We want to consume forex exchange rates and display them on our banking portal. As they are changing rapidly, we would like to keep values up to date. I have decided to expose WebSocket endpoint to stream changes to the client.

exchange rates

MuleSoft case with published WebSocket endpoint

MuleSoft best practice is API-led connectivity. As a result, in our case, we have three layers. We have Banking Portal Experience API (XAPI), Banking Process API (PAPI) and Banking Forex System API (SAPI). In order to make the data flow smoothly, we will use Amazon SQS queues to exchanged data between layers – as in the diagram above.

Our system API reads exchange rates and publishes them to exchange-rates-sapi queue. Banking Process API reads values from this queue and saves them to exchange-rates-papi queue. This queue will be read by the application in the Experience layer. The Banking Portal XAPI broadcast exchange rates to open web sockets.

When the client initiates a web socket connection, it must decide the primary currency. In other words, if exchange rates should be calculated against USD, EUR, PLN currencies.

WebSockets Configuration

WebSocket configuration requires HTTP Listener config. In the picture below, you can see that we have to assign existing HTTP_Listener_config to WebSocket configuration by Listener config property.

http_listener

WebSocket global configuration

You can specify how long the connection should be kept while idle. In my scenario, I have decided to kill the connection after 60 minutes.

WebSocket Connector Operations

In order to expose WebSocket connection we have two listeners.

On New Inbound Connection is triggered when the client initiates the connection. Below you can see sample JavaScrip line that performs this action. In this case, you don’t have any payload, but you receive the headers/metadata.

Java
 




xxxxxxxxxx
1


1
var ws = new WebSocket("ws://localhost:8081/ws/exchange-rates");



On New Inbound Message is triggered when the client sends the message on already establish WebSocket connection. The client can send a body that Mule saves within the payload – like JSON. In this part, we often subscribe to some events like chat entries entered by all the users or exchange rate changes. We can also send a message back to the client if we like.

In the JavsScript code snippet below, you can find sending the message to WebSocket.

Java
 




xxxxxxxxxx
1


1
var request = {
2
  base: "PLN"
3
};
4
ws.send(JSON.stringify(request)); 



In both cases, you need to provide the path on which the application listens. My demo application has the path to web socket as follows ws://localhost:8081/ws/exchange-rates.

WebSocket Sending Messages

MuleSoft gave us two convenient operations. That is Send and Broadcast.

Send is used to send one message to a concrete client. We need to specify the socket identifier. We receive this id in Mule attributes – attributes.socketId during connection initiation. When we want to send the same message to more consumers, we can use broadcast.

In the Broadcast operation, we should specify the body, path for which we want to look for active WebSocket connections and socket type. The last attribute should be set to INBOUND. This value indicates that the only connection to our published socket is considered. Last but not least, we could specify groups. The developer specifies the group.

So let’s see them in action.

Send Operation

successful subscription

Send operation configuration in Anypoint Studio

In the above screenshot, you can see that I am sending a message to a recipient identified by the Socket Id. I also specify the JSON body that can assure the client that the connection has been successfully established.

The Socket Id is available in the attributes in flows with the WebSocket listeners. If you would like to access them in other parts of your application you should save them for example in the ObjectStore.

Subscription and Broadcasting

We can broadcast the message to all active clients. However, we may be interested in restricting specific groups. In order to achieve this, we need to use subscribe-groups operation.

XML
 




xxxxxxxxxx
1


 
1
<websocket:subscribe-groups
2
  doc:name="Rates groups"
3
  config-ref="WebSockets_Config"
4
  socketId="#[attributes.socketId]">
5
    <websocket:groups >
6
      <websocket:group value='#[payload.base ++ "_rates"]' />
7
    </websocket:groups>
8
</websocket:subscribe-groups>



As you can see, we need to provide socket id, to identify the client and one or more groups. In my case, I have decided to name the group dynamically. As a result, I will have three groups like USD_rates, PLN_rates, and EUR_rates.

Now when someone subscribes just for USD_rates, he/she won’t receive updated in PLN and EUR.

Broadcasting a message is a trivial task. We use a broadcast operation. Selected you can see the most important part. That is the path and groups.

XML
 




xxxxxxxxxx
1


 
1
<websocket:broadcast
2
  doc:name="Broadcast"
3
  config-ref="WebSockets_Config"
4
  path="/ws/exchange-rates" socketType="INBOUND">
5
    <websocket:groups >
6
      <websocket:group value='#[vars.base ++ "_rates"]' /> 
7
    </websocket:groups>
8
</websocket:broadcast>



Source Code

Source code is available at GitHub. The code has been prepared using Mule 4.2.2 EE runtime and WebSocket in version 1.0.0.

Summary

I like the idea of web sockets as they introduce the bidirectional traffic without any additional overhead like using HTTP(S). MuleSoft connector is ready and easy to use. Maybe you had a case when that could be useful to use, but was not yet available at Mulesoft. In my case, I can imagine a couple of usage scenarios.

Cheers.

Topics:
api, http, integration, mulesoft, tutorial, websocket

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}