代码之家  ›  专栏  ›  技术社区  ›  arjun

Sinatra将数据从TCP传递到websockets

  •  0
  • arjun  · 技术社区  · 7 年前

    我正在尝试使用Sinatra来侦听自定义HTTP方法。无论从那里接收到什么数据,都会通过websocket传递给 n编号 客户端,实时。

    1. 我已经能够让Sinatra侦听自定义HTTP方法NOTIFY。
    2. 我还运行了一个websocket服务器。
    3. 但我无法理解最后一部分,即在接收时将数据从NOTIFY传递给websocket客户端。如何做到这一点?

    Ruby应用程序。rb型

    require 'sinatra'
    require 'sinatra-websocket'
    
    configure do
      class << Sinatra::Base
        def notify(path, opts={}, &block)
          route 'NOTIFY', path, opts, &block
        end
      end
      Sinatra::Delegator.delegate :notify
    end
    
    set :server, 'thin'
    set :sockets, []
    set :bind, '0.0.0.0'
    enable :sessions # For some reason sessions don't work. Relying on class variable.
    
    
    
    notify '/' do   
        @json = request.body.read    
        session[:order] = @json
        @@pass = session[:order] # Saved in class variable. Hacky?
        puts "NOTIFY"
        puts "is session[:order] nil? #{session[:order].nil?}" # returns false
        puts "END NOTIFY"
    end    
    
    get '/' do
      if !request.websocket?
        puts @@pass # prints NOTIFY data successfully
    
        puts "GETS"
        puts "is session[:order] nil? #{session[:order].nil?}" # returns true. Session dont work
        puts "END GETS"
    
        @new = @@pass
        erb :index
      else
        request.websocket do |ws|
          ws.onopen do
            ws.send("Hello World!")            
            settings.sockets << ws
          end
          ws.onmessage do |msg|
            EM.next_tick { settings.sockets.each{|s| s.send(msg) } }
            ws.send(@@pass) # this will send on each message. Not real-time
          end
          ws.onclose do
            warn("websocket closed")
            settings.sockets.delete(ws)
          end
        end
      end
    end    
    
    __END__
    

    内联ERB索引

    @@ index
    <html>
      <body>
         <h1>Simple Echo &amp; Chat Server</h1>
         <p><%= @new %></p>
         <form id="form">
           <input type="text" id="input" value="send a message"></input>
         </form>
         <div id="msgs"></div>
    
    
      <script type="text/javascript">
        window.onload = function(){
          (function(){
            var show = function(el){
              return function(msg){ el.innerHTML = msg + '<br />' + el.innerHTML; }
            }(document.getElementById('msgs'));
    
            var ws       = new WebSocket('ws://' + window.location.host + window.location.pathname);
            console.log(ws);
            ws.onopen    = function()  { show('websocket opened'); };
            ws.onclose   = function()  { show('websocket closed'); }
            ws.onmessage = function(m) { show('websocket message: ' +  m.data); };
    
            var sender = function(f){
              var input     = document.getElementById('input');
              input.onclick = function(){ input.value = "" };
              f.onsubmit    = function(){
                ws.send(input.value);
                input.value = "send a message";
                return false;
              }
            }(document.getElementById('form'));
          })();
        }
      </script>
        </body>
    </html>
    

    1 回复  |  直到 7 年前
        1
  •  0
  •   arjun    7 年前

    我发现这很难接口。相反,分区方法可以完成这项工作。

    单独启动websocket服务器,Sinatra服务器在每个传入TCP请求时作为客户端进行通信,这是一个短期的客户端。

    websocket服务器将此传入消息广播给所有其他连接的客户端。