2010-06-08 7 views
35

मैं कुछ समय के लिए सिनात्रा का उपयोग कर रहा हूं और मैं वेबकैकेट के माध्यम से डेटा को दबाकर अपने वेब ऐप में कुछ रीयलटाइम फीचर्स जोड़ना चाहता हूं।सिनात्रा के साथ इवेंटमैचिन वेबसाकेट्स के साथ मिलकर काम करने में कोई सफलता?

मैंने सफलतापूर्वक मणि 'em-websocket' का उपयोग किया है, लेकिन एक रूबी फ़ाइल लिखने में सक्षम नहीं है जिसमें एक sinatra वेब सर्वर और एक वेब सॉकेट सर्वर है।

मैंने रन कताई करने की कोशिश की है! या शुरू करो! बिना सफलता के अलग धागे में विधियों को बंद करें।

क्या किसी ने इसे काम करने के लिए प्राप्त किया है?

मैं उन्हें एक ही फाइल में रखना चाहता हूं क्योंकि मैं दो सर्वरों के बीच चर साझा कर सकता हूं।

धन्यवाद!

उत्तर

26

यह कोशिश की है, लेकिन बहुत कठिन नहीं होना चाहिए:

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 एक WebSocket क्रियान्वयन कि पतला/इंद्रधनुष के साथ सीधे काम करता है! आप निकालने में सक्षम हो सकते हैं, इसलिए आपको किसी अन्य पोर्ट पर सर्वर चलाने की भी आवश्यकता नहीं होगी।

+0

यह काफी है कि मैंने इसे कैसे किया है। मेरे पास एक संबंधित प्रश्न है, हालांकि मैं क्लाइंट द्वारा 'ws.onopen' में दिए गए 'हैंडशेक' में लौटाए गए 'रैक :: सर्वर :: कुकी' ('सिनात्रा' वर्ग में सेट) मान को कैसे डीकोड कर सकता हूं। Http://stackoverflow.com/questions/16312024/how-to-decode-a-cookie-from-the-header-of-a-websocket-connection-handshake-rub –

20

धन्यवाद Konstantin ... यह काम किया! मुझे थोड़ा सा कोड बदलना पड़ा। मैंने टिप्पणियां जोड़ दीं जहां मैंने इसे बदल दिया।

-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 
+0

पर मेरे प्रश्न को और अधिक विस्तार से देखें यह अच्छी तरह से काम करता है । हालांकि एक सवाल, इवेंटमैचिन सॉकेट घटनाएं सत्र जानकारी तक कैसे पहुंच सकती हैं यह प्रमाणित करने के लिए कि घटनाएं ठीक से प्रमाणीकृत उपयोगकर्ता से आ रही हैं? –

+0

मैंने एक नया प्रश्न के रूप में @ कॉन्स्टेंटी हास के उत्तर पर मेरी टिप्पणी के अनुसार इसे रेखांकित किया है - http://stackoverflow.com/questions/16312024/how-to-decode-a-cookie-from-the-header- ऑफ-ए-वेबस्केट-कनेक्शन-हैंडशेक-रब –

7

FYI करें, आप भी Padrino उपयोग कर सकते हैं EventMachine वाले ऐप्स (के रूप में वे सिनात्रा क्षुधा के सबसेट हैं):

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 

चीयर्स, माइक

17

मैं ठोकर खाई इस websocket-rack गीथब प्रोजेक्ट पर जो मूल रूप से एक रैकिफाइड em-websocket है और वास्तव में इसे सिना के साथ अच्छी तरह से साइड-साइड काम करने के लिए मिला है ट्रा ऐप यहां मेरा 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 

मज़े करो!
कॉलिन

+0

कॉलिन - बस स्पष्ट होने के लिए, यह आपकी config.ru फ़ाइल में है? – wchrisjohnson

+2

वह सचमुच कहता है "यहां मेरी कॉन्फ़िगरेशन है।आरयू: "। तो मुझे लगता है कि" हां "जवाब है :) –

11

मैं 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> 
+0

.. यह sinatra (मेरी आंखों के लिए) के साथ websocket का उपयोग करने का सबसे तेज़ तरीका है, क्या मैं पूछ सकता हूं कि इस दृष्टिकोण से 'em-websocket' का उपयोग करने के लिए तुलना किस नुकसान से लाती है। , सिनात्रा :: बेस, और "मैन्युअल" घटना लूप में प्लगिंग? –

+0

कोई भी यहां कोई छोटी व्याख्या दे सकता है कि "next_tick" की आवश्यकता क्यों है? –

+0

@@ simulacre - कोई विचार लोड पर यह काम कैसे करें संतुलित सेटअप? मेरा मतलब है ऊपर दिए गए उदाहरण से, प्रत्येक सिनात्रा प्रक्रिया के बाद प्रक्रिया को बदलकर अपनी "सेटिंग्स.sockets" सरणी होगी? – rebnoob

संबंधित मुद्दे