Ruby em websocket是否阻塞?
我正在编写一个有两个线程的ruby程序。一个监听传入的UDP连接,另一个在websocket上广播,客户端的浏览器从中读取。但是,我的UDP侦听器线程从未被调用,而且代码似乎停留在websocket初始化代码中。我猜是因为em-websocket被屏蔽了,但我还没能在网上找到任何提示这一点的信息。这是我的错误吗?我对ruby有点陌生,所以我不知道自己做错了什么Ruby em websocket是否阻塞?,ruby,websocket,em-websocket,Ruby,Websocket,Em Websocket,我正在编写一个有两个线程的ruby程序。一个监听传入的UDP连接,另一个在websocket上广播,客户端的浏览器从中读取。但是,我的UDP侦听器线程从未被调用,而且代码似乎停留在websocket初始化代码中。我猜是因为em-websocket被屏蔽了,但我还没能在网上找到任何提示这一点的信息。这是我的错误吗?我对ruby有点陌生,所以我不知道自己做错了什么 require 'json' require 'em-websocket' require 'socket' socket=nil t
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
require'json'
需要“他们是websocket”
需要“插座”
插座=零
text=“默认值”
$x=0
EventMachine.rundo
EventMachine::WebSocket.start(:host=>0.0.0“,:port=>8080)do | ws|
ws.onopen{
ws.send“你好,客户端!”
套接字=ws
$x=1
}
ws.onmessage{| msg | socket.send“Pong:{msg}”
ws.onclose{put“WebSocket closed”}
结束
结束
def listen()
把“倾听…”
s=UDPSocket.new
s、 绑定(无,3000)
虽然1em websocket
是非阻塞的,但是UDPSocket#recv_from
是非阻塞的。最好只使用EventMachine的open\u datagram\u 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
需要“观察者”
类虚拟
包括可观察的
def接收数据
变为真
通知观察员数据
结束
结束
# ... 后来。。。
$broadcaster=Dummy.new
类UDPHandler“0.0.0.0”,:port=>8080 do | ws|
ws.onopen do
$broadcaster.add\u observer ws
结束
ws.onclose do
$broadcaster.delete\u observer ws
结束
# ...
结束
结束
EventMachine的全部要点是从基本套接字和线程结构中抽象出来,并在内部处理所有异步位。最好不要将诸如UDPSocket
或Thread
之类的经典库与EventMachine内容混合使用。em-websocket
是非阻塞的,而UDPSocket#recv\u from
是。最好只使用EventMachine的open\u datagram\u 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
需要“观察者”
类虚拟
包括可观察的
def接收数据
变为真
通知观察员数据
结束
结束
# ... 后来。。。
$broadcaster=Dummy.new
类UDPHandler“0.0.0.0”,:port=>8080 do | ws|
ws.onopen do
$broadcaster.add\u observer ws
结束
ws.onclose do
$broadcaster.delete\u observer ws
结束
# ...
结束
结束
EventMachine的全部要点是从基本套接字和线程结构中抽象出来,并在内部处理所有异步位。最好不要将诸如UDPSocket
或Thread
之类的经典库与EventMachine内容混合使用。感谢您的详细回复!我发现我的websocket发送调用被阻塞了,我猜这是因为“socket=ws”语句。我不太确定什么是观察者,但我会查一下并尝试使用它。谢谢如果我在一个方法中初始化websocket,并且希望在另一个方法中使用套接字句柄,那么除此之外,我还能用什么方法呢?该引用的范围似乎没有扩展到全球范围。我不知道为什么。ruby中的作用域与Java/C等不同吗?好的。我解决了这个问题。我没有用“$”符号定义变量套接字。所以它不在全球范围内。我不知道ruby中的范围差异。无论如何谢谢你的帮助!是的,在使用def
定义的方法中,任何局部变量(没有sigil-$
、@
或@
的变量)都不可见。但是,您需要记住的主要一点是,您可能有多个连接:ws
并不总是指同一个连接!是的。谢谢你指出这一点。我更改了代码以跟踪所有打开的连接。我没有使用ws,而是将它改为@ws。所以现在我把所有的连接句柄都放在一个数组中,我会给每个句柄发送一条消息。谢谢你的详细回复!我发现我的websocket发送调用被阻塞了,我猜这是因为“socket=ws”语句。我不太确定什么是观察者,但我会查一下并尝试使用它。谢谢如果我在一个方法中初始化websocket,并且希望在另一个方法中使用套接字句柄,那么除此之外,我还能用什么方法呢?该引用的范围似乎没有扩展到全球范围。我不知道为什么。ruby中的作用域与Java/C等不同吗?好的。我解决了这个问题。我没有用“$”符号定义变量套接字。所以它不在全球范围内。我不知道ruby中的范围差异。谢谢你