EventMachine WebSockets - 订阅EM频道与保持套接字集合

时间:2012-08-25 17:04:33

标签: ruby websocket eventmachine

我正在构建一个使用EM和WebSockets的项目,并涉及向订阅的客户端广播数据。

我想知道为什么会更喜欢将websocket订阅到频道,如下所示:

EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|

ws.onopen {
  sid = @channel.subscribe { |msg| ws.send msg }
  @channel.push "#{sid} connected!"

  ws.onmessage { |msg|
    @channel.push "<#{sid}>: #{msg}"
  }

  ws.onclose {
    @channel.unsubscribe(sid)
  }
}

end

将每个websocket添加到数组中:

EM::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|
ws.onopen {
  puts "Websocket connection opened"
  websocket_connections << ws
}
ws.onclose {
  puts "Websocket connection closed"
  websocket_connections.delete(ws)
}
end

并简单地遍历整个数组并在适当的时候进行类似的ws.send msg调用(或者相反)。

对于EventMachine的整个非阻塞特性,频道备选方案是否有更好的优化? (例如,一次广播到某些已订阅的套接字,然后继续与其他套接字一起发送,而不是一次性发送所有套接字)

1 个答案:

答案 0 :(得分:4)

EventMachine :: Channel类只是一个处理订阅者数组迭代的抽象。如果你查看EventMachine::Channel#push的Ruby源代码,你会发现它类似于你的建议:

def push(*items)
  items = items.dup
  EM.schedule { @subs.values.each { |s| items.each { |i| s.call i } } }
end

实际上,如果您不需要复制items数组,它实际上比手动迭代列表要慢。但是,我怀疑性能影响是否显着。 EventMachine :: Channel只是一种抽象,可以更轻松地管理客户列表。