Interfacing data between functions in Node

Tengo un dispositivo conectado a un servidor Node a través de WebSockets. Para poder consultar el dispositivo, una solicitud POST a ese servidor envía el comando necesario a través de WebSockets. Sin embargo, no estoy completamente seguro cuál es el mejor método de implacable conseguir el regreso.

El flujo es esencialmente:

  • El dispositivo se conecta al servidor Node a través de WebSockets
  • Usuario envía solicitud POST a endpoint en el mismo servidor Node
  • Node server envía el comando adecuado al dispositivo a través de WebSockets
  • Respuestas del dispositivo vía WebSockets

Aquí es donde estoy atrapado. ¿Cómo puedo obtener la respuesta de WebSockets de vuelta a la solicitud POST?

Mis primeros pensamientos eran como tales:

  • La solicitud POST sabe qué comando ha sido enviado
  • El dispositivo envía el comando como parte de la respuesta WebSocket

Por lo tanto, puedo tener una simple variedad de mensajes del dispositivo que la función de solicitud POST puede encuestar, y si hay una respuesta adecuada (por ejemplo, en 2 segundos), responder con esos datos y eliminar el mensaje del array. Más abajo de la línea, puedo eliminar cualquier mensaje que haya caducado pero todavía están en el array.

¿Cuáles son mis otras opciones? Presumiblemente podría votar por el cliente haciendo la solicitud POST o conectar alternativamente a ese cliente a través de un WebSocket.

Este servidor admite 1 dispositivo y generalmente 1 usuario a la vez, por lo que no hay ninguna preocupación de que el servidor pueda ser abrumado.

Pregunta hecha hace 3 años, 4 meses, 29 días - Por binarymaestro


2 Respuestas:

  • Para lograr la comunicación efectiva entre las funciones en Node para obtener la respuesta de WebSockets de vuelta a la solicitud POST, puedes considerar implementar un mecanismo de "promesas" (promises) en tu servidor. Aquí te dejo un ejemplo de cómo podrías estructurar tu código:

    • Cuando se realiza la solicitud POST al servidor, puedes devolver una promesa que se resolverá con la respuesta del dispositivo a través de WebSockets.
    • Al enviar el comando adecuado al dispositivo a través de WebSockets, puedes configurar un listener para escuchar las respuestas del dispositivo y resolver la promesa cuando llegue la respuesta correspondiente.

    Aquí tienes un ejemplo de cómo podrías estructurar tu código:

    javascript
    const express = require('express');
    const WebSocket = require('ws');
    
    const app = express();
    const wss = new WebSocket.Server({ port: 8080 });
    
    let responsePromises = {};
    
    wss.on('connection', function connection(ws) {
      ws.on('message', function incoming(message) {
        // Aquí recibirías el mensaje del dispositivo y podrías manejarlo o enviarlo a quién corresponda
        if (responsePromises[message.command]) {
          responsePromises[message.command].resolve(message.data);
          delete responsePromises[message.command];
        }
      });
    });
    
    app.post('/send-command', (req, res) => {
      const command = req.body.command;
    
      const promise = new Promise((resolve, reject) => {
        responsePromises[command] = { resolve, reject };
      });
    
      // Aquí enviarías el comando adecuado al dispositivo a través de WebSockets
    
      promise
        .then((data) => {
          // Cuando llega la respuesta del dispositivo, responde a la solicitud POST con los datos
          res.json(data);
        })
        .catch((error) => {
          res.status(500).json({ error: 'Error al obtener la respuesta del dispositivo' });
        });
    });
    
    app.listen(3000, () => {
      console.log('Servidor Node escuchando en el puerto 3000');
    });
    

    Con este enfoque, la solicitud POST esperará a que se resuelva la promesa para obtener la respuesta del dispositivo a través de WebSockets. Espero que esta sugerencia sea útil para tu implementación. Si tienes alguna pregunta adicional o necesitas más ayuda, no dudes en decírmelo.

    Respondida el Dec 19, 2020 a las 16:33 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Mejor enfoque:

    El enfoque que describiste es viable, pero existen opciones mejores que utilizan las capacidades de Node.js.

    Usando promesas:

    • En la función de ruta POST, crea una promesa.
    • Cuando se envía el comando al dispositivo a través de Websockets, resuelve la promesa con la respuesta.
    • En la función de WebSocket, cuando se recibe una respuesta, llama a la función de resolución de promesas.

    Ejemplo de código:

    Función de ruta POST:

    
    router.post('/endpoint', async (req, res) => {
      // Crea una promesa
      const promise = new Promise((resolve, reject) => {
        // La promesa se resolverá cuando se reciba la respuesta del dispositivo
        resolveResponse = resolve;
      });
    
      // Envía el comando al dispositivo
      wsClient.send(req.body);
    
      // Espera a que se resuelve la promesa
      const response = await promise;
    
      // Envía la respuesta al cliente
      res.json(response);
    });
    

    Función de WebSocket:

    
    wsClient.on('message', (message) => {
      // Llama a la función de resolución de promesas y pasa la respuesta
      resolveResponse(message);
    });
    

    Otras opciones:

    Uso de callbacks: Similar al enfoque de las promesas, pero utilizando callbacks para resolver la promesa. Uso de un bus de mensajes: Implementa un bus de mensajes para comunicar los resultados entre las funciones. Uso de un almacenamiento en memoria caché:* Almacena las peticiones y respuestas en una caché para que la función POST pueda recuperar la respuesta cuando esté disponible.

    El enfoque que elijas depende de tus preferencias y requisitos específicos. Sin embargo, usar promesas o callbacks es generalmente el enfoque más limpio y eficiente.

    Respondida el Dec 19, 2020 a las 16:38 - por Gemini

    Votos positivos: 0 | Votos negativos: 0