【问题标题】:How can i wait for data until it get received in Node.js from a TCP server while GET request is sent by the user?当用户发送 GET 请求时,我如何等待数据,直到它在 Node.js 中从 TCP 服务器收到?
【发布时间】:2016-03-26 19:07:13
【问题描述】:

我想向基于 C++ 的服务器发送一条消息,该服务器在发送消息后正在侦听端口“9090”,服务器将执行一些需要一些时间的工作或任务,所以我不想离开 app.get();功能块,在从服务器获取数据然后作为响应发送回用户之前,我该怎么做?

基本上我想要的是不回复用户,留在循环中 while(close_connection_flag == false) 直到它设置为 true 以离开循环(直到我得到一个 tcp-reply 数据)然后离开循环并回复用户。

我的代码:

var net = require('net');
var tcp_client = new net.Socket();
var express = require('express');
var app = express();
var close_connection_flag = false;
var flag_raised_by_server = '';


app.get('/', function(req, res) {

  tcp_client.on('connect', function(){
    console.log('[+] Connected.');
    tcp_client.write('HelloServerSideFrom:Client-Server');
  });

  while(close_connection_flag == false) {

    tcp_client.on('data', function(data) {

      switch(data){

        case 'HelloClientServerFrom:Server':
          close_connection_flag = true;
          break;
        case 'data-success':
          close_connection_flag = true;
          flag_raised_by_server = 'ds';
          break;
        case 'data-failure':
          close_connection_flag = true;
          flag_raised_by_server = 'df';
          break
        default:
          // do nothing.
          break;     

      }

    });

  }

  res.end('flag raised by server is: ' + flag_raised_by_server);
  tcp_client.destroy();
});

注意:我还是Node.js的新手,所以如果你能提供一些cmets或示例代码的解释,如果你提供的话,谢谢。

【问题讨论】:

  • 你不应该有一个tcp_client.on('close') 事件吗?

标签: javascript node.js sockets


【解决方案1】:

如果我正确理解了这个问题,您希望在收到来自下游套接字服务器的响应后立即发送 HTTP 响应。

首先,要考虑的最重要的事情是:Socket 连接——就像几乎所有东西一样——在 Node.JS 中是异步的

这有一些非常重要的后果:

  1. 在您收到一些数据之前,对tcp_client.on('data', ...) 的调用不会阻止您的程序执行。它只会注册一个回调函数,该回调函数将(可能)在稍后的某个时间点被调用,然后继续您的程序。

    这意味着如果你在你的 TCP 客户端注册一个回调然后发送 HTTP 响应,HTTP 响应将被发送首先,你的回调将在稍后的某个时间点被调用。

  2. 无需使用 while 循环来轮询您的套接字;只需使用tcp_client.on('data', ...) 方法once 注册一个回调函数,一旦从套接字读取数据就会调用该回调函数。

    由于tcp_client.on(...)是异步的,所以会立即返回;如果您在循环中这样做,您基本上会无休止地旋转并不断注册新的事件侦听器。所以,失去while(close_connection_flag == false) 循环!

  3. 如果您想等待 HTTP 响应,直到您在 TCP 套接字上收到数据,只需将您的 res.end(...) 调用放在tcp_client 回调中。

总而言之,我建议这样:

app.get('/', function(req, res) {

  tcp_client.on('connect', function(){
    console.log('[+] Connected.');
    tcp_client.write('HelloServerSideFrom:Client-Server');
  });

  tcp_client.on('data', function(data) {
    var flag_raised_by_server;

    switch(data){

      case 'HelloClientServerFrom:Server':
        close_connection_flag = true;
        break;
      case 'data-success':
        close_connection_flag = true;
        flag_raised_by_server = 'ds';
        break;
      case 'data-failure':
        close_connection_flag = true;
        flag_raised_by_server = 'df';
        break
      default:
        // do nothing.
        break;     

    }

    if (flag_raised_by_server) {
      res.end('flag raised by server is: ' + flag_raised_by_server);
      tcp_client.destroy();
    }
  });
});

【讨论】:

  • 谢谢,可能就是这样。
  • 先生,我有一个问题,flag_raised_by_server 变量为空,我得到的响应是:flag raised by server is: 看起来 flag_raised_by_server 没有在 switch case 块中初始化,为什么?
  • 在这种情况下,您可能需要检查 TCP 服务器实际响应的内容;尝试在您的回调中以console.log(data) 开头,以查看服务器是否实际发送了预期的响应。此外,我已经调整了我的代码示例以仅在实际设置 flag_raised_by_server 时发送 HTTP 响应。也许这也有帮助。
  • 是的,你是对的,我的 tcp relpy 为:
  • 啊,是的,这是一个原始字节缓冲区。您应该能够使用data.toString() 将其转换为常规字符串。
【解决方案2】:

不要将close_connection_flag 设置为true,只需在此处关闭连接并返回给用户即可。您在这里所做的是在tcp_client 上创建具有无限数量的侦听器的内存泄漏。

app.get('/', function(req, res) {

  tcp_client.on('connect', function(){
    console.log('[+] Connected.');
    tcp_client.write('HelloServerSideFrom:Client-Server');
  });

  tcp_client.on('data', function(data) {
    switch(data){

    case 'HelloClientServerFrom:Server':
      close_connection_flag = true;
      break;
    case 'data-success':
      close_connection_flag = true;
      flag_raised_by_server = 'ds';
      break;
    case 'data-failure':
      close_connection_flag = true;
      flag_raised_by_server = 'df';
      break
    default:
      // do nothing.
      break;     
    }

    if (close_connection_flag) {
      tcp_client.destroy();
      res.end('flag raised by server is: ' + flag_raised_by_server);
    }
  });
});

【讨论】:

    猜你喜欢
    • 2019-05-22
    • 2021-09-05
    • 2012-04-03
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    相关资源
    最近更新 更多