Обработка потоковых подключений в приложении Sinatra - PullRequest
1 голос
/ 04 января 2012

Существует отличный пример приложения для чата, использующего отправленные сервером события , автор Konstantin Haase.Я пытаюсь запустить его и у меня проблема с обратными вызовами (я использую Sinatra 1.3.2 и просматриваю Chrome 16).Они просто не запускаются (например, после перезагрузки страницы), и, следовательно, количество соединений растет.

Кроме того, соединение закрывается через 30-60 секунд, если не установить периодический таймер для отправки пустых данных, как это предлагаетсяКонстантин в другом месте.

Можете ли вы повторить это?Если да, можно ли как-то исправить эти проблемы?WebSockets работают без проблем в этом отношении ...

# ruby
get '/stream', provides: 'text/event-stream' do
  stream :keep_open do |out|
    EventMachine::PeriodicTimer.new(20) { out << "data: \n\n" } # added
    settings.connections << out
    puts settings.connections.count # added
    out.callback { puts 'closed'; settings.connections.delete(out) } # modified
  end
end

# javascript
  var es = new EventSource('/stream');
  es.onmessage = function(e) { if (e.data != '') $('#chat').append(e.data + "\n") }; // modified

Ответы [ 2 ]

3 голосов
/ 06 января 2012

Это ошибка в Синатре https://github.com/sinatra/sinatra/issues/446

2 голосов
/ 04 января 2012

аккуратный бит кода.Но вы правы, WebSockets решит эти проблемы.Я думаю, что здесь есть две проблемы:

1) Ваш браузер, веб-сервер или промежуточный прокси-сервер может завершить соединение через некоторое время, в режиме ожидания или нет.Ваше предложение о периодической отправке пустых данных по таймеру поможет, но не является гарантией.

2) Насколько я знаю, нет встроенного способа определить, работает ли одно из этих соединений и когда оно работает.Чтобы ваш список соединений не увеличивался, вам нужно будет отслеживать, когда каждое соединение использовалось в последний раз (возможно, клиент должен время от времени пинговать, и вы бы сохранили эту дату и время). Затем добавьте периодический таймер для проверки.for и kill «устаревшие» соединения.

Более простой, хотя и более уродливый вариант, - сохранить время создания каждого соединения и завершить его через n минут.Клиент должен быть достаточно умен, чтобы переподключиться.

Я знаю, что это убирает простоту кода.Как бы ни был хорош пример, я думаю, что это лучший кандидат для WebSockets.

...