WebSocket Connector in Mule 4
In this Tutorial, we will talk about how to use WebSocket connector in Mule 4 to create a full-fledged client server application based on Websocket protocol. We will create a client and server in MuleSoft
Prerequisite
Before going through this tutorial, you should have a basic idea on websocket.
WebSocket is a communication protocol, which provides a full duplex communication over a single TCP connection. As opposed to HTTP protocol where communication happens in one direction only, in websocket protocol, both client and server can exchange messages with each other till the period socket is open.
You can visit the link https://tools.ietf.org/html/rfc6455 for more understanding on Websocket.
The best use case of websocket can be for creating applications which are related to scenarios below
- Chat applications
- Push notifications
- Live feeds e.g. stocks, sports match feed. etc.
Use case
For the Tutorial, we will create an application which will provide the scores of a match being played live using websocket protocol.
We will create two clients who would subscribe to receive the feeds from the server. The server would send the feed after every 5 seconds (as we cannot replicate the live scenario) to the consumer.
We will create two Mulesoft application. One for Server and one for client implementation.
For the Tutorial, we are using insecure websocket (ws). For secure websocket (wss), underlying layer of http needs to be secured to make it https. You can refer the tutorial link SSL based service for making secured http.
Steps
Here is the sequence of communication that will happen in the application.
- Client will create a new socket with server.
- Server will send the response to client if authentication is successful.
- Client will send a subscription message to subscribe the match feed.
- Server will start sending the feed once the match is started to all the subscribed client.
Server application
Create flow for new connection from client. to achieve this. Client would send the request to ws://localhost:80/wsserver/matchfeed
Use “On New Inbound Connection” websocket connector. As an example, Close the connection using “Close Socket” websocket connector, if the header sent by client doesn’t satisfy the condition attributes.headers.authorization_key == “admin@12345” .
Use “Send” websocket connector to send the success response to the client.
Create the flow for subscription of the match. Server would send the match feed to only subscribed consumer.
Use “On New Inbound Message” websocket connector to receive the message from the Client. Save the Socket ID sent by the client in objectstore. We would need the socket id to send the feed to the consumer later.
Create flow for triggering the Match feed. We are using static data in the example, which will be sent to all the subscribed consumer using their socket ID stored in the Objectstore. Use “Send” websocket connector to send the message to the subscriber using the socket id.
Once all the match score feeds has been sent to the consumers, close the socket as below and remove the entry from object store also. Use “Close Socket” websocket connector to close the socket using the socket id.
WebSocket server-side configuration
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="81ee1384-1849-48bb-be8b-92b93452b135"> <http:listener-connection host="0.0.0.0" port="80" /> </http:listener-config> <websocket:config name="WebSockets_Config_server" doc:name="WebSockets Config" doc:id="e371c5df-6313-434c-9e09-e53ae0ed1850"> <websocket:connection> <websocket:server-settings listenerBasePath="/wsserver" listenerConfig="HTTP_Listener_config" /> </websocket:connection> </websocket:config>
Client application
We need to create a client application which should be able to connect to the server as defined above, subscribe for the match, and receive the Match feeds as an when published by the server.
Create the flow as below to create a new connection (socket) with the server using “Open outbound socket” websocket connector. We are creating and storing the socket id in the objectstore for later use.
Create the flow as below to send a match subscription request to the server using “Send” websocket connector.
Create a flow below which will listen to the match feed sent by the server using “On New Outbound Message” websocket connector.
WebSocket client-side configuration
<websocket:config name="WebSockets_Config_client1" doc:name="WebSockets Config" doc:id="75a0a2aa-f746-4f15-9014-1b6b8449cd86"> <websocket:connection> <websocket:client-settings host="localhost" port="80" basePath="/wsserver" /> </websocket:connection> </websocket:config>
Running & Testing the Application
Start both the Mulesoft application “mulesy-websocket-client” and “mulesy-websocket-server”
. Once started, you would see as below in the console logs.
We have created HTTP listener to trigger the Connection, subscription, and match feed. To trigger the new connection to server, make the http call as below for client_name as client1 and client2.
http://localhost:8081/connect?client_name=client1
http://localhost:8081/connect?client_name=client2
To trigger the subscription request to server, make the http call as below for client_name as client1 and client2.
http://localhost:8081/subscribe?client_name=client1
http://localhost:8081/subscribe?client_name=client2
To trigger the feeds from server to all the subscribed clients, make http call as below.
http://localhost:8082/triggerfeed
Logs
You can look for [mulesy-websocket-server] for logs in server application and [mulesy-websocket-client] for logs in client application.
You could see that both the clients i.e. client1 and client2 received the feeds sent by the server.
logs snippet
INFO 2020-07-17 18:03:14,656 [[MuleRuntime].cpuLight.13: [mulesy-websocket-server].mulesy-websocket-server-new-connection-Flow.CPU_LITE @61215c4e] [event: af1f9b81-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: connection request received from socket id WebSockets_Config_server/wsserver/matchfeed/aeff1b30-c829-11ea-ad31-2079183aaa43 INFO 2020-07-17 18:03:14,685 [[MuleRuntime].cpuLight.13: [mulesy-websocket-server].mulesy-websocket-server-new-connection-Flow.CPU_LITE @61215c4e] [event: af1f9b81-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Authentication successfull for socket id WebSockets_Config_server/wsserver/matchfeed/aeff1b30-c829-11ea-ad31-2079183aaa43 INFO 2020-07-17 18:03:14,768 [[MuleRuntime].cpuLight.14: [mulesy-websocket-client].mulesy-websocket-client-receive-match-feed-Flow.CPU_LITE @640cac4c] [event: af3c9960-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Client - Received the data from Server payload connection successful for socket id ae4233d0-c829-11ea-ad31-2079183aaa43-client1 INFO 2020-07-17 18:03:18,117 [[MuleRuntime].cpuLight.14: [mulesy-websocket-server].mulesy-websocket-server-new-connection-Flow.CPU_LITE @61215c4e] [event: b13ef910-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: connection request received from socket id WebSockets_Config_server/wsserver/matchfeed/b13ed200-c829-11ea-ad31-2079183aaa43 INFO 2020-07-17 18:03:18,119 [[MuleRuntime].cpuLight.14: [mulesy-websocket-server].mulesy-websocket-server-new-connection-Flow.CPU_LITE @61215c4e] [event: b13ef910-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Authentication successfull for socket id WebSockets_Config_server/wsserver/matchfeed/b13ed200-c829-11ea-ad31-2079183aaa43 INFO 2020-07-17 18:03:18,125 [[MuleRuntime].cpuLight.12: [mulesy-websocket-client].mulesy-websocket-client-receive-match-feed-Flow.CPU_LITE @640cac4c] [event: b13fe370-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Client - Received the data from Server payload connection successful for socket id b13c12e0-c829-11ea-ad31-2079183aaa43-client2 INFO 2020-07-17 18:03:22,808 [[MuleRuntime].cpuLight.12: [mulesy-websocket-server].mulesy-websocket-server-new-subscription-Flow.CPU_LITE @2707e2a4] [event: b40a7521-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Subscription requested from WebSockets_Config_server/wsserver/matchfeed/aeff1b30-c829-11ea-ad31-2079183aaa43 for the match id 12345 INFO 2020-07-17 18:03:22,814 [[MuleRuntime].cpuIntensive.16: [mulesy-websocket-client].mulesy-websocket-client-subscription-Flow.CPU_INTENSIVE @49f48980] [event: b406a490-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: subscription Request sent to server for socket id- ae4233d0-c829-11ea-ad31-2079183aaa43-client1 INFO 2020-07-17 18:03:26,325 [[MuleRuntime].cpuLight.12: [mulesy-websocket-server].mulesy-websocket-server-new-subscription-Flow.CPU_LITE @2707e2a4] [event: b623b830-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Subscription requested from WebSockets_Config_server/wsserver/matchfeed/b13ed200-c829-11ea-ad31-2079183aaa43 for the match id 12345 INFO 2020-07-17 18:03:26,325 [[MuleRuntime].cpuIntensive.07: [mulesy-websocket-client].mulesy-websocket-client-subscription-Flow.CPU_INTENSIVE @49f48980] [event: b621bc60-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: subscription Request sent to server for socket id- b13c12e0-c829-11ea-ad31-2079183aaa43-client2 INFO 2020-07-17 18:03:36,741 [[MuleRuntime].cpuLight.12: [mulesy-websocket-client].mulesy-websocket-client-receive-match-feed-Flow.CPU_LITE @640cac4c] [event: bc589e00-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Client - Received the data from Server payload { "id": "1", "event_id": "123", "match_id": 12345, "player1": "Player 1", "player2": "Player 2", "player1_score": "0", "player2_score": "1" } <strong>for socket id ae4233d0-c829-11ea-ad31-2079183aaa43-client1</strong> INFO 2020-07-17 18:03:36,741 [[MuleRuntime].cpuLight.11: [mulesy-websocket-client].mulesy-websocket-client-receive-match-feed-Flow.CPU_LITE @640cac4c] [event: bc593a40-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Client - Received the data from Server payload { "id": "1", "event_id": "123", "match_id": 12345, "player1": "Player 1", "player2": "Player 2", "player1_score": "0", "player2_score": "1" } <strong>for socket id b13c12e0-c829-11ea-ad31-2079183aaa43-client2</strong> INFO 2020-07-17 18:03:36,746 [[MuleRuntime].cpuLight.14: [mulesy-websocket-server].mulesy-websocket-server-send-match-feed-Flow/processors/3/processors/1/processors/0.CPU_LITE @254d11f7] [event: bc2e59b0-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: sent feed to socket id- WebSockets_Config_server/wsserver/matchfeed/aeff1b30-c829-11ea-ad31-2079183aaa43 INFO 2020-07-17 18:03:36,746 [[MuleRuntime].cpuLight.13: [mulesy-websocket-server].mulesy-websocket-server-send-match-feed-Flow/processors/3/processors/1/processors/0.CPU_LITE @254d11f7] [event: bc2e59b0-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: sent feed to socket id- WebSockets_Config_server/wsserver/matchfeed/b13ed200-c829-11ea-ad31-2079183aaa43 INFO 2020-07-17 18:03:41,770 [[MuleRuntime].cpuLight.13: [mulesy-websocket-server].mulesy-websocket-server-send-match-feed-Flow/processors/3/processors/1/processors/0.CPU_LITE @254d11f7] [event: bc2e59b0-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: sent feed to socket id- WebSockets_Config_server/wsserver/matchfeed/aeff1b30-c829-11ea-ad31-2079183aaa43 INFO 2020-07-17 18:03:41,771 [[MuleRuntime].cpuLight.14: [mulesy-websocket-server].mulesy-websocket-server-send-match-feed-Flow/processors/3/processors/1/processors/0.CPU_LITE @254d11f7] [event: bc2e59b0-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: sent feed to socket id- WebSockets_Config_server/wsserver/matchfeed/b13ed200-c829-11ea-ad31-2079183aaa43 INFO 2020-07-17 18:03:41,773 [[MuleRuntime].cpuLight.12: [mulesy-websocket-client].mulesy-websocket-client-receive-match-feed-Flow.CPU_LITE @640cac4c] [event: bf584970-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Client - Received the data from Server payload { "id": "2", "event_id": "123", "match_id": 12345, "player1": "Player 1", "player2": "Player 2", "player1_score": "1", "player2_score": "1" } <strong>for socket id b13c12e0-c829-11ea-ad31-2079183aaa43-client2</strong> INFO 2020-07-17 18:03:41,773 [[MuleRuntime].cpuLight.11: [mulesy-websocket-client].mulesy-websocket-client-receive-match-feed-Flow.CPU_LITE @640cac4c] [event: bf57d440-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Client - Received the data from Server payload { "id": "2", "event_id": "123", "match_id": 12345, "player1": "Player 1", "player2": "Player 2", "player1_score": "1", "player2_score": "1" } <strong>for socket id ae4233d0-c829-11ea-ad31-2079183aaa43-client1</strong> INFO 2020-07-17 18:03:46,779 [[MuleRuntime].cpuLight.11: [mulesy-websocket-server].mulesy-websocket-server-send-match-feed-Flow/processors/3/processors/1/processors/0.CPU_LITE @254d11f7] [event: bc2e59b0-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: sent feed to socket id- WebSockets_Config_server/wsserver/matchfeed/aeff1b30-c829-11ea-ad31-2079183aaa43 INFO 2020-07-17 18:03:46,780 [[MuleRuntime].cpuLight.12: [mulesy-websocket-server].mulesy-websocket-server-send-match-feed-Flow/processors/3/processors/1/processors/0.CPU_LITE @254d11f7] [event: bc2e59b0-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: sent feed to socket id- WebSockets_Config_server/wsserver/matchfeed/b13ed200-c829-11ea-ad31-2079183aaa43 ….. INFO 2020-07-17 18:04:46,954 [[MuleRuntime].cpuLight.11: [mulesy-websocket-client].mulesy-websocket-client-receive-match-feed-Flow.CPU_LITE @640cac4c] [event: e6324550-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Client - Received the data from Server payload { "id": "15", "event_id": "123", "match_id": 12345, "player1": "Player 1", "player2": "Player 2", "player1_score": "5", "player2_score": "10" } for socket id ae4233d0-c829-11ea-ad31-2079183aaa43-client1 INFO 2020-07-17 18:04:46,956 [[MuleRuntime].cpuLight.13: [mulesy-websocket-client].mulesy-websocket-client-receive-match-feed-Flow.CPU_LITE @640cac4c] [event: e632ba80-c829-11ea-ad31-2079183aaa43] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Client - Received the data from Server payload { "id": "15", "event_id": "123", "match_id": 12345, "player1": "Player 1", "player2": "Player 2", "player1_score": "5", "player2_score": "10" } for socket id b13c12e0-c829-11ea-ad31-2079183aaa43-client2
Artifacts
Here is the application attached for you reference.
How can we start both server and client instances Here at the same time? In my local asking to stop one instance and then run a new one.
Right click on one of the projects you want to run -> Go to Run Configurations -> Select application names you want to run.
Hi,
can i import both project in my Anypoint Studio. is it working good for me else i have to do some changes in it?