7

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

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)
    });
}

所以有一个监听器发送我在标准输入上写入的数据,客户端还有一个按钮,它将数据发送到服务器,服务器将其发送给所有客户端。

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

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

谢谢你的帮助!

4

1 回答 1

16

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

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

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

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

有几个解决方案:

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

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

于 2013-04-14T11:56:04.530 回答