Node.js 长轮询逻辑有帮助!

发布于 2024-11-09 13:47:04 字数 1091 浏览 0 评论 0原文

我正在尝试使用node.js 实现长轮询策略,

我想要的是当向node.js 发出请求时,它将等待最多30 秒才能获得某些数据。如果有数据,则输出并退出;如果没有数据,则最多等待30秒,然后退出。

这是我想出的基本代码逻辑 -

var http = require('http');

var poll_function = function(req,res,counter)
{

  if(counter > 30)
  {
    res.writeHeader(200,{'Content-Type':'text/html;charset=utf8'});
    res.end('Output after 5 seconds!');
  }
  else
  {
    var rand = Math.random();

    if(rand > 0.85)
    {
      res.writeHeader(200,{'Content-Type':'text/html;charset=utf8'});
      res.end('Output done because rand: ' + rand +  '! in counter: ' + counter);
    }
  }

  setTimeout
  (
    function()
    {
      poll_function.apply(this,[req,res,counter+1]);
    },
    1000
  );
};

http.createServer
(
  function(req,res)
  {
    poll_function(req,res,1);
  }
).listen(8088);

我想的是,当发出请求时,调用 poll_function ,它会在 1 秒后通过自身内部的 setTimeout 调用自身。因此,它应该保持异步方式,它不会阻止其他请求,并在完成时提供其输出。

我在这里使用 Math.random() 逻辑来模拟不同时间间隔的数据可用性场景。

现在,我关心的是 -

1)会有什么问题吗? - 我只是不想部署它,不确定它不会反击!

2)效率高吗?如果没有,有什么建议我该如何改进吗?

谢谢,
安坚

I m trying to implement a long polling strategy with node.js

What i want is when a request is made to node.js it will wait maximum 30 seconds for some data to become available. If there is data, it will output it and exit and if there is no data, it will just wait out 30 seconds max, and then exit.

here is the basic code logic i came up with -

var http = require('http');

var poll_function = function(req,res,counter)
{

  if(counter > 30)
  {
    res.writeHeader(200,{'Content-Type':'text/html;charset=utf8'});
    res.end('Output after 5 seconds!');
  }
  else
  {
    var rand = Math.random();

    if(rand > 0.85)
    {
      res.writeHeader(200,{'Content-Type':'text/html;charset=utf8'});
      res.end('Output done because rand: ' + rand +  '! in counter: ' + counter);
    }
  }

  setTimeout
  (
    function()
    {
      poll_function.apply(this,[req,res,counter+1]);
    },
    1000
  );
};

http.createServer
(
  function(req,res)
  {
    poll_function(req,res,1);
  }
).listen(8088);

What i figure is, When a request is made the poll_function is called which calls itself after 1 second, via a setTimeout within itself. So, it should remain asynchronous means, it will not block other requests and will provide its output when its done.

I have used a Math.random() logic here to simulate data availability scenario at various interval.

Now, what i concern is -

1) Will there be any problem with it? - I simply don't wish to deploy it, without being sure it will not strike back!

2) Is it efficient? if not, any suggestion how can i improve it?

Thanks,
Anjan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

很糊涂小朋友 2024-11-16 13:47:04

只要您不陷入紧密的 CPU 循环(如 while(true))或使用具有阻塞 I/O 的库,所有 Nodejs 代码都是非阻塞的。将 setTimeout 放在函数末尾并不会使其变得更加并行,它只是将一些 cpu 工作推迟到稍后的事件。

这是一个简单的演示聊天服务器,它每隔 0 到 60 秒随机向所有连接客户端发出“Hello World”。

// A simple chat server using long-poll and timeout

var Http = require('http');

// Array of open callbacks listening for a result
var listeners = [];

Http.createServer(function (req, res) {

    function onData(data) {
        res.end(data);
    }
    listeners.push(onData); 

    // Set a timeout of 30 seconds
    var timeout = setTimeout(function () {
        // Remove our callback from the listeners array
        listeners.splice(listeners.indexOf(onData), 1);
        res.end("Timeout!");
    }, 30000);

}).listen(8080);
console.log("Server listening on 8080");

function emitEvent(data) {
    for (var i = 0; l = listeners.length; i < l; i++) {
        listeners[i](data);
    }
    listeners.length = 0;
}

// Simulate random events
function randomEvents() {
    emitData("Hello World");
    setTimeout(RandomEvents, Math.random() * 60000);
}
setTimeout(RandomEvents, Math.random() * 60000);

这会非常快。唯一危险的部分是接头。如果数组变得非常大,拼接可能会很慢。通过每隔 30 秒或最后一个事件后 30 秒一次关闭所有处理程序,而不是从连接开始 30 秒后关闭连接,可以提高效率。但同样,这不太可能成为瓶颈,因为每个数组项都由可能更昂贵的真实客户端连接支持。

All nodejs code is nonblocking as long as you don't get hunk in a tight CPU loop (like while(true)) or use a library that has blocking I/O. Putting a setTimeout at the end of a function doesn't make it any more parallel, it just defers some cpu work till a later event.

Here is a simple demo chat server that randomly emits "Hello World" every 0 to 60 seconds to and and all connection clients.

// A simple chat server using long-poll and timeout

var Http = require('http');

// Array of open callbacks listening for a result
var listeners = [];

Http.createServer(function (req, res) {

    function onData(data) {
        res.end(data);
    }
    listeners.push(onData); 

    // Set a timeout of 30 seconds
    var timeout = setTimeout(function () {
        // Remove our callback from the listeners array
        listeners.splice(listeners.indexOf(onData), 1);
        res.end("Timeout!");
    }, 30000);

}).listen(8080);
console.log("Server listening on 8080");

function emitEvent(data) {
    for (var i = 0; l = listeners.length; i < l; i++) {
        listeners[i](data);
    }
    listeners.length = 0;
}

// Simulate random events
function randomEvents() {
    emitData("Hello World");
    setTimeout(RandomEvents, Math.random() * 60000);
}
setTimeout(RandomEvents, Math.random() * 60000);

This will be quite fast. The only dangerous part is the splice. Splice can be slow if the array gets very large. This can be made possibly more efficient by instead of closing the connection 30 seconds from when it started to closing all the handlers at once every 30 seconds or 30 seconds after the last event. But again, this is unlikely to be the bottleneck since each of those array items is backed by a real client connection that probably more expensive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文