[英]how do I close a redis connection using the sinatra streaming api?
我有以下sinatra應用程序:
require 'sinatra'
require 'redis'
require 'json'
class FeedStream < Sinatra::Application
helpers do
include SessionsHelper
def redis
@redis ||= Redis.connect
end
end
get '/feed', provides: 'text/event-stream' do
stream do |out|
redis.subscribe "feed" do |on|
on.message do |channel, message|
event_data = JSON.parse message
logger.info "received event = #{event_data}"
out << "event: #{event_data['event']}\n"
out << "data: #{{:data => event_data['data'],
:by => current_user}}.to_json\n\n"
end
end
end
end
end
基本上,它使用redis pubsub接收其他用戶發布到feed的事件,然后使用sinatra streaming api發送這些事件。 問題是,當瀏覽器重新連接到源時,redis客戶端保持連接,並且它一直接收事件,因此redis服務器充滿了無用的連接。 一旦broser關閉與Web服務器的連接,我該如何關閉所有這些連接?
我知道已經有一段時間了。
你在找戒煙嗎?
經過大量的研究和實驗,這里是我與sinatra + sinatra sse gem使用的代碼(應該很容易適應Rails 4):
class EventServer < Sinatra::Base
include Sinatra::SSE
set :connections, []
.
.
.
get '/channel/:channel' do
.
.
.
sse_stream do |out|
settings.connections << out
out.callback {
puts 'Client disconnected from sse';
settings.connections.delete(out);
}
redis.subscribe(channel) do |on|
on.subscribe do |channel, subscriptions|
puts "Subscribed to redis ##{channel}\n"
end
on.message do |channel, message|
puts "Message from redis ##{channel}: #{message}\n"
message = JSON.parse(message)
.
.
.
if settings.connections.include?(out)
out.push(message)
else
puts 'closing orphaned redis connection'
redis.unsubscribe
end
end
end
end
end
redis連接阻止on.message並且只接受(p)subscribe /(p)unsubscribe命令。 取消訂閱后,redis連接不再被阻止,並且可以由初始sse請求實例化的Web服務器對象釋放。 當您在redis上收到消息時,它會自動清除,並且集合數組中不再存在與瀏覽器的連接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.