我正在写一个有两个线程的ruby程序。一个监听传入的UDP连接,另一个在客户端浏览器读取的websocket上广播。我正在使用em-websocket gem。然而,我的UDP侦听器线程从未被调用过,看起来代码停留在websocket初始化代码中。我猜是因为em-websocket被屏蔽了,但我在网上找不到任何表明这一点的信息。这是我这边的错误吗?我是ruby的新手,所以我不知道我做错了什么。
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发布于 2012-06-12 09:30:13
与UDPSocket#recv_from不同,em-websocket是非阻塞的。使用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
endEventMachine的全部要点是从基本的套接字和线程结构中抽象出来,并在内部处理所有的异步位。最好不要将UDPSocket或Thread等经典库与EventMachine混合使用。
https://stackoverflow.com/questions/10988840
复制相似问题