【问题标题】:Accept requests during streaming in Symfony2在 Symfony2 流式传输期间接受请求
【发布时间】:2015-10-08 06:47:07
【问题描述】:

我的网站有问题。我尝试在我的网站上放置视频流。这部分效果很好。我使用这个主题来制作我的代码:Symfony2 video streaming.

我使用的是外部视频文件而不是本地文件,但它可以工作。

但是在没有为客户端完全加载视频之前,我无法提出任何请求(例如,发表评论或转到另一个页面(即使该操作会中断流式传输以转到另一个页面) )。我尝试了stream_context_create 函数,但我不明白它是如何工作的。

我不知道如何“委托”流式传输并继续导航。

你能帮帮我吗,因为客户端在加载视频之前被阻止。

【问题讨论】:

    标签: php apache symfony stream streaming


    【解决方案1】:

    我会将您的流式处理逻辑包装到 Symfony 控制台命令中,并使用 upstart 或 bash 脚本启动守护程序。您可以使用 Redis 或 Mysql 中的任务与守护进程交互。

    UPD:在 AppBundle/Entity 文件夹中创建任务实体:

    <?php
    namespace AppBundle\Entity;
    use Doctrine\ORM\Mapping as ORM;
    /**
     * @ORM\Entity
     * @ORM\Table
     */
    class Task
    {   
        /**
         * @ORM\Id
         * @ORM\Column(type="bigint")
         * @ORM\GeneratedValue(strategy="AUTO")
         * @var int
         */
        private $id;    
        /**
         * @ORM\Column(type="text")
         * @var string
         */
        private $fileName;
        /**
         * @var boolean
         * @ORM\Column(type="string", length=50)
         */
        protected $status = 'new';
        /**
         * @return integer
         */
        public function getId()
        {
            return $this->id;
        }
        /**
         * @param string $status
         */
        public function setStatus($status)
        {
            $this->status = $status;
        }
        /**
         * @return string
         */
        public function setStatus($status)
        {
            return $this->status;
        }
    }
    

    更新数据库架构并确保已创建表:

    app/console doctrine:schema:update --force
    

    创建Symfony Command

    namespace AppBundle\Command;
    
    use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
    use Symfony\Component\Console\Input\InputArgument;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class VideoDaemonCommand extends ContainerAwareCommand
    {
        protected function configure()
        {
            $this->setName('app:video-daemon');
        }
    
        /** @var EntityManager */
        private $em;
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
            while (true) {
                $task = $this->em->getRepository('AppBundle:Task')->findOneBy(['status' => 'new']);
                if (is_null($task)) {
                    sleep(5);
                    continue;
                }
                $this->setTaskStatus('processing', $task);
                $this->processTask($task);
            }
        }
    
        private function processTask($task) {
            //here do streaming logic
            $this->setTaskStatus('completed', $task);
        }
    
        private function setTaskStatus($status, $task) {
            $task->setStatus($status);
            $this->em->persist($task);
            $this->em->flush();
        }
    }
    

    让我们用 upstart(debian/ubuntu) 创建一个守护进程。将以下内容放入/etc/init/video-daemon.conf并重启电脑。

    start on filesystem or runlevel [2345]
    stop on runlevel [!2345]
    
    ### Keep the process alive, limit to 5 restarts in 60s
    
      respawn
      respawn limit 5 60
    
    ### Start daemon
    
    script
      exec /path/to/your/project/app/console app:video-daemon
    end script
    

    检查守护进程是否工作:

    ps -aux | grep video-daemon
    

    现在,如果一切顺利,您可以通过以下方式在 Symfony 控制器/服务中创建任务:

    $task = new \AppBundle\Entity\Task();
    $em->persist($task);
    $em->flush();
    

    【讨论】:

    • 您好,感谢您的回答。您有任何示例或链接可以帮助我吗?我是 symfony 的一个小新手,我不知道如何与控制台交互,并且守护程序任务可以通过 mysql 响应客户端?
    • 谢谢,我现在可以创建任务并执行它们,但我还有一个问题,命令如何将内容返回给我的客户?因为控制器只会创建任务。从我的树枝上,我需要一个渲染控制器吗?为我的应答器
    • 您可以在一分钟内对服务器执行 1-2 次 ajax 请求 (/check-task/{task_id}) 以检查任务是否准备就绪。如果准备好了,您可以提出视频请求并将内容返回给您的客户。如果您认为正确,请接受我的回答。谢谢!
    • 我接受了你的回答,因为它对我帮助很大。但如果我提出视频请求,我的问题会不会一样? : 在没有下载内容之前,我不能提出另一个请求。并且视频会在内存中收费,所以如果很多客户想加载视频,我认为我的服务器不支持大文件。
    • 视频流不在 nginx 下执行,因此不会影响您的请求。 Parallels 请求在 nginx 中运行良好,不用担心。使用额外的服务器来处理任务和交付视频内容。
    【解决方案2】:

    我发现了真正的问题:它在 FF 上运行良好,但在 Chrome 中,请求仍处于待处理状态。

    我需要在我的请求中添加时间戳参数以强制 Chrome 重新下载页面

    主题:HTML5 video element request stay pending forever (on chrome)

    【讨论】:

      猜你喜欢
      • 2012-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-08
      • 2013-03-11
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多