4

ビデオファイルを受け取り、それらをさまざまな他の形式に操作するカスタムペーパークリッププロセッサを備えたRailsアプリに取り組んでいます。

私はビデオを扱っており、このプロセスがサーバー上で完了するまでに時間がかかるため、処理のステータスに関する情報をサーバーからフロントエンドに渡したいと考えています。

私の質問は、ページをリロードせずにカスタム ペーパークリップ クラスから JS にこれらのメッセージを取得するための最良の方法は何ですか? ある種のイベント pub/sub システムを推測していますが、これを実装する最良の方法については不明です。

Rails からしばらく離れていたので、初心者向けの質問でしたら申し訳ありません。

4

1 に答える 1

8

あなたの質問は比較的あいまいだったので、私の答えが同じであれば申し訳ありません:


WebSocket または SSE (サーバー送信イベント)

複数のレコードを削除し、削除された更新を送信するアプリでこれに似たものを実装しました

pub/sub についてはそのとおりです。基礎となる技術について説明しようと思います。これは、実際には SSE または WebSocket の同様のプロセスです。


「ライブ」データの受信

サーバーから「ライブ」データを受信するプロセスは、Rails 内でActionController::Liveコントローラーを使用することです。これは、response.headers['Content-Type'] = 'text/event-stream'HTTP MIME タイプと連携して、データの小さなパケットを Javascript の「リスナー」(フロントエンドで初期化します) に送信します。

SSE を使用するか WebSocket を使用するかに関係なく、「ライブ」コントローラー アクション (ライブ情報を作成する) が必要であり、ブラウザーでリアルタイム データをキャプチャするためのJavascript EventListenerも必要です。

これを行う方法はテクノロジーごとに異なりますが、実際には SSE と WebSocket の両方で同様のプロセスです。


SSEの

Server Sent Eventsは、必要なデータを公開するサーバー上のエンドポイント (Rails ActionController::Live アクション) への非同期接続を開くことで、更新されたデータを基本的に受信 (送信ではなく) できるようにする HTML5 テクノロジです。

通常、 Redisを使用してこれを設定し(データを JSON にコンパイルするため)、Rails の ActionController::Live 機能を使用して送信します。Javascript は、トリガーされたイベントを「リッスン」するため、サーバーから送信されたリアルタイム データをキャプチャし、フロント エンドで操作できます。

SSE の問題は、ロング ポーリングを使用してエンドポイントに継続的に「ping」を実行し、最新の情報を取得しようとすることです。Puma ではマルチスレッドが可能ですが、接続を同時に実行することができず、パフォーマンスが大幅に低下しました (基本的に、毎秒リクエストを送信すると接続が消費されます)。


WebSocket

Websocketsは SSE と同様のテクノロジーですが、大きな違いがあります。永続的な接続が可能です。

WebSocket は、単一の TCP 接続を介して全二重通信チャネルを提供するプロトコルです。

これは、その間に何をするかに関係なく、データを送受信できるだけでなく、一度だけ接続して接続を維持できることを意味します。これは、SSE よりもはるかに安定したソリューションであることがわかりました。ロング ポーリングの要件がなくなり、認証を正しく維持できれば、データを正しく受信できるようになるからです。

すべての大物は WebSocket (StackOverflow を含む) を使用しており、実際にはセットアップが比較的簡単です。


「リアルタイム」設定

必要なもの:

  1. Rails ActionController::Live 関数とエンドポイント (ルート)
  2. サードパーティ Websocket 統合 ( Pusher )
  3. Javascript EventListeners (返されたデータを処理するため)

私たちが使用するライブコードは次のとおりです。

#app/controllers/resources_controller.rb (inherited resources)
        def destroy        
            element = @resource.find(params[:id])
            element.destroy
            Pusher['private-user-' + current_user.id.to_s].trigger('my_event', {
                message: "Removed #{element.title}"
            })
        end

   #app/assets/javascripts/users.js.coffee.erb
   pusher = new Pusher("******************",
        cluster: 'eu'
   )

   channel = pusher.subscribe("private-user-#{gon.user_id}")
   channel.bind "my_event", (data) ->
       alert data.message

これにより、プッシャー アプリへの永続的な接続が開かれ、データが処理されます。プッシャーはデータを受信するたびに更新を送信し、ユーザーにメッセージを警告することができます

単純な概要だとは思いますが、参考になれば幸いです

于 2013-11-15T09:36:27.213 に答える