前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Node.js实现的BigPipe

Node.js实现的BigPipe

作者头像
meteoric
发布2018-11-16 17:29:16
7870
发布2018-11-16 17:29:16
举报
文章被收录于专栏:游戏杂谈游戏杂谈

以前用PHP实现过,详情点击这里查看《Nginx中的PHP的缓冲问题》

无论用java、.net还是python都是可以实现bigpipe的…

拿那篇文章中的php显示页做示例:

先输出页面的主体结构:

然后按顺序更新页面的内容:

2s后输出header

4s后输出content

6s后输出footer

从加载到显示共消耗约13s (2 + 4 + 6 + 1 ~= 13s),符合预期结果

这个示例的源码(可复制至本地直接运行):

代码语言:javascript
复制
/**
 * Created with JetBrains WebStorm.
 * User: Meteoric_cry
 * Date: 13-4-13
 * Time: 上午11:10
 * To change this template use File | Settings | File Templates.
 */

var http = require('http');

var server = http.createServer(function(req, res) {

    res.writeHead(200, {
       'Content-Type' : 'text/html',
        'Transfer-Encoding' : 'chunked'
    });

    res.write([
        '<!DOCTYPE html>',
        '<html>',
        '<head>',
        '<meta charset="utf-8">',
        '<title>Node.js Bigpipe Demo</title>',
        '<style type="text/css">',
        ' * {margin: 0; padding:0;}',
        ' body {background-color:#fff;}',
        ' div{border:2px solid #4F81BD; margin:30px; padding: 10px;}',
        ' p {word-wrap:break-wrod; word-break:break-all; color: #666;}',
        ' .red {color: #f00;}',
        ' .blue {color:blue;}',
        ' .green {color:green;}',
        '</style>',
        '<script>',
        'var g_startTime = new Date();',
        'var g_renderArr = []',
        'function render(nodeID,html){',
        '   g_renderArr.push(new Date())',
        '    document.getElementById(nodeID).innerHTML=html;',
        '}',
        '</script>',
        '</head>',
        '<body>',
        '<div id="header"><p>Loading...</p></div>',
        '<div id="content"><p>Loading...</p></div>',
        '<div id="footer"><p>Loading...</p></div>'
    ].join('\r\n'));

    function out_header() {
        res.write("<script type='text/javascript'>render('header', '<p><span class=\"blue\">111111</span></p>');</script>\r\n");

        setTimeout(out_content, 4 * 1000);
    }

    function out_content() {
        res.write("<script type='text/javascript'>render('content', '<p><span class=\"red\">222222</span></p>');</script>\r\n");

        setTimeout(out_footer, 6 * 1000);
    }

    function out_footer() {
        res.write("<script type='text/javascript'>render('footer', '<p><span class=\"green\">333333</span></p>');</script>\r\n");

        setTimeout(out_end, 1 * 1000);
    }

    function out_end() {

        res.write([
            '<script>',
            'var str = [',
            '    "start:" + g_startTime.toGMTString(),',
            '    "header:" + g_renderArr[0].toGMTString() + "-" + (g_renderArr[0] - g_startTime) / 1000,',
            '    "content:" + g_renderArr[1].toGMTString() + "-" + (g_renderArr[1] - g_renderArr[0]) / 1000,',
            '    "footer:" + g_renderArr[2].toGMTString() + "-" + (g_renderArr[2] - g_renderArr[1]) / 1000,',
            '    "end:" + new Date().toGMTString() + "-" + (new Date() - g_renderArr[2]) / 1000 + "-" + (new Date() - g_startTime) / 1000',
            '].join("\\n");',
            'alert(str);',
            '</script>'
        ].join(''));

        res.end("\r\n</body></html>");
    }

    setTimeout(out_header, 2 * 1000);


}).listen(3002);

上面是将界面的显示顺序固定写死了,下面将展示一个灵活的动态界面:

先输出6个内容容器,然后构建6个客户端请求,当收到请求数据时直接返回给客户端。如果你需要让界面的内容按顺序显示,只需要修改,返回的delay值,比如按索引值的大小进行修改

代码语言:javascript
复制
1: var params = url.parse(request.url, true);

       2: var delay = params.query.id * 3000; console.log(delay);

这个示例的完整源码:

代码语言:javascript
复制
/**
 * Created with JetBrains WebStorm.
 * User: zhangyi
 * Date: 13-4-23
 * Time: 上午10:57
 * To change this template use File | Settings | File Templates.
 */
var http = require('http');
var sys = require('sys');
var url = require("url");

http.createServer(function(request, response) {

    response.writeHead(200, {"Content-Type" : "text/html"});
    response.write("<!Doctype html><html><head>");
    response.write("<style type='text/css'>div{border:2px solid #4F81BD; margin:30px; padding: 10px;}</style>");
    response.write("<script type=\"text/javascript\">function arrived(id,text) { var b=document.getElementById(id); b.innerHTML = text; }</script>");
    response.write("</head><body><div>Progressive Loading");
    for(var i = 0; i < 6; i++) {
        response.write("<div id='" + i + "'>Loading...</div>");
    }
    response.write("</div>");


    var down = 6;
    for (i = 0; i < 6; i++) {
        var proxy = http.createClient(2000, "localhost");
        var proxyRequest = proxy.request("GET", "/?id=" + i, {"host" : "localhost"});

        proxyRequest.addListener('response', function (proxyResponse) {
            --down;
            proxyResponse.addListener('data', function(chunk) {
                response.write(chunk, 'binary');
            });
            proxyResponse.addListener('end', function() {
                if(down == 0) {
                    response.end();
                }
            });
        });
        proxyRequest.end();
    }
    response.write("</body></html>");

}).listen(8080);

http.createServer(function(request, response) {

    var delay = Math.round(Math.random() * 8000);
    /*
    var params = url.parse(request.url, true);
    var delay = params.query.id * 3000; console.log(delay);
    */
    setTimeout(function() {
        var params = url.parse(request.url, true);
        var id = params.query.id;
        response.writeHead(200, {"Content-Type" : "text/html"});
        var content = "<span>Content of Module " + id + "</span>";
        response.write("<script>" +
            "arrived('" + id + "', '" + content + "');" +
            "</script>");
        response.end();
    }, delay);
}).listen(2000);

上面的示例中并没有像第一个例子一样,显示输出header信息('Transfer-Encoding' : 'chunked'),而浏览器,在response里却看到了,猜测是node.js在输出的时候内部加上去的。

相比php,node.js内部实现并没有“缓冲池”的功能,都是直接输出,很简单吧…

本文参考:

node.js搭建bigpipe demo时碰到的雷

BigPipe Done in Node.js

bigpipe-node

BigPipe: Pipelining web pages for high performance

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013-04-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档