Ruby em-websocket阻塞?

时间:2012-06-11 23:41:08

标签: ruby websocket em-websocket

我正在编写一个有2个线程的ruby程序。一个侦听传入的UDP连接,另一个侦听来自客户端浏览器的websocket上的广播。我正在使用em-websocket gem。但是,我的UDP侦听器线程永远不会被调用,看起来代码仍然在websocket初始化代码中。我猜测是因为em-websocket阻塞了,但我还没有能够在网上找到任何暗示这一点的信息。这是我的错误吗?我对红宝石有点新意,所以我无法弄清楚我做错了什么。

require 'json'
require 'em-websocket'
require 'socket'

socket=nil
text="default"
$x=0

EventMachine.run do
EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|
  ws.onopen    { 
            ws.send "Hello Client!"
            socket=ws
            $x=1
        }

  ws.onmessage { |msg| socket.send "Pong: #{msg}" }
  ws.onclose   { puts "WebSocket closed" }
end
end
def listen()
puts "listening..."
s = UDPSocket.new
s.bind(nil, 3000)
while 1<2 do
  text, sender = s.recvfrom(1024)     
  puts text
  if $x==1 then
    socket.send text      
  end   
end
end

t2=Thread.new{listen()}
t2.join

1 个答案:

答案 0 :(得分:4)

em-websocket是非阻止的,但UDPSocket#recv_from是。可能最好只使用EventMachine的open_datagram_socket

需要注意的另一点是:您不应将socket公开为“全局”变量。每次有人连接时,对先前连接的客户端的引用都将丢失。可能为套接字连接创建某种存储库,或者在有东西进入时使用观察者模式来广播消息。我要做的是让虚拟对象充当观察者,无论何时连接/断开套接字,您都可以注册/取消注册观察员:

require 'observer'

class Dummy
  include Observable

  def receive_data data
    changed true
    notify_observers data
  end
end

# ... later on ...

$broadcaster = Dummy.new

class UDPHandler < EventMachine::Connection
  def receive_data data
    $broadcaster.receive_data data
  end
end

EventMachine.run do
  EM.open_datagram_socket "0.0.0.0", 3000, UDPHandler

  EM::WebSocket.start :host => "0.0.0.0", :port => 8080 do |ws|
    ws.onopen do
      $broadcaster.add_observer ws
    end

    ws.onclose do
      $broadcaster.delete_observer ws
    end

    # ...
  end
end

EventMachine的重点是从基本套接字和线程结构中抽象出来,并在内部处理所有异步位。最好不要将UDPSocketThread等经典库与EventMachine混合使用。