使用线程在websocket中发送多条消息

时间:2013-07-04 13:29:35

标签: ruby multithreading em-websocket

我正在使用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

如何执行:

  • 我正在向服务器发送“thread”消息
  • 在我的控制台中一秒后,我看到打印的字符串“1”。又过了一会儿,我看到了“2”。
  • 只有在这两个消息同时发送到客户端之后。

问题是我想在发送调试输出“1”和“2”的同时准确发送消息。

我的Ruby版本是1.9.3p194。

2 个答案:

答案 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内进行了几次“发送”调用,他们都将同时发送。因此,增加时差将确保不会发生这种情况。