HTTP Streaming - широковещательная рассылка, ожидающая n клиентов - PullRequest
0 голосов
/ 31 октября 2018

Я хочу передать файл через nodejs нескольким клиентам. Допустим, я хочу, чтобы 5 клиентов подключились к серверу, а затем сервер "транслировал" видеоконтент.

Мой код слишком потоковый файл:

const express = require("express");
const fs = require("fs");


const app = express();
app.listen(8081);

app.get('/video', function (req, res) {


  const path = './video.webm';
  const stat = fs.statSync(path);
  const fileSize = stat.size;
  const range = req.headers.range;

  if (range) {

    const parts = range.replace(/bytes=/, "").split("-");
    const start = parseInt(parts[0], 10);
    const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
    const chunksize = (end - start) + 1;
    const file = fs.createReadStream(path, {start, end});

    const head = {
      'Content-Range': "bytes ${start}-${end}/${fileSize}",
      'Accept-Ranges': 'bytes',
      'Content-Length': chunksize,
      'Content-Type': 'video/webm'
    };


    res.writeHead(206, head);
    file.pipe(res);

  } else {

    const head = {
      'Content-Length': fileSize,
      'Content-Type': 'video/webm'
    };

    res.writeHead(200, head);
    fs.createReadStream(path).pipe(res)

  }
});

Отлично работает, но код "подожди 5 клиентов" отсутствует.

Я не знаю, как мне это заархивировать. Основная проблема: как я скажу клиенту, что в будущем будет контент, и он не закроет соединение?

Вот что я попробовал (работает не так, как я хочу, только последний клиент получает контент):

var counter = 0;

app.get('/video', function (req, res) {
  
  counter++;

  const path = './video.webm';
  const stat = fs.statSync(path);
  const fileSize = stat.size;
  const range = req.headers.range;

  const head = {
    'Content-Length': fileSize,
    'Content-Type': 'video/webm'
  };

  res.writeHead(200, head);
  
  
  const wait = setInterval(function () {
    res.write("");
  }, 1000);
  
  if(counter === 2){
    
    clearInterval(wait);
    fs.createReadStream(path).pipe(res);
    
  }


});

Является ли "setInterval" neccessery?

Спасибо за любые идеи и советы

РЕДАКТИРОВАТЬ: Это то, что я хочу, но это не совсем "настоящее" время. Поток работает на всех клиентах, но имеет небольшую задержку. Есть ли способ слишком синхронизировать потоки?

var counter = 0;
var requests = [];

app.get('/video', function (req, res) {
  
  counter++;

  const path = './video.webm';
  const stat = fs.statSync(path);
  const fileSize = stat.size;
  const range = req.headers.range;

  const head = {
    'Content-Length': fileSize,
    'Content-Type': 'video/webm'
  };

  res.writeHead(200, head);
  requests.push(res);
  
  
  const wait = setInterval(function () {
    res.write("");
  }, 1000);
  
  if(counter === 2){
    
    clearInterval(wait);
    const stream = fs.createReadStream(path);
    
    stream.on("error", function(err){
      console.log(">>", err);
    });
    
    requests.forEach(function(client){
      stream.pipe(client);
    });
    
    
    
  }

});
...