Установите соединение 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, таких как 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 было закрыто в то же время.

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

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

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

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

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


person Hangchen Yu    schedule 17.03.2015    source источник
comment
У меня такая же проблема, вы нашли решение?   -  person rolele    schedule 25.10.2015
comment
Я забыл детали решения. Но вы можете обновить версию Ruby, чтобы избежать этой ошибки (›=ruby-2.1 кажется нормальным). Я также добавил несколько микросекунд сна между каждыми двумя операциями записи. Надеюсь, это поможет вам!   -  person Hangchen Yu    schedule 26.10.2015


Ответы (1)


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

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

person Hangchen Yu    schedule 13.11.2015