Установить соединение WebSocket на HTTP-сервере (Sinatra Stream) в Ruby

Я пишу HTTP-сервер (A), используя Sinatra::Streaming (я использую Ruby). Он должен прочитать данные с сервера WebSocket (B) и переслать их клиенту (C). Поток данных "B ->A->C". Операции чтения и записи должны выполняться в режиме реального времени.

В качестве возможного решения я попытался создать соединение WebSocket в Sinatra. Код выглядит так:

class Deploy < Sinatra::Base
  helpers Sinatra::Streaming
  set :sessions, true
  set :server, 'thin'

  get '/' do
    stream(:keep_open) do |out|
      #create a WebSocket connection
        EM.run {
          ws = Faye::WebSocket::Client.new('ws://0.0.0.0:8080/')
          ws.on :message do |event|
            out << event.data
            out.flush
          end
          ws.on :close do |event|
            ws = nil
          end
        }
    end
  end
end

Я пробовал несколько библиотек WebSocket Client, таких как faye-websocket. Программа потерпела неудачу как ~/.rvm/gems/ruby-2.0.0-p598/gems/sinatra-contrib-1.4.2/lib/sinatra/streaming.rb:100:in '<<': not opened for writing (IOError) при выполнении out << event.data, Соединение WebSocket было закрыто в то же время.

Кажется, что IO WebSocket конфликтует / закрывает IO Sinatra Stream.

В настоящее время я создаю подпроцесс для установления соединения WebSocket и позволяю подпроцессу взаимодействовать с сервером Sinatra (A). Но это может потребовать слишком много системных ресурсов, если десятки людей получат доступ к A. Более того, сервер Sinatra Stream также часто прерывает работу not opened for writing (IOError) когда слишком много клиентов или слишком долгое время ожидания.

Итак, мой вопрос

  1. Как реализовать клиент WebSocket на сервере потоков HTTP? (Можно использовать другую библиотеку вместо Sinatra)
  2. Если в Sinatra Stream может быть реализован клиент WebSocket, как повысить стабильность Sinatra Stream? (Избегайте IOError)

Извините за мой плохой английский. Большое спасибо!

1 ответ

Проблема произошла давным-давно, и я забыл детали решения. Но, согласно моей слабой памяти, вы можете обновить версию Ruby, чтобы избежать этой ошибки (>=ruby-2.1 кажется нормальным). Я также добавил несколько микросекунд "сна" между каждыми двумя "записи".

Я считаю, что версия Ruby является основной причиной. Извините, что я не могу проверить это сейчас.

Другие вопросы по тегам