3

我正在构建一个使用 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 的整个非阻塞特性有更好的优化?(例如一次广播到一些订阅的套接字,然后继续其他的,而不是一次发送所有这些套接字)

4

1 回答 1

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

于 2012-08-28T17:37:10.353 回答