I have an Express server that listens for webhook events from an external API. When it received these events, I want the handler for that http request to send a message to a WebSocket client. Here is some basic code to illustrate what I mean
The external API will send a HTTP POST request to an endpoint on my Express server, lets say it looks like this:
app.post('/external-api', (req, res) => {
// webhook payload will be in req.body
})
In that handler for /external-api
I'd like to send a message to a client who's connected to the server via WebSocket. As of right now, I'm using the npm ws
library, so I want the logic to look something like this
app.post('/external-api', (req, res) => {
ws.broadcast(req.body);
})
Is there a way to do this? I'm open to using other libraries but I just need a way to send a message to a WebSocket client from a HTTP POST request handler in Express.
To send a message through the WebSocket connection you call the send() method on your WebSocket instance; passing in the data you want to transfer. socket. send(data); You can send both text and binary data through a WebSocket.
Yes, a webSocket connection will always start with a GET request, not a POST or any other method.
In order to communicate using the WebSocket protocol, you need to create a WebSocket object; this will automatically attempt to open the connection to the server. The URL to which to connect; this should be the URL to which the WebSocket server will respond.
You can't call an HTTP API from web socket. You can call a web socket API from a web socket. That mostly means you send some specific message over web socket to the server, and the server sends something specific back.
WebSockets - Send & Receive Messages. The Message event takes place usually when the server sends some data. Messages sent by the server to the client can include plain text messages, binary data, or images. Whenever data is sent, the onmessage function is fired. This event acts as a client's ear to the server.
Here's how you can use the ws package to listen to websockets on an Express server. The ws package supports native Node.js HTTP servers. Conveniently, Express' listen () function returns a native Node.js HTTP server.
//To access POST variable use req.body ()methods. In this way, you can handle the GET and POST request in the Express framework. To demonstrate this, I am going to code one simple log-in System which will use GET request to serve HTML page to client and POST request from the client to send user name and password to Server.
POST requests requests are different from GET requests because POST requests are allowed to send data in the HTTP request body. For example, the below code sends an HTTP POST request with a JSON object in the request body:
Here is an example:
index.ts
:
import express from 'express';
import WebSocket from 'ws';
import http from 'http';
import path from 'path';
import faker from 'faker';
const app = express();
const port = 3000;
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
wss.on('connection', (ws: WebSocket) => {
console.log('establish websocket connection');
ws.on('message', (message) => {
console.log('received: %s', message);
});
});
app.get('/client/:id', (req, res) => {
res.sendFile(path.resolve(__dirname, `./public/client-${req.params.id}.html`));
});
app.get('/external-api', (req, res) => {
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(faker.internet.email());
}
});
res.sendStatus(200);
});
server.listen(port, () => console.log(`http server is listening on http://localhost:${port}`));
client-1.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>client 1</title>
</head>
<body>
<p>client 1</p>
<button id="test">Test</button>
<script>
(function() {
window.onload = function() {
const socket = new WebSocket('ws://localhost:3000');
// Connection opened
socket.addEventListener('open', function(event) {
socket.send('Hello Server! Client - 1');
});
// Listen for messages
socket.addEventListener('message', function(event) {
console.log('Message from server ', event.data);
});
const btn = document.getElementById('test');
btn.addEventListener('click', async () => {
try {
const res = await fetch('http://localhost:3000/external-api');
console.log(res);
} catch (error) {
console.log(error);
}
});
};
})();
</script>
</body>
</html>
client-2.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>client 2</title>
</head>
<body>
<p>client 2</p>
<button id="test">Test</button>
<script>
(function() {
window.onload = function() {
const socket = new WebSocket('ws://localhost:3000');
// Connection opened
socket.addEventListener('open', function(event) {
socket.send('Hello Server! Client - 2');
});
// Listen for messages
socket.addEventListener('message', function(event) {
console.log('Message from server ', event.data);
});
const btn = document.getElementById('test');
btn.addEventListener('click', async () => {
try {
const res = await fetch('http://localhost:3000/external-api');
console.log(res);
} catch (error) {
console.log(error);
}
});
};
})();
</script>
</body>
</html>
Now, click the button of client 1, send HTTP request to /external-api
.
The console logs of client 1:
The console logs of client 2:
The logs of server:
http server is listening on http://localhost:3000
establish websocket connection
received: Hello Server! Client - 1
establish websocket connection
received: Hello Server! Client - 2
As you can see, the server broadcast fake emails to client 1 and client 2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With