2

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 秒ほどかかる場合があり、その間、管理パネルには自然に何も表示されません。

さて、今回は時間がかかっても構いません。1 つのクエリを使用するようにアップロードを最適化する必要はありませんが、アップロードがどこまで進んだかを知るために、実際のフィードバックが必要です。


質問

キーをアップロードするとき、数秒またはパーセントティックごとにビューのプログレスバーまたはカウンターを更新できるようにしたいと考えています (現在の を使用$index)

できればLaravel 4に統合して、これを簡単に処理する方法はありますか? これにはajaxが関係していると思いますが、誰かが私を正しい方向に向けることができますか?

4

3 に答える 3

8

PHP には、Web ソケットまたはプッシュプル セットアップに行かない 2 つのオプションがあります。これは実際には 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を使用してこれに関するスクリーンキャストを作成しましたが、ロングポーリングはLaravelではなくPHPに関連しています。 https://www.youtube.com/watch?v=LDgJF77jELo

于 2013-08-21T00:34:37.373 に答える
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');
});
于 2013-08-20T20:35:13.133 に答える
1

Laravel とコア PHP のどちらを使用してコーディングする場合でも、サーバー送信イベントを試してみてください。SSEを使えば簡単にできます。

それは基本的に2つの部分を含みます:-

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()));

このすべてのスニペットは前述のリンクから借用したものであり、明確な理解のために徹底的な調査が推奨されます。

乾杯

于 2015-11-29T15:46:39.807 に答える