EventMachine WebSockets - 订阅 WS 到 EM 频道与保持套接字收集

Posted

技术标签:

【中文标题】EventMachine WebSockets - 订阅 WS 到 EM 频道与保持套接字收集【英文标题】:EventMachine WebSockets - Subscribe ws to EM channels vs Keeping sockets in collection 【发布时间】:2012-08-25 17:04:33 【问题描述】:

我正在构建一个使用 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】:

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 只是一种抽象,它使管理客户端列表更加容易。

【讨论】:

以上是关于EventMachine WebSockets - 订阅 WS 到 EM 频道与保持套接字收集的主要内容,如果未能解决你的问题,请参考以下文章

EventMachine/em-http-request 检测 http 流连接何时停止

使用 EventMachine 和 RabbitMQ 的 RPC

安装eventmachine(1.0.3)时出错[重复]

如何在 EventMachine 实现中捕获异常?

Sinatra 流媒体和 Eventmachine 频道

无法在 Rails 控制台中加载 Ruby EventMachine - 没有要加载的文件