gpt4 book ai didi

php - Laravel 5 : Use Server-Sent Events to push messages to browser

转载 作者:行者123 更新时间:2023-12-01 00:53:56 25 4
gpt4 key购买 nike

我看过 This SO questionThis article尝试在 Laravel 5 中实现服务器发送的事件。虽然,在两者之间,我无法弄清楚如何根据事件将更新推送到客户端。在这种情况下,事件是抛出的 ClientException。我的应用程序中的 ClientException 是由用户出错引起的。当一个被抛出时,我想将更新推送到填充通用错误面板的客户端。

这是我的 Blade :

<script>
var source = new EventSource("{{ route('globalmessages') }}");
source.addEventListener("message", function(e)
{
$("#errors").html(e);
}, false);
</script>

<div id="errors">
</div>

EventSource 成功命中 Controller Action :
public function pushErrors()
{
$response = new StreamedResponse(function()
{
$errors = ???; // How do I populate this
if (!empty($error))
{
echo $error;
ob_flush();
flush();
}
else
{
\Log::info("No errors to push");
}
});

$response->headers->set('Content-Type', 'text/event-stream');
return $response;
}

错误处理发生在 Handler.php@render 中:
if ($e instanceof ClientException)
{
$message = $e->getMessage(); // Need to send this to client
return \Response::json([]);
}
else
{
return parent::render($request, $e);
}

所以,我需要做的是以某种方式将错误提供给 Controller 路由。我尝试使用单例,但我无法让它发挥作用。我试着给 Controller 一个字段来保存它,但它总是空的。

最重要的是,这个当前的实现似乎每 5 秒运行一次。我希望能够在抛出 ClientException 以推送更新时调用函数。

谢谢你的帮助。

编辑:

更多信息:

这是呈现我的页面的 Controller 操作:
class HomeController
{
public function getHome()
{
return view('home');
}
}

我的 Controller 使用无限循环:
class MainController extends RouteController
{
public function pushErrors()
{
$response = new StreamedResponse();
$response->headers->set('Content-Type', 'text/event-stream');
$response->headers->set('Cach-Control', 'no-cache');

$response->setCallback(
function()
{
while (true)
{
$error = MessageQueue::dequeue();
if (!empty($error))
{
echo 'data: ' . $error. "\n\n";
ob_flush();
flush();
}
sleep(1);
}
});

return $response;
}
}

如果我取出 while 循环,则此代码有效,因为消息被推送,连接断开,然后重新建立并再次推送。使用 while 循环,页面就会挂起。

我的路线:
+--------+----------+----------------+----------------+--------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------------+----------------+--------------------------------------------------+------------+
| | GET|HEAD | globalmessages | globalmessages | App\Http\Controllers\MainController@pushErrors | |
| | GET|HEAD | / | / | App\Http\Controllers\HomeController@getHome | |
| | POST | login | login | App\Http\Controllers\HomeController@postLogin | |
+--------+----------+----------------+----------------+--------------------------------------------------+------------+

HomeController@postLogin 是我调用的生成 ClientException 的路由。

最佳答案

您的 Controller 缺少文章中的关键功能。在文章中, Controller 在做一个无限循环。在无限循环中,检查数据的相似性,如果数据发生变化,则刷新并写入缓冲区,以便客户端 JS 可以读取它。

我将如何实现这是创建一个包含所有 ServerSentEvents 的表,然后在我的 Controller 查询中从该表中检索尚未发送的行。

在这个例子中,我们将检查我们的 $data 中是否有任何数据。数组,如果有,则将其发送给客户端。

DB::table('ServerSentEvents')->where('sent', 0)->get();

如果没有从查询返回的行,将返回一个空数组。
public function pushErrors() {

$response = new Symfony\Component\HttpFoundation\StreamedResponse(function() {

$data = $this->getData();

while (true) {
if (!empty($data)) {
echo 'data: ' . json_encode($data) . "\n\n";
ob_flush();
flush();

/* update the table rows as sent */
$ids = [];
foreach($data as $event){
$ids[] = $event->id;
}
DB::table('ServerSentEvents')->whereIn('id', $ids)->update('sent', 1);
}

//sleep for 3 seconds
sleep(3);

//requery for new events that need to be sent
$data = $this->getData();
}

});

$response->headers->set('Content-Type', 'text/event-stream');
return $response;
}

public function getData(){
$data = DB::table('ServerSentEvents')->where('sent', 0)->get();
return $data;
}

您还需要在发生 ClientException 时向数据库中插入新行:
if ($e instanceof ClientException)
{
DB::table('ServerSentEvents')->insert(['message' => $e->getMessage(), 'sent' => 0]);
}
else
{
return parent::render($request, $e);
}

根据您基于事件所需的信息类型,您可能需要向 ServerSentEvents 表添加或删除更多列。

ServerSentEvents 表是您需要创建的表,我在这里没有提供结构,因为您可能希望在行中保存更多信息,而从数据库中提取数据的总体概念是重点。

关于php - Laravel 5 : Use Server-Sent Events to push messages to browser,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29541775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com