3

EMとWebSocketを使用し、サブスクライブされたクライアントにデータをブロードキャストするプロジェクトを構築しています。

次のように、なぜ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 に答える