辛納特拉與EventMachine WebSockets合作成功了嗎?

[英]Any success with Sinatra working together with EventMachine WebSockets?


I have been using Sinatra for sometime now and I would like to add some realtime features to my web-app by pushing the data via websockets.

我使用Sinatra已經有一段時間了,我想通過websockets將數據推送到我的web應用程序中,從而增加一些實時功能。

I have successfully used the gem 'em-websocket' on its own, but have not been able to write one ruby file that has a sinatra web server AND a web-socket server.

我已經成功地使用了gem“em-websocket”,但是還不能編寫一個包含sinatra web服務器和websocket服務器的ruby文件。

I've tried spinning the run! or start! methods off in separate threads with no success.

我已經試過了!或者開始!方法分離在單獨的線程中,沒有成功。

Has anyone gotten this to work?

有人把這個工作做了嗎?

I want to have them in the same file as I can then share variables between the two servers.

我想把它們放在同一個文件中,這樣我就可以在兩個服務器之間共享變量。

Thanks!

謝謝!

5 个解决方案

#1


27  

Did not try it, but should not be too hard:

沒有嘗試過,但也不應該太難:

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

Also, Cramp has a websocket implementation that works directly with Thin/Rainbows! you might be able to extract, so you won't even need to run the server on another port.

而且,Cramp有一個websocket實現,可以直接使用瘦/彩虹!您可能可以提取,因此甚至不需要在另一個端口上運行服務器。

#2


20  

Thanks Konstantin... that worked! I had to tweak your code slightly. I added comments where I changed it.

謝謝康斯坦丁……那工作!我不得不稍微修改你的代碼。我在我修改的地方添加了注釋。

-poul

保羅•

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  

I stumbled onto this websocket-rack github project which is basically a rackified em-websocket and actually got it to work nicely side-by-side with a Sinatra app. Here's my config.ru:

我偶然發現了這個websocket-rack github項目它基本上是一個簡化了的emm -websocket項目,實際上它和Sinatra很好地結合在一起。

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

Have fun!
Colin

玩得開心!科林

#4


11  

I've been using sinatra-websocket. It let's you run the websocket server in the same process and on the same port as Sinatra.

我一直使用sinatra-websocket。讓我們在與Sinatra相同的進程和端口上運行websocket服務器。

Disclaimer: I'm the maintainer.

免責聲明:我是維護者。

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


7  

FYI, you can also use Padrino apps with EventMachine (as they are subsets of Sinatra apps):

另外,你也可以在EventMachine上使用Padrino應用程序(因為它們是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

Cheers, Mike

干杯,邁克


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2010/06/08/7c2c40c292c8de17985038c28da7e240.html



 
  © 2014-2022 ITdaan.com 联系我们: