如何调用ws WebSocket并等待Express.js的响应?



我已经设置Nodejs使用ExpressJs服务HttpServer。我还需要使用wsWebSocket,以便连接到我的设备获取数据。

我的尝试就是这样。

import express from 'express';
import cors from 'cors';
import http from 'http';
import { WebSocketServer } from 'ws';
const app = express();
app.use(cors());
//initialize a simple http server
const httpServer = http.createServer(app);
const wsServer = new WebSocketServer({ port: 7777});
wsServer.on('connection', function connection(ws, req) {
app.get('/', (req, res) => {
ws.send('{"msg":"getdata"}');
ws.on('message', function message(data) {
data = JSON.parse(data);
res.json(data);
});
});

//start our server
httpServer.listen(7778, () => {
console.log(`Server started on port ${httpServer.address().port} :)`);
});
});

问题是当API被多次调用时。抛出错误code: 'ERR_HTTP_HEADERS_SENT'。我认为这是因为ws.on('message')被执行了多次。所以,我试图找到一种方法来删除侦听器,但无济于事。

有更好的方法吗?我只是想有一个web服务器调用另一个websocket,以便从设备获取数据。

要使您的代码示例工作,必须在/请求后发送websocket上的消息。因为在此之前,没有在message上注册处理程序。而且,一旦成功处理了第一个请求,你就不能再发送websocket消息了。因为,当您这样做时,message处理程序中的res已经完成。所以你会得到ERR_HTTP_HEADERS_SENT。由此证明:-)

因此,您的API调用必须像以下模式 一样
  • /Call #1

  • Websocket message #1

  • /Call #2

  • Websocket message #2

如果您这样做,您将不会得到ERR_HTTP_HEADERS_SENT错误。因为每个/请求都会发送一次res

这将解决您的错误代码:'ERR_HTTP_HEADERS_SENT'

wsServer.on('connection', function connection(ws, req) {
app.get('/', (req, res) => {
//first This
ws.on('message', function message(data) {
data = JSON.parse(data);
res.json(data);
});
//then use this
ws.send('{"msg":"getdata"}');

});

//start our server
httpServer.listen(7778, () => {
console.log(`Server started on port ${httpServer.address().port} :)`);
});
});
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var timeout = require('connect-timeout');
var uuid = require('uuidv4');
var _ = require('lodash');
app.use(timeout('10s'));
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
let responses = []
io.on('connection', (socket) => {
socket.on('res', (e) => {
var obj = _.find(responses, r => r.id === e.id);
obj.res.send(e)
_.remove(responses, r => r.id === e.id);
})
})
app.get('/endpoint', (req, res) => {
const id = uuid()
io.emit('req', { id, ip: req.ip, header: req.headers, method: req.method });
responses.push({ id, res })
});
http.listen(3000);

如果需要多个实例,可以使用redis pub sub。

最新更新