简体   繁体   English

HTTP / 2:stream.end使用For-Loop

[英]HTTP/2: stream.end using For-Loop

How can a stream be closed within a for-loop ? 如何在for-loop关闭流?

I am attempting a HTTP/2 resource push-stream within a loop by reading a .json config file. 我通过读取.json配置文件在循环中尝试HTTP / 2资源push-stream If there is only one resource in the resurce.file,type , the push is successful. 如果resurce.file,type只有一个资源resurce.file,type ,推送成功。 If there are more than one resource in the config, only the first resource listed is pushed and the remaining resource(s) are not pushed & the client never receives the remaining files and will not finish parsing. 如果配置中有多个资源,则仅推送列出的第一个资源,并且不推送其余资源,客户端永远不会接收剩余文件,也不会完成解析。

I am thinking that only the first resource stream ends and the remaining open streams are not closing. 我想只有第一个资源流结束,剩下的开放流没有关闭。

I commented as best as I believe the code should be functioning: 我最好评论代码应该正常运行:

// 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: .config.json5:

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

Using the example above; 使用上面的例子;

If the /js/theme.min.js is listed first and the /css/theme.min.css is listed second in the config , the /js/theme.min.js will be loaded by the browser and the other file will not load and the client hangs up ( doesn't continue parsing ). 如果/js/theme.min.js列出/css/theme.min.css并且在配置中第二个列出/js/theme.min.js ,则浏览器将加载/js/theme.min.js ,而另一个文件将不加载,客户端挂起( 不继续解析 )。 If the the list order of the resources are swapped, the same thing occurs. 如果交换资源的列表顺序,则会发生相同的事情。 If there is only one file listed in the config, everything works as expected. 如果配置中只列出了一个文件,则一切都按预期工作。

Any help will be greatly appreciated. 任何帮助将不胜感激。

The problem is in config.json5 . 问题出在config.json5 You are checking the requested url before passing the files here: 您在传递文件之前检查所请求的URL:

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

But in your json only one item can pass the test, the other one is missing the url property. 但是在你的json中只有一个项目可以通过测试,另一个项目缺少url属性。 Change your config to this (added url: '/' to the first item) and it will work: 将您的配置更改为此(将url: '/'添加到第一个项目),它将起作用:

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

Tested with this small app, following the http2 server example , and also with your server code. 使用这个小应用程序进行测试,遵循http2服务器示例 ,以及您的服务器代码。

server.js 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);

The config.json file contains the corrected config described above. config.json文件包含上述更正的配置。

Output : 输出

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM