• 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 文件系统模块

  • 相关阅读:
    Python 基于Python实现的ssh兼sftp客户端(上)
    lintcode: 最长连续序列
    lintcode:颜色分类
    lintcode: 堆化
    lintcode: 旋转图像
    lintcode: 寻找旋转排序数组中的最小值
    lintcode: 跳跃游戏 II
    lintcode:最小差
    华为:数独填充
    华为:字符集合
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/2605847.html
Copyright © 2020-2023  润新知