最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Long polling with Node.js and ajax - Stack Overflow

programmeradmin0浏览0评论

I have following server code.

var http = require('http');
var mysql = require('mysql');
var querystring = require('request');
var util = require('util');
var url = require('url');

var singer_name;
var currentmodif, lastmodif;
var requests=[];
var response;

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'someone',
  password : 'xxxxxxx',
  database : 'rest',  //mysql database to work with (optional)
});
connection.connect(); //connect to mysql

connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
  if (err) throw err;

  singer_name=rows[0].singer_name;
  currentmodif=rows[0].time_added;
});


http.createServer(function (req, res) {
    console.log('request received');

    requests.push({
        response: res,
        timestamp: new Date().getTime()
    });

    if(req.method=='GET'){
        var url_parts = url.parse(req.url,true);
        lastmodif = url_parts.query.timestamp;
    }

    //check_update(req, res);

}).listen(9000);


setInterval(function() {

    var expiration = new Date().getTime() - 30000;

    for (var i = requests.length - 1; i >= 0; i--) {
        //console.log("Request timestamp: "+requests[i].timestamp+" Expiration : "+expiration);
        response = requests[i].response;
        if (requests[i].timestamp < expiration) {
            console.log("The condition is met");
            response.writeHead(200, {
            'Content-Type'   : 'text/plain',
            'Access-Control-Allow-Origin' : '*'
            });

            // return response
            response.write('_testcb(\'ok\')', 'utf8');
            response.end();
            //break;
        }
    }

    connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
        if (err) throw err;
        currentmodif=rows[0].time_added;        
            //console.log("currentmodif: "+currentmodif+" lastmodif: "+lastmodif);
        if (currentmodif > lastmodif){
            singer_name=rows[0].singer_name; 
            var _arrays = {'singer_name': singer_name, 'time': currentmodif}
            var data = "_testcb"+"("+JSON.stringify(_arrays)+")";
            response.writeHead(200, {
            'Content-Type'   : 'text/plain',
            'Access-Control-Allow-Origin' : '*'
            });
            if (response.end(data))
            console.log("Response successfully sent");
            //return false;
        }

    });
}, 2000);

and Client code:

<html>
<head>
    <script src=".10.1.min.js"></script>
    <title>Node.js Ajax test</title>
</head>
<body>

</body>
<script>
var timestamp = "1380020402";
function callNode() {

var time = "1380020402";
    $.ajax({
        url: ':9000/',
        dataType: "jsonp",
        data: {"timestamp":timestamp},
        type: 'POST',
        jsonpCallback: "_testcb",
        cache: false,
        timeout: 35000,
        success: function(response, code, xhr) {
            if ('ok' == response) {
                callNode();
                return false;
            }

            console.log(response);

            timestamp = response.time;
            // make new call
            callNode();
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log('error ' + textStatus + " " + errorThrown);
        }
    });
}
$(function () {
    callNode();
});
</script>
</html>

I am trying to do a long polling. So until a data in database is updated, the response to ajax request should be paused but the above code is not working. I am making the ajax request from different domain and therefore using jsonp.

Exact problem is that currently when the data is changed in database the response doesn't get sent. It works every now and then but it is not consistently reliable.

Another problem is that the code block for time out is not working. If the request is 30 seconds old then a blank response should be sent in order to avoid the timeout from ajax.

If someone can help then I would appreciate.

Cheers.

I have following server code.

var http = require('http');
var mysql = require('mysql');
var querystring = require('request');
var util = require('util');
var url = require('url');

var singer_name;
var currentmodif, lastmodif;
var requests=[];
var response;

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'someone',
  password : 'xxxxxxx',
  database : 'rest',  //mysql database to work with (optional)
});
connection.connect(); //connect to mysql

connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
  if (err) throw err;

  singer_name=rows[0].singer_name;
  currentmodif=rows[0].time_added;
});


http.createServer(function (req, res) {
    console.log('request received');

    requests.push({
        response: res,
        timestamp: new Date().getTime()
    });

    if(req.method=='GET'){
        var url_parts = url.parse(req.url,true);
        lastmodif = url_parts.query.timestamp;
    }

    //check_update(req, res);

}).listen(9000);


setInterval(function() {

    var expiration = new Date().getTime() - 30000;

    for (var i = requests.length - 1; i >= 0; i--) {
        //console.log("Request timestamp: "+requests[i].timestamp+" Expiration : "+expiration);
        response = requests[i].response;
        if (requests[i].timestamp < expiration) {
            console.log("The condition is met");
            response.writeHead(200, {
            'Content-Type'   : 'text/plain',
            'Access-Control-Allow-Origin' : '*'
            });

            // return response
            response.write('_testcb(\'ok\')', 'utf8');
            response.end();
            //break;
        }
    }

    connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
        if (err) throw err;
        currentmodif=rows[0].time_added;        
            //console.log("currentmodif: "+currentmodif+" lastmodif: "+lastmodif);
        if (currentmodif > lastmodif){
            singer_name=rows[0].singer_name; 
            var _arrays = {'singer_name': singer_name, 'time': currentmodif}
            var data = "_testcb"+"("+JSON.stringify(_arrays)+")";
            response.writeHead(200, {
            'Content-Type'   : 'text/plain',
            'Access-Control-Allow-Origin' : '*'
            });
            if (response.end(data))
            console.log("Response successfully sent");
            //return false;
        }

    });
}, 2000);

