使用 Comet 长轮询向服务器发送消息

发布于 2024-08-13 15:07:36 字数 151 浏览 12 评论 0原文

从客户端向服务器发送数据的最佳方式是什么?

我使用的示例代码来自 如何实现基本的“长轮询”?

What's the best way to send data from client to server?

The example code I'm using is from How do I implement basic "Long Polling"?

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

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

发布评论

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

评论(3

耳根太软 2024-08-20 15:07:37

只需使用 XHR 进行 POST 即可。

一个问题是,在某些浏览器上,每台服务器只能有 2 个(或 n 个)并发 XHR 连接。您可以通过创建一个队列来解决此问题,该队列允许您在当前 XHR 完成时发布所有等待消息,然后填充新队列直到该发布完成,如此往复。

Just use XHR to do a POST.

One problem is on some browsers you can only have 2 (or some number n) concurrent XHR connections per server. You can work around this by making a queue that lets you post all waiting messages when the current XHR completes, then filling up a new queue until that post completes, and back and forth.

简单气质女生网名 2024-08-20 15:07:37

向服务器发送数据只是一个标准请求。 Xhr 或 JSONP 都可以,只要你喜欢就行。

不要对长轮询感到困惑;长轮询仅作为从服务器发送到客户端的一种方式存在。从客户端向服务器发送数据是 Web 自诞生以来的使命,而普通的 Xhr 请求就足够了。

Sending data to the server is just a standard request. Xhr is fine, or JSONP, whatever floats your boat.

Don't get confused by the long-polling; the long-polling only exists as a way to send from the server to the client. Sending data from the client to the server is what the web has been about since its inception, and a normal Xhr request is all you need.

半透明的墙 2024-08-20 15:07:37

是的,只需用完与服务器的第二个连接即可。这是大多数框架所做的,包括 iirc Bayeux 协议。如果您发现您确实需要第二个连接,那么请担心。

以下是从我上面的链接修改的一些长轮询代码:

var userid = Math.ceil(1000000*Math.random()).toString(16).toUpperCase();
var startLongpoll = function() {
    $.ajax({
        type:"POST", async:true, cache:false, timeout:0, 
        data: {userid: userid},
        success: function(data){
            _outCallback(data);
            setTimeout( startLongpoll, 10 );
        },
        error: function(xhr, textStatus, errorThrown){
            _errCallback(textStatus+" ("+errorThrown+")");
            setTimeout( startLongpoll, 5000 );
        },
    });
};
setTimeout(startLongpoll,10);

Moishe 在队列中谈论的是 js 不保证 xhrs 将按照您发送它们的顺序接收。消息不会丢失(或者至少在我的测试中没有丢失),这不是一个特定的长轮询问题,而是每当您使用 xhr 发送时都需要考虑的问题。

这是队列代码:有

var queue = [];
var busy = false;
this.send = function(msg) {
    queue[queue.length] = msg;
    if (busy) return;
    busy=true;
    var s = function() {
        var m = queue.shift();
        $.ajax({
            type:"POST", async:true, cache:false, timeout: 5000,
            data: {userid:userid, msg:m},
            error: function(xhr, textStatus, errorThrown){
                _errCallback(textStatus + " (" + errorThrown + ")");
                if (queue.length>0) s(); else busy = false;
            },
            success: function(){
                if (queue.length>0) s(); else busy = false;
            }
        });
    }
    s();
};

两件事需要注意。首先,如果您发送许多消息并且队列已满,则会出现相当大的延迟。最好找到一种方法每次都发送整个队列,而不是一块一块地发送。一种方法是将消息转换为 JSON 数组,然后在服务器上进行解码。

其次,如果发送消息时出现错误,那么您就会丢失该消息。需要一些代码来将失败的消息推回到队列中,或者在成功之前不将其删除。

Yes, just use up the second connection to the server. This is what most frameworks do, including iirc the Bayeux protocol. If you find out you actually need that second connection, worry about it then.

Here's some long-polling code modified from my link above:

var userid = Math.ceil(1000000*Math.random()).toString(16).toUpperCase();
var startLongpoll = function() {
    $.ajax({
        type:"POST", async:true, cache:false, timeout:0, 
        data: {userid: userid},
        success: function(data){
            _outCallback(data);
            setTimeout( startLongpoll, 10 );
        },
        error: function(xhr, textStatus, errorThrown){
            _errCallback(textStatus+" ("+errorThrown+")");
            setTimeout( startLongpoll, 5000 );
        },
    });
};
setTimeout(startLongpoll,10);

What Moishe was talking about with the queue is that js doesn't guarantee that xhrs will be received in the order that you dispatched them. The messages won't be lost (or at least they haven't been in my tests), and this isn't a specific long-polling issue, but something to consider whenever you use xhr to send.

So here's the queue code:

var queue = [];
var busy = false;
this.send = function(msg) {
    queue[queue.length] = msg;
    if (busy) return;
    busy=true;
    var s = function() {
        var m = queue.shift();
        $.ajax({
            type:"POST", async:true, cache:false, timeout: 5000,
            data: {userid:userid, msg:m},
            error: function(xhr, textStatus, errorThrown){
                _errCallback(textStatus + " (" + errorThrown + ")");
                if (queue.length>0) s(); else busy = false;
            },
            success: function(){
                if (queue.length>0) s(); else busy = false;
            }
        });
    }
    s();
};

Two things to note. First, there's a fair bit of lag if you're sending many messages and the queue is filling up. It's better to find a way to send the entire queue each time, rather than piece by piece. One way to do this is to convert the messages into a JSON array, and decode on the server.

Second, if there's an error sending the message, then you've lost the message. There needs to be a bit of code that will either push the failed message back onto the queue, or not remove it until there's success.

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