楼主现在做一个组件发布平台,其中需要用到 websocket 同步组件的发布状态到 Web,这里我用的是 em-websocket。
由于用到的功能不多,我直接开新的线程在 Sinatra 进程里面初始化 websocket 了,初始化代码如下
Thread.new do
EM.run do
signature = EventMachine::WebSocket.start(
:host => '0.0.0.0',
:port => Labor.config.websocket_port,
:debug => false#!Sinatra::Base.settings.production?
) do |ws|
ws.onopen do |handshake|
catch_logger do
query = CGI::parse(handshake.query_string)
deploy_id = query['id']&.first
Labor::DeployMessager.push_ws(deploy_id, ws)
logger.info("open socket #{ws} with deploy id #{deploy_id}")
end
end
....
end
# EM.stop_server signature
end
end
当 Web 点击开发发布时,Sinatra 会处理这个请求,并且去 Labor::DeployMessager 保存的 websockets 数组中找对应的 websocket,发送状态信息。后续 GitLab 会触发 webhook,Sinatra 处理之后也会通过 websocket 通过给 Web。
但是在使用 Sidekiq 将 GitLab 触发 webhook 的任务放到后台后(这个任务比较耗时,可能要十几秒),发现由于 Sidekiq 和 Sinatra 读取执行了两次代码,上面保存的 websockets 在 Sidekiq 里面访问不了。 楼主做客户端的,对后台的这些服务不是很了解,想问下这种情况下,怎么处理两个服务都要通过 websocket 向 Web 同步状态的情况?