我正在构建一个订阅 Redis 通道并使用服务器发送事件将消息推送到客户端的 Rack 中间件。Sinatra 提供了一个很好的 DSL 来做这件事。我有一个工作示例,但是,我遇到的问题是,一旦我到达 7 或 8 个客户端,性能就会大幅下降。在尝试重用请求之间的 Redis 连接时,我还遇到了“死锁”服务器的问题。
我正在使用 Thin 为应用程序提供服务(它在后台使用 EventMachine)。我认为 Sinatra DSL 已经使用 EventMachine 处理了并发,但也许这是我需要自己实现的东西?我不想将自己限制在仅基于 EventMachine 的服务器(Thin,Rainbows!),以防有人想使用像 Puma 这样的多线程服务器。我应该怎么做才能增加代码的并发性?
require 'redis'
require 'sinatra/base'
class SSE < Sinatra::Base
def send_message(json)
"id: #{Time.now}\n" +
"data: #{json}" +
"\r\n\n"
end
get '/channels/:id/subscribe', provides: 'text/event-stream' do
channel_id = params['id']
stream(:keep_open) do |connection|
Redis.new.subscribe("channels:#{channel_id}") do |on|
on.message do |channel, json|
connection << send_message(json)
end
end
end
end
end