EventMachine WebSockets - Subscribe ws to EM channels vs Keeping sockets in collection
eventmachine, ruby, websocket
Solution
The EventMachine::Channel class is simply an abstraction that handles the iteration of a subscribers array. If you look at the Ruby source code for EventMachine::Channel#push, you see it is similar to what you propose:
def push(*items)
items = items.dup
EM.schedule { @subs.values.each { |s| items.each { |i| s.call i } } }
end
In fact, if you don't need to duplicate your items array, it is actually slower than manually iterating the list. However, I doubt that the performance impact is significant. EventMachine::Channel is simply an abstraction that makes managing lists of clients easier.
Problem
I'm building a project which uses EM and WebSockets and involves broadcasting data to subscribed clients. I'm wondering why would one prefer subscribing a websocket to a channel, like the following: ``` 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 ``` Over adding each websocket to an array: ``` 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 ``` and simply iterating over the entire array and make a similar `ws.send msg` call when appropriate (or the other way around). Does the channel alternative has better optimisation for the entire non-blocking characteristics of EventMachine? (e.g. broadcast to some of the subscribed sockets in one time, and then continue with the others instead of sending all of them at once)