javascript - Node.js 和 Comet

标签 javascript ajax node.js comet

基本上,我正在尝试从头开始使用 node.js 设置一个基本的 Comet 服务器和客户端。尝试用谷歌搜索它应该工作的过程,并且在我测试时它似乎工作正常。然而,有一个问题仍然在我脑海中。首先,我想向您展示代码。

var http = require('http');
var sys = require('sys');
var fs = require('fs');
var qs = require('querystring');

var server = http.createServer();

var connections = [];

server.on('request', function(req, res) {

    console.log(req.url);

    if(req.url == '/index') {

        fs.readFile(__dirname + '/index.html', function(err, data){
            if(err) {
                res.writeHead(err, data);
                return res.end('Error loading index.html');
            }

            res.writeHead(200);
            res.end(data);
        });
    } else if(req.url == '/sendData') {
        if (req.method == 'POST') {
            var body = '';
            req.on('data', function (data) {
                body += data;
            });
            req.on('end', function () {

                var POST = qs.parse(body);
                console.log(POST);
                res.writeHead(200);
                res.end("");
                broadcastData(POST);
            });
        }

    } else {
        connections.push(res);
    }
});

function broadcastData(data) {
    for(var i = 0; i < connections.length; i++) {
        connections[i].writeHead(200);
        connections[i].end(JSON.stringify({'message': data}));
    }
}

process.openStdin().addListener('data', function(chunk) {
    for(var i = 0; i < connections.length; i++) {
        connections[i].writeHead(200);
        var message = chunk.toString();
        connections[i].end(JSON.stringify({'message': {'name': message}}));
    }
});

server.listen(4000);

客户端:

function doComet() {
    $.getJSON('/', function(events){
        doComet();
        console.log(events);
        $('#content').append(events.message.name);
    });
}

function sendData(data) {
    $.ajax({
        type: "POST",
        url: "/sendData",
        contentType: 'application/javascript; charset=UTF-8',
        data: { name: "John", location: "Boston" }
    }).done(function( msg ) {
        console.log(msg)
    });
}

所以有一个监听器发送我写在 stdin 上的数据,在客户端还有一个按钮将数据发送到服务器,然后服务器将它发送到所有客户端。

我的问题是,如果在非常短的时间内发生了很多事件怎么办?我的意思是,一旦从服务器收到响应,就会发送另一个 ajax 请求,但是当客户端尚未连接时应该有很短的时间,如果在此期间发生某些事情,客户端将不会有新数据。

那么我的想法对吗?在这种情况下,我应该以某种方式正确同步数据以确保每个人都能得到它。有谁知道如何正确地做到这一点?

谢谢你的帮助!

最佳答案

Comet 是所有旧的基于 HTTP 的 hack 的总称,是我们想要摆脱的短语。 WebSockets 是我们想要的地方;浏览器及其他。因此,如果您对构建实时解决方案感兴趣,那么您可能应该首先研究 WebSockets,然后处理诸如 HTTP 流和 HTTP 长轮询之类的回退。有关详细信息,请参阅 Realtime Web Technology Transport Mechanisms .

您提供的示例将被归类为 HTTP 长轮询。

what if a lot of events happen in a really short amount of time? I mean as soon as a response got from the server another ajax request is sent but there should be a short amount of time when the client is not connected yet and if happens something during that time the client will not have the fresh data

这是 HTTP 长轮询的限制之一,也是为什么 HTTP 流式传输是更好的解决方案,而 WebSockets 更好 - 发送数据时连接不会关闭。对于任何类型的轮询解决方案,您可能都需要一种解决方案来确保在轮询请求期间接收和发送的消息不会被轮询客户端遗漏。

有几个解决方案:

  1. 使用 session 来跟踪发送给特定客户的最后一条消息。当他们重新连接时,检查最后发送了哪些消息,错过了哪些消息并发送。
  2. 作为客户端轮询的一部分,发送一个 lastMessageId。当服务器收到此消息时,您可以检查它是否是最后一条消息。如果没有,您可以回复任何遗漏的消息。

实时网络技术的复杂性之一是处理所有可能的连接场景。因此,如果您将此作为一种学习体验,那绝对是有益且有趣的。但是,如果您正在创建一个应用程序以投入生产,我会推荐一个现有的实时框架。查看realtime web tech guide .

关于javascript - Node.js 和 Comet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15966813/

相关文章:

javascript - 仅在ajax完成后加载部分html View - 同步

javascript - Ajax请求说提交数据成功但是php没有响应

javascript - 如何在不刷新的情况下加载新内容到DIV

javascript - Nodejs,通过回调关闭mongo db连接

node.js - npm 更新检查失败

javascript - 使用scrapy抓取动态网页数据

javascript - 当我选择另一个选择标签的某个选项时,如何自动更改选择标签选项的值列表 HTML <select>

javascript - 如何在 javascript + html 中获取 li 类中的嵌套 div id 值

javascript - 如何为用 svelte.js 编写的应用程序创建插件?

node.js - 为什么 DecisionTask 没有从 AWS-SWF 服务 (SWF) 接收任何任务?