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