<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>tripleCC (tripleCC)</title>
    <link>https://ruby-china.org/tripleCC</link>
    <description/>
    <language>en-us</language>
    <item>
      <title>Sinatra 和 Sidekiq 如何访问同个 websocket 连接？</title>
      <description>&lt;p&gt;楼主现在做一个组件发布平台，其中需要用到 websocket 同步组件的发布状态到 Web，这里我用的是 em-websocket。&lt;/p&gt;

&lt;p&gt;由于用到的功能不多，我直接开新的线程在 Sinatra 进程里面初始化 websocket 了，初始化代码如下&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
 &lt;span class="no"&gt;EM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
   &lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;EventMachine&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'0.0.0.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
     &lt;span class="ss"&gt;:port&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Labor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;websocket_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
     &lt;span class="ss"&gt;:debug&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="c1"&gt;#!Sinatra::Base.settings.production?&lt;/span&gt;
     &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onopen&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;handshake&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="n"&gt;catch_logger&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
         &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;CGI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handshake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="n"&gt;deploy_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;

         &lt;span class="no"&gt;Labor&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;DeployMessager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push_ws&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deploy_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"open socket &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; with deploy id &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;deploy_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;
     &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
   &lt;span class="nf"&gt;end&lt;/span&gt;
   &lt;span class="c1"&gt;# EM.stop_server signature&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当 Web 点击开发发布时，Sinatra 会处理这个请求，并且去 Labor::DeployMessager 保存的 websockets 数组中找对应的 websocket，发送状态信息。后续 GitLab 会触发 webhook，Sinatra 处理之后也会通过 websocket 通过给 Web。&lt;/p&gt;

&lt;p&gt;但是在使用 Sidekiq 将 GitLab 触发 webhook 的任务放到后台后（这个任务比较耗时，可能要十几秒），发现由于 Sidekiq 和 Sinatra 读取执行了两次代码，上面保存的 websockets 在 Sidekiq 里面访问不了。 
楼主做客户端的，对后台的这些服务不是很了解，想问下这种情况下，怎么处理两个服务都要通过 websocket 向 Web 同步状态的情况？&lt;/p&gt;</description>
      <author>tripleCC</author>
      <pubDate>Wed, 17 Oct 2018 19:45:42 +0800</pubDate>
      <link>https://ruby-china.org/topics/37641</link>
      <guid>https://ruby-china.org/topics/37641</guid>
    </item>
  </channel>
</rss>
