node.js實現的Long Polling例子

前臺頁面使用jquery的jsonp來進行輪詢。後端node.js監聽的端口是8124

index.html

<!Doctype html>
<html>
<head>
<title>Long Polling in node.js</title>
<meta http-equiv='content-type' content='text/html; charset=utf-8'>
<style type='text/css'>
* {margin:0; padding:0;}
body {background-color:#fff;}

#infoContainer{margin:40px; padding:10px; font-size:14px; border:1px solid #eee;}
</style>
</head>
<body>

<div id='infoContainer'>loading...</div>

<script type='text/javascript' src='js/jquery.js'></script>   1:     2:     3: <script type='text/javascript'>   4:     5: function callPolling() {   6:     $.ajax({   7:         url: 'http://localhost:8124/?callback=pollingCallback',   8:         dataType : 'jsonp',   9:         jsonp : 'kk',  10:         timeout : 70 * 1000,  11:         complete : function() {  12:             callPolling();  13:         }  14:     })  15: }  16:    17: function pollingCallback(str) {  18:     $("#infoContainer").html(str);  19: }  20:    21: $(callPolling);  22:  </script>

</body>
</html>

後臺用node.js實現的polling.js

var http = require('http'),    fs = require('fs'); http.createServer(function(req, res) {    checkFile(req, res);}).listen(8124); var filepath = 'E:/Node_app/file/a.txt'; function checkFile(req, res) {    var reqUrl = req.url;    var callbackFnName = null;     if (/callback=([^&]+)/.test(reqUrl)) {        callbackFnName = RegExp['$1'];    }     var date = new Date();     if (date - req.socket._idleStart.getTime() > 60 * 1000) {        res.writeHead(200, {            'Content-Type' : 'text/plain',            'Access-Control-Allow-Origin' : '*'        });         res.write(callbackFnName + "('ok')", 'utf8');        res.end();    }         fs.stat(filepath, function(err, stats) {        if (err) {            res.writeHead(200, {                'Content-Type' : 'text/plain',                'Access-Control-Allow-Origin' : '*'            });             res.write(callbackFnName + "('Error')", 'utf8');            res.end();             return false;        }         //文件是在請求過來之後發生更改的        if (stats.mtime.getTime() > req.socket._idleStart.getTime()) {            fs.readFile(filepath, 'utf8', function(err, data) {                res.writeHead(200, {                    'Content-Type' : 'text/plain',                    'Access-Control-Allow-Origin' : '*'                });                 res.write(callbackFnName + "('" + data + "')", 'utf8');                res.end();                 return false;            });        }    });        setTimeout(function() {        checkFile(req, res);            }, 10 * 1000);} /** * 時間對象的格式化; */Date.prototype.format = function (format) {    /*     * eg:format="YYYY-MM-dd hh:mm:ss";     */    var o = {        "M+": this.getMonth() + 1, //month        "d+": this.getDate(), //day        "h+": this.getHours(), //hour        "m+": this.getMinutes(), //minute        "s+": this.getSeconds(), //second        "q+": Math.floor((this.getMonth() + 3) / 3), //quarter        "S": this.getMilliseconds() //millisecond    }     if (/(Y+)/i.test(format)) {        format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));    }     for (var k in o) {        if (new RegExp("(" + k + ")").test(format)) {            format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));        }    }    return format;} setInterval(function() {    fs.writeFileSync(filepath, '當前時間:' + new Date().format('YYYY-MM-dd hh:mm:ss'), 'utf8');    }, 1000 * 1);

監聽文件發生改變,就立即輸出內容給前臺頁面請求。

這裏有關於文件atime、ctime、mtime三者區別的詳細介紹>>

關於File的元信息,可以參考這裏(stat詳解)>>

在控制檯上打印出的req信息

{    socket: {        _handle: {            writeQueueSize: 0,            owner: [Circular],            onread: [Function: onread]        },        _pendingWriteReqs: 0,        _flags: 0,        _connectQueueSize: 0,        destroyed: false,        errorEmitted: false,        bytesRead: 602,        _bytesDispatched: 0,        allowHalfOpen: true,        writable: true,        readable: true,        _paused: false,        server: {            _connections: 1,            connections: [Getter / Setter],            allowHalfOpen: true,            _handle: [Object],            _events: [Object],            httpAllowHalfOpen: false,            _connectionKey: '4:0.0.0.0:8124'        },        _events: {            drain: [Function: ondrain],            timeout: [Object],            error: [Function],            close: [Object]        },        _idleTimeout: 120000,        _idleNext: {            _idleNext: [Circular],            _idlePrev: [Circular],            ontimeout: [Function]        },        _idlePrev: {            _idleNext: [Circular],            _idlePrev: [Circular],            ontimeout: [Function]        },        _idleStart: Tue Jul 24 2012 01: 18: 39 GMT + 0800(中國標準時間),        parser: {            _headers: [],            _url: '',            onHeaders: [Function: parserOnHeaders],            onHeadersComplete: [Function: parserOnHeadersComplete],            onBody: [Function: parserOnBody],            onMessageComplete: [Function: parserOnMessageComplete],            socket: [Circular],            incoming: [Circular],            maxHeaderPairs: 2000,            onIncoming: [Function]        },        ondata: [Function],        onend: [Function],        _httpMessage: {            output: [],            outputEncodings: [],            writable: true,            _last: false,            chunkedEncoding: false,            shouldKeepAlive: true,            useChunkedEncodingByDefault: true,            sendDate: true,            _hasBody: true,            _trailer: '',            finished: false,            socket: [Circular],            connection: [Circular],            _events: [Object]        }    },    connection: {        _handle: {            writeQueueSize: 0,            owner: [Circular],            onread: [Function: onread]        },        _pendingWriteReqs: 0,        _flags: 0,        _connectQueueSize: 0,        destroyed: false,        errorEmitted: false,        bytesRead: 602,        _bytesDispatched: 0,        allowHalfOpen: true,        writable: true,        readable: true,        _paused: false,        server: {            _connections: 1,            connections: [Getter / Setter],            allowHalfOpen: true,            _handle: [Object],            _events: [Object],            httpAllowHalfOpen: false,            _connectionKey: '4:0.0.0.0:8124'        },        _events: {            drain: [Function: ondrain],            timeout: [Object],            error: [Function],            close: [Object]        },        _idleTimeout: 120000,        _idleNext: {            _idleNext: [Circular],            _idlePrev: [Circular],            ontimeout: [Function]        },        _idlePrev: {            _idleNext: [Circular],            _idlePrev: [Circular],            ontimeout: [Function]        },        _idleStart: Tue Jul 24 2012 01: 18: 39 GMT + 0800(中國標準時間),        parser: {            _headers: [],            _url: '',            onHeaders: [Function: parserOnHeaders],            onHeadersComplete: [Function: parserOnHeadersComplete],            onBody: [Function: parserOnBody],            onMessageComplete: [Function: parserOnMessageComplete],            socket: [Circular],            incoming: [Circular],            maxHeaderPairs: 2000,            onIncoming: [Function]        },        ondata: [Function],        onend: [Function],        _httpMessage: {            output: [],            outputEncodings: [],            writable: true,            _last: false,            chunkedEncoding: false,            shouldKeepAlive: true,            useChunkedEncodingByDefault: true,            sendDate: true,            _hasBody: true,            _trailer: '',            finished: false,            socket: [Circular],            connection: [Circular],            _events: [Object]        }    },    httpVersion: '1.1',    complete: true,    headers: {        accept: 'image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*',        'accept-language': 'zh-cn',        'user-agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6; QQDownload 715; .NET CLR 2.0.50727; CIBA; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)',        'accept-encoding': 'gzip, deflate',        host: 'localhost:8124',        connection: 'Keep-Alive'    },    trailers: {},    readable: false,    _paused: false,    _pendings: [],    _endEmitted: true,    url: '/?callback=abc&abc=1123',    method: 'GET',    statusCode: null,    client: {        _handle: {            writeQueueSize: 0,            owner: [Circular],            onread: [Function: onread]        },        _pendingWriteReqs: 0,        _flags: 0,        _connectQueueSize: 0,        destroyed: false,        errorEmitted: false,        bytesRead: 602,        _bytesDispatched: 0,        allowHalfOpen: true,        writable: true,        readable: true,        _paused: false,        server: {            _connections: 1,            connections: [Getter / Setter],            allowHalfOpen: true,            _handle: [Object],            _events: [Object],            httpAllowHalfOpen: false,            _connectionKey: '4:0.0.0.0:8124'        },        _events: {            drain: [Function: ondrain],            timeout: [Object],            error: [Function],            close: [Object]        },        _idleTimeout: 120000,        _idleNext: {            _idleNext: [Circular],            _idlePrev: [Circular],            ontimeout: [Function]        },        _idlePrev: {            _idleNext: [Circular],            _idlePrev: [Circular],            ontimeout: [Function]        },        _idleStart: Tue Jul 24 2012 01: 18: 39 GMT + 0800(中國標準時間),        parser: {            _headers: [],            _url: '',            onHeaders: [Function: parserOnHeaders],            onHeadersComplete: [Function: parserOnHeadersComplete],            onBody: [Function: parserOnBody],            onMessageComplete: [Function: parserOnMessageComplete],            socket: [Circular],            incoming: [Circular],            maxHeaderPairs: 2000,            onIncoming: [Function]        },        ondata: [Function],        onend: [Function],        _httpMessage: {            output: [],            outputEncodings: [],            writable: true,            _last: false,            chunkedEncoding: false,            shouldKeepAlive: true,            useChunkedEncodingByDefault: true,            sendDate: true,            _hasBody: true,            _trailer: '',            finished: false,            socket: [Circular],            connection: [Circular],            _events: [Object]        }    },    httpVersionMajor: 1,    httpVersionMinor: 1,    upgrade: false}

參考:

1、Long Polling in node.js

2、Diving into Node.js – A Long Polling Example

3、Node.js File System 文件系統模塊

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章