使用Laravel 4更新视图中的实时数据(如进度条)

时间:2013-08-20 20:23:59

标签: php ajax laravel laravel-4

TL; DR

  

我想将数据发送到视图中的实时更新,例如进度   栏显示行动的状态。   laravel 4中最好的方法是什么?


设置

我正在开发基于Laravel 4的项目,每个用户都可以兑换序列密钥。

我已经制作了一个管理员后端,我可以轻松地粘贴到一个键列表中,或上传一个文件。

假设$key_string是我上传的换行符的字符串,并且想要解析然后上传所包含的键字符串 - 这里是添加键的简化代码:

$key_string = rtrim($key_string);
$key_string = str_replace("\n\r", "\n", $key_string);
$keys = explode( "\n", $key_string);

foreach($keys as $index => $key) {
    Key::create(
        array( "serial" => trim($key) )
    );
}

由于我上传的数字组成千上万,这有时可能需要30秒,在此期间管理面板自然不会显示任何内容。

现在,我不介意花这个时间。我不需要优化上传以使用一个查询等,但我想得到一些实际的反馈,所以我知道上传已经走了多远。


问题

当我上传密钥时,我希望能够每隔几秒或百分比滴答在我的视图中更新进度条或计数器(使用当前$index

有一种简单的方法可以轻松地处理这种情况,最好是集成在Laravel 4中吗?我假设这会涉及ajax,但是有人能指出我正确的方向吗?

3 个答案:

答案 0 :(得分:7)

使用PHP,实际上有两种选择,无需使用Web套接字或推送设置。这不是Laravel的事情,它更像是一个请求JSON“事物”的AJAX循环。

短轮询

Olark将这种方法用于他们的聊天脚本。

setInterval(function() {
    $.getJSON("/path", function(data) {
        // update the view with your fresh data
    });
}, 5000);

长轮询

的Javascript

var eventName = function() {
    $.getJSON("/path", function(data) {
        // update the view with your fresh data
        if (data.progress < 100)
            eventName();
    });
};

控制器逻辑

我在用户上传CSV并等待其完成上传和处理时使用此功能。

// in your controller
$check = true;
while ($check) {
    // search database
    // compare values
    if ($newDataWasFound)
        $check = false;

    $progressFromAbove = 90;
}

return Response::json(array(
    'newData' => $array,
    'progress' => $progressFromAbove,
));

我使用Laravel 3对此进行了截屏,但Long Polling与PHP相关而非Laravel。 https://www.youtube.com/watch?v=LDgJF77jELo

<强>实施例

答案 1 :(得分:2)

您可以将其放入会话中并从其他链接获取。

$key_string = rtrim($key_string);
$key_string = str_replace("\n\r", "\n", $key_string);
$keys = explode( "\n", $key_string);

$count = 0;
foreach($keys as $key) {
  Key::create(
      array( "serial" => trim($key) )
  );
  $count++;
  if($count % 5== 0) Session::put('count',$count);
}


//route.php
Route::get('/count', function()
{
   if( Session::has('count'))
        return Session::get('count');
});

答案 2 :(得分:1)

无论您使用Laravel还是Core PHP进行编码,都应该尝试Server sent events。使用SSE很容易实现。

它基本上包括两部分: -

<强> 1。 Javascript API(客户端) - 您必须订阅一个事件流,创建一个EventSource对象并将其传递给您的流的URL,如下所示: -

if (!!window.EventSource) {
  var source = new EventSource('stream.php');
} else {
  // Result to xhr polling :(
}

然后为消息事件设置处理程序。你可以选择听取开放和错误: -

source.addEventListener('message', function(e) {
  console.log(e.data);
}, false);

source.addEventListener('open', function(e) {
  // Connection was opened.
}, false);

source.addEventListener('error', function(e) {
  if (e.readyState == EventSource.CLOSED) {
    // Connection was closed.
  }
}, false);

<强> 2。 PHP(服务器端) - 您必须发送Content-Type: text/event-stream标头,然后在处理时按预定义格式推送响应: -

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // recommended to prevent caching of event data.

/**
 * Constructs the SSE data format and flushes that data to the client.
 *
 * @param string $id Timestamp/id of this connection.
 * @param string $msg Line of text that should be transmitted.
 */
function sendMsg($id, $msg) {
  echo "id: $id" . PHP_EOL;
  echo "data: $msg" . PHP_EOL;
  echo PHP_EOL;
  ob_flush();
  flush();
}

$serverTime = time();

sendMsg($serverTime, 'server time: ' . date("h:i:s", time()));

所有这些片段均来自上述链接,建议进行彻底的研究,以便清楚地理解。

干杯