如何在原生 JavaScript 和 node.js 中使用长轮询?

Posted

技术标签:

【中文标题】如何在原生 JavaScript 和 node.js 中使用长轮询?【英文标题】:How to use long polling in native JavaScript and node.js? 【发布时间】:2018-02-01 20:27:20 【问题描述】:

我需要为聊天应用程序实现long polling。我四处搜索,但我只找到了如何在javascript 中使用JQuery 来实现它。如何仅使用native JavaScriptnode.js 来实现它?你能指导我一些相关的文章或材料吗?

【问题讨论】:

我建议你看看套接字而不是长轮询,它比长轮询更有效***.com/questions/10028770/… (ps:我最近才知道什么是长轮询,所以我无法帮助你解决你的问题) 你好,我不允许使用sockets,这是我项目中的要求,虽然sockets更专业,我之前的项目中使用过 【参考方案1】:

问:如何在原生Javascript in nodeJS 中进行长轮询?

答:我想首先您需要了解长轮询模型的工作原理。如果您还没有任何线索,那么RFC-6202 specification 是一个很好的起点。

这是关于客户端向server 发送request 并等待直到返回响应。

从规范中我们知道,首先客户端必须发出一个http 请求,该请求具有无限或至少一个高超时值。然后服务器,也就是你的nodeJs 应用程序,应该将所有传入的请求存储到一个数据结构中,基本上是一个保存区域。您的应用程序基本上会保留所有 response 对象,直到触发事件,然后您适当地回复响应。

考虑这个伪代码:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');

var requestCounter = 0;

var responses = 
  /* Keyed by room Id =*/
  "room_abc" : [ /* array of responses */]
;

app.get('/', function (req, res) 
    requestCounter += 1;

    var room = /* assuming request is for room_abc */ "room_abc";

    // Stash the response and reply later when an event comes through
    responses[room].push(res);

    // Every 3rd request, assume there is an event for the chat room, room_abc.
    // Reply to all of the response object for room abc.
    if (requestCounter % 3 === 0) 
        responses["room_abc"].forEach((res) => 
            res.send("room member 123 says: hi there!");
            res.end();
        );
    
);

app.use(bodyParser.text( type: 'text/*' ));
app.use(bodyParser.json());

app.listen(9999, function () 
    console.log('Example app listening on port 9999!')
)

在这里编写一个工作示例相对耗时,但上面的代码是一个很好的示例,说明了如何在NodeJS 中实现长轮询。

如果您安装了postmancurl,您可以使用GET 方法对HTTP 进行HTTP 调用。您应该注意到,在前两个调用中您不会得到响应,而当您触发第三个调用时,您将收到所有先前和当前调用的响应。

这里的想法是您首先存储请求的response 对象,当事件发生时,假设在每 3 次 HTTP 调用中,您然后循环所有响应并回复它们。对于您的聊天应用程序而言,触发响应的事件可能是有人向聊天室发送消息。

【讨论】:

嗨,谢谢你的回答,但是我有一个问题,当一些用户向房间发送消息时,我可以用一个通过计数器值检查是否有新消息的条件替换最后一个条件,也就是说,如果计数器值大于我已经拥有的值,那么房间聊天中应该会显示新消息,对吗?另一件事,我如何使用本机javascript“调用”客户端的服务器? 我猜你需要有两个端点。一个供客户停放并等待响应。这在上面得到了证明。然后另一条供客户发布聊天消息。写完消息后,您将需要遍历该房间的所有 response 对象并适当地回复它们。 关于您关于客户如何发送HTTP 休息电话的其他问题。以developer.mozilla.org/en-US/docs/Web/API/Request为例 您的代码示例没有显示长轮询,它实际上显示了既不是长轮询也不是短轮询的东西。对于长轮询,如果在发出请求时数据不可用,则将保持连接,当数据可用时,将发送响应。如果在超时之前数据不可用,则应通过超时中止连接。

以上是关于如何在原生 JavaScript 和 node.js 中使用长轮询?的主要内容,如果未能解决你的问题,请参考以下文章

使用原生javascript如何读写css样式?

将“Vanilla”Javascript 库加载到 Node.js 中

node.js 1

如何将 json 从 JavaScript 传递到 iPad 原生应用程序?

使用JavaScript调用手机平台上的原生API

如何编写重用通用 JavaScript 代码的反应原生“本机模块”(桥)?