Установить соединение 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)
когда слишком много клиентов или слишком долгое время ожидания.
Итак, мой вопрос
- Как реализовать клиент WebSocket на сервере потоков HTTP? (Можно использовать другую библиотеку вместо Sinatra)
- Если в Sinatra Stream может быть реализован клиент WebSocket, как повысить стабильность Sinatra Stream? (Избегайте IOError)
Извините за мой плохой английский. Большое спасибо!
1 ответ
Проблема произошла давным-давно, и я забыл детали решения. Но, согласно моей слабой памяти, вы можете обновить версию Ruby, чтобы избежать этой ошибки (>=ruby-2.1 кажется нормальным). Я также добавил несколько микросекунд "сна" между каждыми двумя "записи".
Я считаю, что версия Ruby является основной причиной. Извините, что я не могу проверить это сейчас.