Configuré Nodejs para servir un HttpServer usando ExpressJs. También necesito usar ws WebSocket para conectarme a mi dispositivo para obtener datos.
Mi intento ahora es este.
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} :)`); }); }); El problema es que cuando se llama a la API más de una vez. Se arroja un code: 'ERR_HTTP_HEADERS_SENT' . Supongo que se debe a que ws.on('message') se ejecuta varias veces. Entonces, estoy tratando de encontrar una manera de eliminar al oyente, pero fue en vano.
¿Hay alguna manera mejor de hacer esto? Solo quiero tener un servidor web que llame a otro websocket para obtener datos de un dispositivo.
esto resolverá su código de error: '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} :)`); }); });Para que su ejemplo de código funcione, se debe enviar un mensaje en websocket después de realizar la solicitud / . Porque, antes de eso, el controlador de message no está registrado. Además, una vez que haya manejado la primera solicitud con éxito, no podrá volver a enviar un mensaje websocket. Porque, cuando haces eso, la res en el controlador de message ya está completa. Entonces, obtendrá ERR_HTTP_HEADERS_SENT . Así lo demostró :-)
Entonces, sus llamadas API deben ser como en el siguiente patrón
/ Llamada #1
Mensaje de WebSocket #1
/ Llamada #2
Mensaje de WebSocket #2
Si lo hace, no obtendrá el error ERR_HTTP_HEADERS_SENT . Porque, res se envía una vez por cada / solicitud.
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);Si desea más de varias instancias, puede usar redis pub sub.