and Client code:

<html>
<head>
    <script src="http://code.jquery./jquery-1.10.1.min.js"></script>
    <title>Node.js Ajax test</title>
</head>
<body>

</body>
<script>
var timestamp = "1380020402";
function callNode() {

var time = "1380020402";
    $.ajax({
        url: 'http://xx.xxx.xx.xxx:9000/',
        dataType: "jsonp",
        data: {"timestamp":timestamp},
        type: 'POST',
        jsonpCallback: "_testcb",
        cache: false,
        timeout: 35000,
        success: function(response, code, xhr) {
            if ('ok' == response) {
                callNode();
                return false;
            }

            console.log(response);

            timestamp = response.time;
            // make new call
            callNode();
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log('error ' + textStatus + " " + errorThrown);
        }
    });
}
$(function () {
    callNode();
});
</script>
</html>

I am trying to do a long polling. So until a data in database is updated, the response to ajax request should be paused but the above code is not working. I am making the ajax request from different domain and therefore using jsonp.

Exact problem is that currently when the data is changed in database the response doesn't get sent. It works every now and then but it is not consistently reliable.

Another problem is that the code block for time out is not working. If the request is 30 seconds old then a blank response should be sent in order to avoid the timeout from ajax.

If someone can help then I would appreciate.

Cheers.

Share Improve this question edited Sep 25, 2013 at 16:23 hexacyanide 91.8k31 gold badges166 silver badges162 bronze badges asked Sep 25, 2013 at 16:22 SahilSahil 1,9836 gold badges27 silver badges44 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

I have figured this out. Amended code that work is as below:

Client side:

<html>
<head>
    <script src="http://code.jquery./jquery-1.10.1.min.js"></script>
    <title>Node.js Ajax test</title>
</head>
<body>

</body>
<script>
var timestamp;
function callNode() {

    $.ajax({
        url: 'http://xx.xxx.xx.xxx:9000/',
        dataType: "jsonp",
        data: {"timestamp":timestamp},
        //type: 'POST', //don't need this with jsonp
        jsonpCallback: "_testcb",
        cache: false,
        timeout: 35000,
        success: function(response, code, xhr) {
            if ('ok' == response) {
                console.log(response);
                callNode();
                return false;
            }

            console.log(response);

            timestamp = response.time;
            // make new call
            callNode();
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log('error ' + textStatus + " " + errorThrown);
        }
    });
}
$(function () {
    setTimeout(callNode, 1); //call function with setTimeout in order to avoid ugly constant browser loading 
});
</script>
</html>

Server Side (server.js):

var http = require('http');
var mysql = require('mysql');
var util = require('util');
var url = require('url');

var singer_name, currentmodif, lastmodif, request, response, time_of_request;

//var requests=[];

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'someone',
  password : 'xxxxxx',
  database : 'rest',  //mysql database to work with (optional)
});
connection.connect(); //connect to mysql

connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
  if (err) throw err;

  singer_name=rows[0].singer_name;
  currentmodif=rows[0].time_added;
});


http.createServer(function (req, res) {
    request = req;
    response = res;
    time_of_request = new Date().getTime();
    console.log('request received');


    if(req.method=='GET'){
        var url_parts = url.parse(req.url,true);
        lastmodif = url_parts.query.timestamp;
    }

    req.on('error', function(e) {
        console.log('problem with request: ' + e.message);
    });

    //checkupdate();     

}).listen(9000);

var response;

function checkupdate() { 

    var expiration = new Date().getTime() - 30000;

    //for (var i = requests.length - 1; i >= 0; i--) {
        //console.log("Request timestamp: "+time_of_request+" Expiration : "+expiration);
        if (time_of_request < expiration) {
            console.log("The condition is met");
            // return response
            response.write('_testcb(\'ok\')', 'utf8');
            response.end();
        }
    //}

    connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
        if (err) throw err;
        currentmodif=rows[0].time_added;

        if (lastmodif == undefined)
            lastmodif = 0;

        console.log("currentmodif: "+currentmodif+" lastmodif: "+lastmodif);

        if (currentmodif > lastmodif){
            singer_name=rows[0].singer_name;  
            var _arrays = {'singer_name': singer_name, 'time': currentmodif} 
            var data = "_testcb"+"("+JSON.stringify(_arrays)+")";

            //response.writeHead(200, { 'content-type':'application/json',
                                    //'Access-Control-Allow-Origin' : '*'});
            //response.write(data); 
            response.end(data);
            console.log("Response successfully sent");
            //return false;
        }

    });
};

setInterval(checkupdate, 2000);

The problem was with the server side. The response object was not available (it was undefined) when server wanted to reply and therefore the response was not being sent. I may have overlooked the error in the node.js's console.

This is almost a plete example of long polling with node.js with MYSQL database. This script will wait for fresh data to bee available before replying to the ajax request. If fresh data (in MYSQL) is not available within 30 seconds of the request then a fake reply is made so that the request does not time out. There is a condition in ajax's success callback that re-initiates this ajax request when this demo response is received, therefore making this an infinite loop.

I have successfully tested code above and it seems to work fine. I ran the script and then updated the data in my database (mainly the time_added field) and this triggered a reply to my waiting ajax call with new data from node.js's server.

I hope this code helps someone out there.

Checkout tutorial here for further explanation: http://www.sahilsaid./blog/long-polling-node-js-mysql-database-ajax/

发布评论

评论列表(0)

  1. 暂无评论