2017-02-28 5 views
2

Rubyで複数のWebSocketに接続する方法は? <a href="https://github.com/faye/faye-websocket-ruby" rel="nofollow noreferrer">faye-websocket</a>を使用し、EventMachineコードは、クライアントの例-のWebSocketをフェイと非常によく似ています

require 'faye/websocket' 
require 'eventmachine' 

def setup_socket(url) 
    EM.run { 
     ws = Faye::WebSocket::Client.new(url) 

     ws.on :open do ... end 

     ws.on :message do ... end 

     ws.on :close do ... end 
    } 
end 

私は複数の接続オープン並列を持っているしたいと思います。実行がEM.run節を終了しないので、私は単にsetup_socketを複数回呼び出すことはできません。私は別のスレッドでsetup_socket複数回実行しようとしました:

urls.each do |url| 
    Thread.new { setup_socket(url) } 
end 

しかし、puts文が出力に到達しないようanyhtingを行うにはいないようです。

私はfaye-websocketの使用に制限されていませんが、ほとんどの人がこのライブラリを使用していたようです。可能であれば、私はマルチスレッドを避けたいと思います。また、時間の経過とともに変更を加える可能性(例えば、新しいウェブソケットを追加する可能性)を失うことも望まない。したがって、EM.run句の中でURLの繰り返しを移動することは望ましくなく、代わりに複数のEMを開始する方が有益です。私はexample for starting multiple servers via EMを非常にきれいな方法で見つけました。私は似たようなものを探しています。

同時に複数のWebSocketに接続するにはどうすればよいですか?

+0

どうして 'def setup_sockets(urls); EM.run {urls.each {...}};終わり。それは働かないの? – Casper

+0

それはうまくいくかもしれません。 URLが時間の経過とともに変化したり、新しいURLが追加される可能性があるので、私はそれについて考えなかった。このアプローチでは、プロセスを再開する必要があり、その場で変更を加えることはできません。 – thisismydesign

答えて

2

これは1つの方法です。

まず、EMスレッドが実行されている必要があります。このスレッドがなければ、現在の接続を処理することはできません。だからあなたはそれを回避することはできません。

EMスレッドに新しいURLを追加するには、メインスレッドからEMスレッドに通信する必要があるため、新しい接続を開始するよう指示できます。これはEventMachine::Channelで行うことができます。

だから我々は今構築することができますどのようなものです:

@channel = EventMachine::Channel.new 

Thread.new { 
    EventMachine.run { 
    @channel.subscribe { |url| 
     ws = Faye::...new(url) 
     ... 
    } 
    } 
} 

その後、メインスレッド、あなたがイベントループに新しいURLを追加したい任意の時点で、あなたはこれを使用します。

ここで
def setup_socket(url) 
    @channel.push(url) 
end 
0

はそれを行うための別の方法があります...使用のヨウ素のネイティブWebSocketをサポート(またはPlezi framework)の代わりにem-websocket ...

の...私は、(私が著者だ)BU偏ったよ私は彼らがそれをもっと楽にすると思う。また、PleziはRedisで自動スケーリングを提供するので、簡単に拡張できます。

ここでは、Pleziを使用した例を示しています。各コントローラはチャネルのように動作し、独自のURLとWebsocketコールバックを持っています(Pleziの自動ディスパッチは、より低いレベルのon_messageコールバックより簡単です)。このコードはconfig.ruファイルに置くことができます:

require 'plezi' 

# Once controller/channel for all members of the "Red" group 
class RedGroup 
    def index # HTTP index for the /red URL 
    "return the RedGroup client using `:render`".freeze 
    end 
    # handle websocket messages 
    def on_message data 
    # in this example, we'll send the data to all the members of the other group. 
    BlueGroup.broadcast :handle_message, data 
    end 
    # This is the method activated by the "broadcast" message 
    def handle_message data 
    write data # write the data to the client. 
    end 
end 
# the blue group controller/channel 
class BlueGroup 
    def index # HTTP index for the /blue URL 
    "return the BlueGroup client using `:render`".freeze 
    end 
    # handle websocket messages 
    def on_message data 
    # in this example, we'll send the data to all the members of the other group. 
    RedGroup.broadcast :handle_message, data 
    end 
    # This is the method activated by the "broadcast" message 
    def handle_message data 
    write data 
    end 
end 
# the routes 
Plezi.route '/red', RedGroup 
Plezi.route '/blue', BlueGroup 
# Set the Rack application 
run Plezi.app 

P.S.

em-websocketがリソースに失敗したり、リソースが不足することがあるため、この回答も書いています。詳細についてはわかりませんが、websocket-shootout benchmarkAnyCable Websocket Benchmarksの両方に記載されています。

関連する問題