在 Symfony2 中流式传输期间接受请求
Accept requests during streaming in Symfony2
我的网站有问题。我尝试在我的网站上放一个视频流。这部分效果很好。我用这个主题来编写我的代码:Symfony2 video streaming.
我使用的是外部视频文件而不是本地文件,但它可以工作。
但是在视频没有为客户端完全加载之前,我无法发出任何请求(例如,post评论或转到另一个页面(即使该操作会中断流式传输转到另一页))。我尝试了 stream_context_create
函数,但我不明白它是如何工作的。
我不知道如何"delegate" 流和继续导航。
你能帮帮我吗,因为客户端在他的视频加载之前被阻止了。
我会将您的流式传输逻辑包装到 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;
}
}
更新数据库架构并确保 table 已创建:
app/console doctrine:schema:update --force
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 controllers/services 中创建任务:
$task = new \AppBundle\Entity\Task();
$em->persist($task);
$em->flush();
我发现了真正的问题:它在 FF 上运行良好,但在 Chrome 中,请求仍处于待处理状态。
我需要在我的请求中添加时间戳参数以强制Chrome重新下载页面
主题:HTML5 video element request stay pending forever (on chrome)
我的网站有问题。我尝试在我的网站上放一个视频流。这部分效果很好。我用这个主题来编写我的代码:Symfony2 video streaming.
我使用的是外部视频文件而不是本地文件,但它可以工作。
但是在视频没有为客户端完全加载之前,我无法发出任何请求(例如,post评论或转到另一个页面(即使该操作会中断流式传输转到另一页))。我尝试了 stream_context_create
函数,但我不明白它是如何工作的。
我不知道如何"delegate" 流和继续导航。
你能帮帮我吗,因为客户端在他的视频加载之前被阻止了。
我会将您的流式传输逻辑包装到 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;
}
}
更新数据库架构并确保 table 已创建:
app/console doctrine:schema:update --force
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 controllers/services 中创建任务:
$task = new \AppBundle\Entity\Task();
$em->persist($task);
$em->flush();
我发现了真正的问题:它在 FF 上运行良好,但在 Chrome 中,请求仍处于待处理状态。
我需要在我的请求中添加时间戳参数以强制Chrome重新下载页面
主题:HTML5 video element request stay pending forever (on chrome)