1

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"?

Community
  • 1
  • 1
mk.
  • 11,360
  • 6
  • 40
  • 54
  • Doesn't that other question answer this one? – Bjorn Dec 08 '09 at 05:12
  • No - the answers there show how to do long polling to get data from the server, not how to send something *to* the server while long polling. Unless I missed something? – mk. Dec 08 '09 at 05:43

3 Answers3

1

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.

Moishe Lettvin
  • 8,462
  • 1
  • 26
  • 40
  • Long-polling might take 10 seconds or much more - that's a long time to wait to send something to the server. I assume some popular framework has already solved this - but how? (Right, 2 connections per server per tab. Since one is the poll, the second would be the to-server xhr, images, stylesheets, etc. These would get queued up.) – mk. Dec 08 '09 at 07:58
  • You need an async XHR. Then, while that's waiting to complete, you can make another (async or not, it's up to you) XHR to post data to the server. If the second XHR *is* async you'll need to implement some queuing so you don't lose messages that you want to post while the second XHR is in progress. – Moishe Lettvin Dec 08 '09 at 17:36
  • I don't think you lose messages if you send an asynch xhr beyond the 2-connection limit. Do you mean queuing on the server? – mk. Dec 10 '09 at 00:20
1

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.

Jerod Venema
  • 44,124
  • 5
  • 66
  • 109
1

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.

mk.
  • 11,360
  • 6
  • 40
  • 54