0

以下のようにサーバーでwebsocketを使用しています。イベントに応答しonmessage、メッセージに従ってさまざまなタスクを実行するように調整されます。

require "websocket-eventmachine-server"

WebSocket::EventMachine::Server.start(host: some_server_name, port: some_port) do |ws|
  # (A) Here, the current thread is the main thread
  ws.onmessage do |s|
    if foo
      # (B) Here, the current thread is the main thread
      ...
    else
      # (C) Here, the current thread is the main thread
      ...
    end 
  end
end

すべてのonmessageイベントが実行されるスレッド (BおよびC上記で説明) は毎回同じであり、それらはメイン スレッド (A上記で説明されている) と同じです。

Bとして別のスレッドでコードを実行したいC。これを行う 1 つの方法は、次のように操作を新しいスレッド内に配置することBですC

WebSocket::EventMachine::Server.start(host: some_server_name, port: some_port) do |ws|
  # (A) Here, the current thread is the main thread
  ws.onmessage do |s|
    if foo
      # (B) Here, the current thread will be created each time.
      Thread.new{...}
    else
      # (C) Here, the current thread will be created each time.
      Thread.new{...}
    end
  end
end

しかし、イベントが発生するたびに新しいスレッドを作成すると、重いようで、応答が遅くなります。したがって、1 つのスレッドを で処理されるすべてのイベントで共有し、別のスレッドを でonmessage処理されるすべてのイベントで共有する必要があります。BC

WebSocket::EventMachine::Server.start(host: some_server_name, port: some_port) do |ws|
  # (A) Here, the current thread is the main thread
  ws.onmessage do |s|
    if foo
      # (B) I want this part to be executed in a thread
      #     that does not change each time, but is different from the thread in C
      ...
    else
      # (C) I want this part to be executed in a thread
      #     that does not change each time, but is different from the thread in B
      ...
    end
  end
end

これを行うにはどうすればよいでしょうか。または、相互にブロックしない方法で websocketonmessageイベントに応答するためのより良い構造はありますか?

4

2 に答える 2

2

メソッドを使用EventMachine.deferして、その内部スレッド プールでコードを実行します。

于 2013-11-18T15:15:00.843 に答える
-2

受信したメッセージのキューを作成し、traitment を実行するためにキューごとに 1 つのスレッドを作成できます。

def do_foo(message)
   .... your code
end
def do_fee(message)
   .... your code
end

queueA= Queue.new
queueB= Queue.new
Thread.new { loop { do_foo(queueA.pop) } }
Thread.new { loop { do_fee(queueB.pop) } }
WebSocket::EventMachine::Server.start(host: some_server_name, port: some_port) do |ws|
  # (A) Here, the current thread is the main thread
  ws.onmessage do |s|
    if foo
       queueA.push(s)
    else
       queueB.push(s)
    end
  end
end

警告 !!do_foo/fee が Websocket でメッセージを送信する必要がある場合は、EM.next_tick { if .. } で「if foo..」を呼び出す必要があります。

于 2013-11-18T12:26:18.713 に答える