Everyday is an API Day
MuleSoft is loaded with features. Mule runtime engine (Mule) is a lightweight integration engine that runs Mule applications and supports domains and policies. MuleSoft is well known for getting APIs and integrations done in short time.
I would like to demonstrate how I got a real time chat application working with MuleSoft.
Some components used:
- HTTP
- Web Socket
- Database
- DataWeave
I have also created an android application that talks to MuleSoft WebSocket Server. Thus the end to end app allows users to join a room over android app or web. 😀🙌
WebSocket : two-way interactive communication
WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection, i.e both server and client can send messages across the network.
The WebSocket API is an advanced technology that makes it possible to open a two-way interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply.
The solution is divided into two parts:
- The System API to store data of users and handle room details
- The Experience layer in form of a WebSocket Server
High Level Architecture
System API Implementation
The main aim of the system api is to give a CRUD based API interface to users and chat rooms.
I am using SQLite DB for this and we are good to use any persistence mechanism for this.
- The API specification(RAML):
- /users :
- GET : This end point returns all the users registered to some chat room
- POST : This end point is used to add a user to the persistent store
- /users/{userId}:
- GET : This end point returns the user with the URI Param userId
- PUT : This end point is used to updated details of a user. Example: SocketId is generated only when user successfully joins any room.
- DELETE : This end point is used to delete an user
- /room :
- GET : This end point returns all the rooms where users are present
- POST : This end point adds an user to a room
- /room/{roomId} :
- GET : This endpoint is used to get all the users in the roomId
- DELETE : This end point deletes a room
- /users :
We can add more endpoints here to add enhance capabilities. For now we will stick to this minimal viable product.
#%RAML 1.0
title: mule-chat-sapi
description: Set of endpoints to add user and rooms for chat application
types:
User: !include dataType/User.raml
Room: !include dataType/Room.raml
/users:
get:
description: This endpoint is used to get all users
responses:
200:
body:
application/json:
type: User[]
post:
description: This endpoint is used to add an user
body:
application/json:
type: User
responses:
201:
body:
application/json:
example: !include examples/users_post.json
/{userId}:
get:
description: This endpoint is used to get a particular users
responses:
200:
body:
application/json:
type: User
put:
description: This endpoint is used to update details of an already added user recognized by the userId
body:
application/json:
type: User
responses:
200:
body:
application/json:
example: !include examples/users_put.json
delete:
description: This endpoint is used to delete an user
responses:
200:
body:
application/json:
example: !include examples/users_delete.json
/room:
get:
description: Get all room and user ids in the room
responses:
200:
body:
application/json:
type: Room[]
post:
description: This endpoint is used to add an user to a room
body:
application/json:
type: Room
responses:
201:
body:
application/json:
example: !include examples/join_post.json
/{roomId}:
description: This endpoint is used to get all the users in the roomId
get:
responses:
200:
body:
application/json:
type: User[]
delete:
description: This endpoint is used to delete a room
responses:
200:
body:
application/json:
example: !include examples/room_delete.json
- The Database: SQLite is a relational database management system (RDBMS) contained in a C library. This has all the CRUD features. I am using this to show the Mule capability to handle any form of JDBC connection. Also using SQLite removes the dependency of hosting any Database solution. But we can connect the system API to any persistent mechanism like AWS RDS, IBM DB2, MySQL etc. I am using a Generic Database connection:
The Driver class org.sqlite.JDBC comes from below Maven Dependency:
- API Implementation: The API Implementation is a generic APIKit Router based solution and the database operations are coded as per requirement.
Now we are done with our System API layer. It's now time to go into the interesting part of the solution which actually adds the WebSocket based chat feature.
Experience Layer : Mule Chat App
This application also written in Mule and HTML, CSS, JS allows multiple users to join multiple rooms and start interacting with each other.
WebSocket:
The WebSocket specification defines an API establishing "socket" connections between a web browser and a server. In plain words: There is an persistent connection between the client and the server and both parties can start sending data at any time.
Unlike the method where client polls for data every time, Websocket allows server to push data to client as and when available.-
WebSocket Implementation:
- WebSocket(WSS) HTTPS Listener: We create a HTTPS Listener with port 8082. This will be used by the WebSockets to communicate over the channel.
- WebSocket(WSS) Mule Server: We use Mule, only as the Web Socket Server. The connection is WSS which is a secured Web Socket communication comparable to HTTPSThe configuration is below: It's worth noting that I checked only the Server setting to make sure that it acts as WebSocket server.
- WebSocket(WS) HTML/JS Client: The WebSocket client in this case is the web browser where users comes and logs to join multiple rooms and chat with people. Here we used JavaScript to connect to the WebSocket over : wss://:8082/ Note that unlike http the protocol here is wss In the image highlighted above the highlighted boxes signifies below:
- 1 : WebSocket is deployed over a shared Load Balancer, so we provide the internal worker URL with port.
- 2 : We create the WebSocket URL that will be used.
- 3 : We establish a full duplex connection to Mule WebSocket Server.
- 4 : Listens to incoming messages and adds the messages to the HTML DOM using custom javascript function insertChat()
-
WebSocket Mule Flow:
- Initiate Connection: Whenever a user joins a room using Web Client, this flow is triggered and it updates the socketId of the user.
- Route Messages: Mule is well known for routing messages using it's connector, here I route the appropriate messages to users in a room.
- Close Connection: When user closes the browser, this flow is called and it removes user from the table
This pretty much covers the WebSocket implementation.
For connecting to the System APIs to add/remove room and users I have used the connector published to exchange as below:
Below are the images of the working solution:
Enter Room Id or Number and Join Room
Add name and avatar image(This appears in the Chat UI)
Send Chat Messages and enjoy interacting!
- Web UI (Mule Flow)
MuleSoft is well known for hosting APIs and integration but it can also be used to host your UI application and serve it as the frontend.
For the Chat UI, I am using Parse Template.
Here, I fetch the Room Id from query parameters and set it in variable. Then use it to dynamically to generate HTML content using Parse Template.
- Android UI
The native android application allows user to join a room by entering Room Number, name and an optional avatar link. In case user doesn't give a link to avatar the default robot image is considered.
The user can then interact 💬 with other users in same room connected using Web or Android Client 💻
Deployment
The SAPI is deployed at : https://mule-chat-sapi.us-e2.cloudhub.io/console/
The WebSocket deployment actually needs Dedicated Load Balancer to work as sited here : (https://docs.mulesoft.com/websockets-connector/1.0/websockets-connector-cloudhub).
The trial account doesn't support VPC or DLB. So I am using self signed certificate and exposing internal worker URL.
The application can be accessed at : https://mule-worker-mule-chat-app.us-e2.cloudhub.io:8082/
You will see an error like below :
Since the certificates are self signed, it doesn't recognize and throw this error but you can click on Proceed to mule-worker-mule-chat-app.us-e2.cloudhub.io (unsafe) and start inviting your friends for a chat 😉
This can also be run on local Anypoint studio by importing jar from Mule-Chat-App
We can however get the DLB setup and deploy the chat application too.
The android app(apk) is hosted here to download and install : Download
Demo
Updated : Added a new Android interface to interact with WebSocket Mule Server.
References and Code
RAML-Specification
Mule-Chat-SAPI GitHub-Repo
Mule-Chat-App GitHub-Repo
Android-App Download
Future Prospects
Suppose an API takes good amount of time to do some really resource intensive task, we can run an async operation at backend and then whenever data is ready we can send it back from Server to Client using the duplex channel. This is useful since client doesn't have to constantly poll the server for updates. Also, for cases like stock market ticks, this will be useful. Asynchronous messaging in going to be the next revolution in data delivery ✅
Can be integrated with Chatbots and a wide range of APIs to give a more enhanced experience.
About the author
Tirthankar Kundu is a full stack developer who loves to code. He is MuleSoft Certified Developer who loves APIs. Proficient in both frontend and backend technologies. Working with Persistent Systems Ltd. as a Senior Mule developer in Insurance domain.
Top comments (12)
Hi Tirthankar, this seems like quite an interesting project. I tried to setup and get it working on my machine. I have a couple of questions. 1) Do you have the code in GitHub for Experience layer? 2) Link for "Mule-Chat-App" jar throws a 404 error. Please advise.
Hi @srkomma thanks for the review. I am actually tweaking the experience layer and so kept the repo private for sometime. The jar you are trying to access which has exp layer code is part of same repo. I will make it public and notify you. Thanks again for your comment 😊
@srkomma Please check, it's shared now.
Thank you! I will check it out.
Hi Thirthankar, Congratulations on winning one of top 3 prizes. I wanted to give this a try this weekend but other than "Mule-Chat-SAPI" Github link, rest of the 3 links under "References and Code" are broken. Can you please fix them so I can try this project.
Thank you for your submission, Tirthankar!
Welcome :) It was a great experience. I am doing some code cleanup. Once done will share the repository.
Great project @Tirthankar
Thanks a lot Shailesh !
Congratulations for this project Tirthankar, very well done!
Thanks a lot Andres !
Hi @tirthankar I am unable to access any of the github Repo links that you shared here.