3

バックグラウンド プロセスで Ruby を使用して WebSocket にデータを送信するにはどうすればよいですか?

バックグラウンド

gemを使用して Websocket サーバーを実行する別の ruby​​ ファイルが既にありますwebsocket-eventmachine-server。ただし、Rails アプリケーション内で、バックグラウンド タスクで websocket にデータを送信したいと考えています。

これが私のWebSocketサーバーです:

EM.run do
  trap('TERM') { stop }
  trap('INT') { stop }

  WebSocket::EventMachine::Server.start(host: options[:host], port: options[:port]) do |ws|

    ws.onopen do
      puts 'Client connected'
    end

    ws.onmessage do |msg, type|
      ws.send msg, type: type
    end

    ws.onclose do
      puts 'Client disconnected'
    end

  end

  def stop
    puts 'Terminating WebSocket Server'
    EventMachine.stop
  end
end

ただし、バックグラウンド プロセス (Sidekiq を使用しています) では、WebSocket に接続してデータを送信する方法がわかりません。

これが私の Sidekiq ワーカーです。

class MyWorker
  include Sidekiq::Worker

  def perform(command)
    100.times do |i|
      # Send 'I am on #{i}' to the Websocket
    end  
  end

end

私は何かができることを望んでいましたがEventMachine::WebSocket.send 'My message!'、そのための API や同様のものは見当たりません。RubyでWebSocketにデータを送信する正しい方法は何ですか?

4

2 に答える 2

3

受け入れられた回答:

現在の websocket サーバーを維持する場合:

テスト用の単純な Websocket クライアントとしてIodineを使用できます。独自のリアクター パターン ベースのコードを使用してバックグラウンド タスクを実行し、websocket クライアントを備えています (私は偏見がありますが、私は作成者です)。

次のようなことができます。

require 'iodine/http'
Iodine.protocol = :timers
# force Iodine to start immediately
Iodine.force_start!

options = {}
options[:on_message] = Proc.new {|data| puts data}

100.times do |i|
    options[:on_open] = Proc.new {write "I am number #{i}"}
    Iodine.run do
        Iodine::Http.ws_connect('ws://localhost:3000', options) 
    end
end

PS

Websocketには Pleziなどのフレームワークを使用することをお勧めします (私は作成者です)。一部のフレームワークでは、Rails/Sinatra アプリ内でコードを実行できます (Plezi はそれを行い、厳密にはフレームワークではありませんが、Faye もそれを行うと思います)。

EM を直接使用するのは非常に困難であり、Websocket を扱う際には管理すべきことがたくさんありますが、優れたフレームワークが管理に役立ちます。

編集3

Iodine WebSocket クライアント接続は、OpenSSL の場合の TLS 接続を含め、Iodine 0.7.17 以降で (再) サポートされています>= 1.1.0

次のコードは、元の回答の更新版です。

require 'iodine'

class MyClient
  def on_open connection
    connection.subscribe :updates
    puts "Connected"
  end
  def on_message connection, data
    puts data
  end
  def on_close connection
    # auto-reconnect after 250ms.
    puts "Connection lost, re-connecting in 250ms"
    Iodine.run_after(250) { MyClient.connect }
  end

  def self.connect
    Iodine.connect(url: "ws://localhost:3000/path", handler: MyClient.new)
  end
end


Iodine.threads = 1
Iodine.defer { MyClient.connect if Iodine.master? }
Thread.new { Iodine.start }

100.times {|i| Iodine.publish :updates, "I am number #{i}" }

編集2

Iodine 0.2.x にはクライアントが含まれなくなったため、この回答は古くなっています。websocket クライアントには Iodine 0.1.x または別の gem を使用してください

于 2014-12-07T11:44:45.247 に答える
1

websocket-eventmachine-serverは websocketsサーバーです。

Ruby を使用して websocket サーバーに接続する場合は、次のようないくつかの gem を使用して接続できます。

于 2013-06-04T16:33:36.060 に答える