【问题标题】:HTTP/2: stream.end using For-LoopHTTP/2:stream.end 使用 For-Loop
【发布时间】:2016-03-15 14:03:35
【问题描述】:

如何在for-loop 中关闭流?

我正在通过读取 .json 配置文件在循环中尝试 HTTP/2 资源 push-stream。如果resurce.file,type中只有一个资源,则推送成功。如果配置中有多个资源,则仅推送列出的第一个资源,而不推送其余资源,客户端永远不会收到剩余的文件,也不会完成解析。

我在想只有第一个资源流结束,其余打开的流没有关闭。

我认为代码应该可以正常运行,我的评论是最好的:

// Verify if client can be pushed to:
if (res.push) {

  // Read what resources should be pushed via config.json5:
  for(var i = 0; i < confg.resource.length; i++) {

    // Compare what URL requested the resources & pass the relevant files:
    if (req.url == confg.resource[i].url) {

      // Request the resource(s) to stream:
      var ps  = fs.readFileSync('../build' + confg.resource[i].file)

          // Push the relevant resource stream(s):
        , stream = res.push(confg.resource[i].file
        , { // ..and set the content type;
            res: {'content-type': confg.resource[i].type},
          });

      // Close the resource stream(s):
      stream.end(ps, function() {
        // TODO(CelticParser): Remove for production ->v
        console.log("Pushed Sream");
      });
    }
  }
}

.config.json5:

resource: [ // HTTP/2 Push-Streams
  { file: '/js/theme.min.js',
     type: 'script'
  },
  { file: '/css/theme.min.css',
    type: 'style',
    url:  '/'
  }
]

使用上面的例子;

如果/js/theme.min.js 在配置中列在第一位,/css/theme.min.css 在配置中列在第二位,则/js/theme.min.js 将由浏览器加载,而其他文件将不会加载,客户端会挂起( '不继续解析)。如果交换资源的列表顺序,也会发生同样的事情。如果配置中只列出一个文件,则一切正常。

任何帮助将不胜感激。

【问题讨论】:

  • 对不起,我不太明白这个问题。

标签: javascript for-loop stream http2


【解决方案1】:

问题出在config.json5。在此处传递文件之前,您正在检查请求的 url:

// Compare what URL requested the resources & pass the relevant files:
if (req.url == confg.resource[i].url) {
   ...
}

但是在您的 json 中只有一项可以通过测试,另一项缺少 url 属性。将您的配置更改为此(将url: '/' 添加到第一项),它将起作用:

{
   resource : [
      { 
         file : '/js/theme.min.js',
         type : 'script',
         url  :  '/'
      },
      { 
         file : '/css/theme.min.css',
         type : 'style',
         url  :  '/'
      }
   ]
}

http2 server example 之后使用这个小应用程序进行了测试,并且还使用了您的服务器代码。

server.js

var fs      = require("fs");
var path    = require("path");
var http2   = require("http2");
var config  = require("./config.json");

var options = {
    key  : fs.readFileSync("./localhost.key"),
    cert : fs.readFileSync("./localhost.crt")
};

//----------------------------------------------------
http2.createServer(options, function(req, res) {

    if (res.push) {

        config.resource.forEach(function(resource){

            if (req.url === resource.url) {

                var push = res.push(resource.file, { res: {"content-type": resource.type } });
                push.writeHead(200);
                fs.createReadStream(path.join("../build", resource.file)).pipe(push);
            }
        });
    }

    res.writeHead(200);
    res.end();

}).listen(8080);

config.json 文件包含上述更正的配置。

输出

Receiving pushed resource: ./js/bootstrap.min.js -> /Developer/so/tests/push-0
Receiving pushed resource: ./css/bootstrap.min.css -> /Developer/so/tests/push-1

【讨论】:

  • 哇!我怎么错过了??哈哈,谢谢!
  • 老实说,我也做过..我在注意到它之前构建了整个服务器和客户端:)
  • ..而且我什至将那个 json 块从default.json5 移到了theme.json5 并且没有看到它。 C&P 是个坏习惯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
  • 2014-01-11
  • 2018-11-29
  • 2017-07-23
  • 1970-01-01
相关资源
最近更新 更多