以快递方式从 POST 请求处理程序发送 WebSocket 消息
Posted
技术标签:
【中文标题】以快递方式从 POST 请求处理程序发送 WebSocket 消息【英文标题】:Sending a WebSocket message from a POST request handler in express 【发布时间】:2020-11-15 20:25:50 【问题描述】:我有一个 Express 服务器,用于侦听来自外部 API 的 webhook 事件。当它收到这些事件时,我希望该 http 请求的处理程序向 WebSocket 客户端发送消息。这是一些基本代码来说明我的意思
外部 API 将向我的 Express 服务器上的端点发送 HTTP POST 请求,假设它看起来像这样:
app.post('/external-api', (req, res) =>
// webhook payload will be in req.body
)
在/external-api
的处理程序中,我想向通过 WebSocket 连接到服务器的客户端发送消息。截至目前,我正在使用 npm ws
库,所以我希望逻辑看起来像这样
app.post('/external-api', (req, res) =>
ws.broadcast(req.body);
)
有没有办法做到这一点?我愿意使用其他库,但我只需要一种从 Express 中的 HTTP POST 请求处理程序向 WebSocket 客户端发送消息的方法。
【问题讨论】:
也许你改用 AWS Websockets。 【参考方案1】:这是一个例子:
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>
现在,点击客户端1的按钮,向/external-api
发送HTTP请求。
客户端1的控制台日志:
客户端2的控制台日志:
服务器日志:
http server is listening on http://localhost:3000
establish websocket connection
received: Hello Server! Client - 1
establish websocket connection
received: Hello Server! Client - 2
如您所见,服务器向客户端 1 和客户端 2 广播虚假电子邮件。
【讨论】:
以上是关于以快递方式从 POST 请求处理程序发送 WebSocket 消息的主要内容,如果未能解决你的问题,请参考以下文章
通过Angular App和NodeJS向快递服务器发送GET / POST请求时如何修复404 Not Found
在 multipart/form-data POST 请求节点中发送缓冲区 |快递 |要求
java使用POST发送soap报文请求webservice返回500错误解析