我正在使用em-websocket gem制作一个Ruby服务器。当客户端发送一些消息(例如“线程”)时,服务器创建两个不同的线程,并且并行地向客户端发送两个anwsers(我实际上正在研究多线程和websockets)。这是我的代码:
EM.run {
EM::WebSocket.run(:host => "0.0.0.0", :port => 8080) do |ws|
ws.onmessage { |msg|
puts "Recieved message: #{msg}"
if msg == "thread"
threads = []
threads << a = Thread.new {
sleep(1)
puts "1"
ws.send("Message sent from thread 1")
}
threads << b = Thread.new{
sleep(2)
puts "2"
ws.send("Message sent from thread 2")
}
threads.each { |aThread| aThread.join }
end
如何执行:
问题是我想在发送调试输出“1”和“2”的同时准确发送消息。
我的Ruby版本是1.9.3p194。
答案 0 :(得分:0)
我认为问题在于你正在调用sleep方法,将1传递给第一个线程,将2传递给第二个线程。 尝试在两个线程上删除睡眠调用或在每次调用时传递相同的值。
答案 1 :(得分:0)
我没有EM的经验,所以拿一点盐就可以了。
然而,乍一看,看起来“aThread.join”实际上阻止了“onmessage”方法的完成,从而也阻止了“ws.send”的处理。 您是否尝试删除“threads.each”块?
编辑: 在使用ruby 1.9.3和2.0.0(使用em-websocket示例中的"test.html")在arch linux中测试过这个之后,我确信即使删除“threads.each”块也不会为你解决问题,你仍然需要删除它,因为Thread#join将挂起当前线程,直到“加入”线程完成。
如果你通过源代码跟随“ws.onmessage”的函数调用,你将最终到达Connection#send_data method of the Eventmachine module并在评论中找到以下内容:
调用此方法将数据发送到网络连接的远程端。它需要一个String参数,它可能包含二进制数据。缓冲数据以在此事件循环结束时发送(周期)。
由于“onmessage”被“join”阻止,直到两个“send”方法都运行,事件循环滴答无法完成,直到两组数据都被缓冲,因此,所有数据在此之前都无法发送。 / p>
如果删除“threads.each”块后仍然无法正常工作,请确保已重新启动事件处理器并尝试将第二次睡眠设置为5秒。我不知道一个典型的事件循环在eventmachine中花了多长时间(我无法想象它只要一秒钟),但是,文档基本上说如果在同一个tick内进行了几次“发送”调用,他们都将同时发送。因此,增加时差将确保不会发生这种情况。