1

プログラムの進行状況 (ここではループとして例示) を Web サイトにリアルタイムで表示したいと考えています。

適切な Ruby サーバーが実行されている場合、クライアントはブラウザーを使用して websocket 経由でサーバーに接続し、接続すると、新しく生成されたプロセスに関する「更新」をリアルタイムで受信できるはずです。ポーリングや Ajax は必要ありません。

これをテストする私の考えは、クライアント側の JavaScript を使用して、EventMachine::WebSocket とクライアント ブラウザーの間で二重通信を確立することです。ループを構築し、ブラウザ クライアントに更新を送信します。

ruby_socket_server.rb:

require 'eventmachine'
require 'em-websocket'
@sockets = []
EventMachine.run do
    EventMachine::WebSocket.start(:host =>'localhost',:port =>8887) do |socket|
    socket.onopen do
        @sockets << socket
        (0..10).each do |i|
            puts "i am on loop #{i}" #to terminal window
            @sockets.each do |s|
                s.send "Just received notification of loop #{i}" 
                sleep(1) #pause for a second
            end
        end
    end
end

main.js:

socket = new WebSocket('ws://localhost:8887');
socket.onopen = function(){
    console.log('OPEN');
}
socket.onclose = function(){
    console.log('CLOSED');
}
socket.onmessage = function(msg){
    console.log(msg);
}

次のようになると思います。

  • サーバー: 私はループ 1 にいます。
  • クライアント: ループ 1 の通知を受け取りました。
  • サーバー: 私はループ 2 にいます。
  • クライアント: ループ 2 の通知を受け取りました。

実際に起こっていること:

  • サーバー: 私はループ 1 にいます。
  • サーバー: 私はループ 2 にいます。
  • クライアント: ループ 1 の通知を受け取りました。
  • クライアント: ループ 2 の通知を受け取りました。

Ruby ループ内からクライアントにデータを送信できません。つまり、最終的にはすべてのパケットを送信しますが、期待どおりにすべての反復中に送信するわけではありません。代わりに、サーバー ループが完了するまで待機し、複数の呼び出しを連続して送信します。

ここで何が間違っていますか?私が探しているものは可能ですか?このナットを割る方法についての考えは役に立ちます。

4

2 に答える 2

1

EventMachine はマルチスレッドではありません。したがって、実行させない場合、つまりコールバック内にとどまっている場合は、何も起こりません。

あなたの例ではsleep、コールバック内で呼び出します。これにより、コールバックが終了しないため、EM を実行できません。実行できない場合は、メッセージを送信できません。

したがって、任意の EM サーバーは、イベント化されたコールバック セットアップを中心に完全に構​​築する必要があります。

それがEvent Machine と呼ばれる理由です。少し考え方が異なりますが、コツをつかめば大丈夫です。

これを機能させる方法の例を次に示します。

EM.run do
  EM::WebSocket.start(:host =>'localhost',:port =>8887) do |ws|
    ws.onopen { |handshake|
      puts "New connection from #{handshake.origin}"
      loop = 1
      timer = EM.add_periodic_timer(1) {
        ws.send "Timer loop #{loop}"

        if (loop += 1) == 5
          EM.cancel_timer(timer)
          ws.send "Bye"
          ws.close_websocket
        end
      }
    }
  end
end
于 2013-02-06T06:05:34.330 に答える