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

Sinatra与EventMachine WebSockets合作是否成功?

  •  36
  • Poul  · 技术社区  · 16 年前

    我已经成功地单独使用了gem'emwebsocket',但是还不能编写一个包含sinatraweb服务器和websocket服务器的ruby文件。

    我试过了!或者开始!方法在单独的线程中关闭,但没有成功。

    有人用过这个吗?

    我想把它们放在同一个文件中,这样我就可以在两个服务器之间共享变量。

    5 回复  |  直到 15 年前
        1
  •  27
  •   Kamiel Wanrooij    14 年前

    没有试过,但不应该太用力:

    require 'em-websocket'
    require 'sinatra/base'
    require 'thin'
    
    EM.run do
      class App < Sinatra::Base
        # Sinatra code here
      end
    
      EM::WebSocket.start(:host => '0.0.0.0', :port => 3001) do
        # Websocket code here
      end
    
      # You could also use Rainbows! instead of Thin.
      # Any EM based Rack handler should do.
      Thin::Server.start App, '0.0.0.0', 3000
    end
    

    也, Cramp

        2
  •  20
  •   Poul    16 年前

    谢谢康斯坦丁。。。成功了!我不得不稍微修改一下你的代码。我在修改的地方添加了评论。

    -波尔

    require 'rubygems'      # <-- Added this require
    require 'em-websocket'
    require 'sinatra/base'
    require 'thin'
    
    EventMachine.run do     # <-- Changed EM to EventMachine
      class App < Sinatra::Base
          get '/' do
              return "foo"
          end
      end
    
      EventMachine::WebSocket.start(:host => '0.0.0.0', :port => 8080) do |ws| # <-- Added |ws|
          # Websocket code here
          ws.onopen {
              ws.send "connected!!!!"
          }
    
          ws.onmessage { |msg|
              puts "got message #{msg}"
          }
    
          ws.onclose   {
              ws.send "WebSocket closed"
          }
    
      end
    
      # You could also use Rainbows! instead of Thin.
      # Any EM based Rack handler should do.
      App.run!({:port => 3000})    # <-- Changed this line from Thin.start to App.run!
    end
    
        3
  •  17
  •   Colin Surprenant    15 年前

    websocket-rack github项目基本上是一个框架化的 em-websocket 实际上,它可以很好地与Sinatra应用程序并行工作。这是我的config.ru:

    require 'rubygems'
    require 'rack/websocket'
    require 'sinatra/base'
    
    class WebSocketApp < Rack::WebSocket::Application
      # ...
    end
    
    class SinatraApp < Sinatra::Base
      # ...
    end
    
    map '/ws' do
      run WebSocketApp.new
    end
    
    map '/' do
      run SinatraApp
    end
    

    玩得高兴!
    科林

        4
  •  11
  •   simulacre    14 年前

    我一直在用 sinatra-websocket . 它允许您在与Sinatra相同的进程和端口上运行websocket服务器。

    免责声明:我是维护者。

    require 'sinatra'
    require 'sinatra-websocket'
    
    set :server, 'thin'
    set :sockets, []
    
    get '/' do
      if !request.websocket?
        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) } }
          end
          ws.onclose do
            warn("websocket closed")
            settings.sockets.delete(ws)
          end
        end
      end
    end
    
    __END__
    @@ index
    <html>
      <body>
         <h1>Simple Echo & Chat Server</h1>
         <form id="form">
           <input type="text" id="input" value="send a message"></input>
         </form>
         <div id="msgs"></div>
      </body>
    
      <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);
            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>
    </html>
    
        5
  •  8
  •   user546469    15 年前

    仅供参考,您还可以将Padrino应用程序与EventMachine一起使用(因为它们是Sinatra应用程序的子集):

    require 'rubygems'
    require 'eventmachine'
    require 'padrino-core'
    require 'thin'
    require ::File.dirname(__FILE__) + '/config/boot.rb'
    
    EM.run do
      Thin::Server.start Padrino.application, '0.0.0.0', 3000
    end
    

    干杯, 迈克