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如上所述)。CA

我想B在一个单独的线程中执行代码作为C. 一种方法是将操作放入新线程中,如下所示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) 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

但是每次发生事件时创建一个新线程似乎很重,并且使响应变慢。因此,我希望在 中处理的所有事件之间共享一个线程onmessageB并在中处理的所有事件之间共享另一个线程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) 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

什么是这样做的好方法?或者,是否有更好的结构以onmessage相互非阻塞的方式响应 websocket 事件?

4

2 回答 2

2

使用EventMachine.defer方法在其内部线程池中执行代码。

于 2013-11-18T15:15:00.843 回答
-2

您可以制作接收消息的队列,并按队列制作一个线程以执行特征:

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 回答