Ruby Sinatra与EventMachine WebSockets合作是否成功?
我使用Sinatra已经有一段时间了,我想通过WebSocket推送数据,为我的web应用程序添加一些实时功能 我已经成功地单独使用了gem'em websocket',但是还不能编写一个包含sinatra web服务器和web套接字服务器的ruby文件 我试过旋转跑步!或者开始!方法在单独的线程中关闭,但没有成功 有人用过这个吗 我希望将它们放在同一个文件中,以便在两台服务器之间共享变量Ruby Sinatra与EventMachine WebSockets合作是否成功?,ruby,sinatra,websocket,rack,eventmachine,Ruby,Sinatra,Websocket,Rack,Eventmachine,我使用Sinatra已经有一段时间了,我想通过WebSocket推送数据,为我的web应用程序添加一些实时功能 我已经成功地单独使用了gem'em websocket',但是还不能编写一个包含sinatra web服务器和web套接字服务器的ruby文件 我试过旋转跑步!或者开始!方法在单独的线程中关闭,但没有成功 有人用过这个吗 我希望将它们放在同一个文件中,以便在两台服务器之间共享变量 谢谢 没有尝试,但不应该太难: require 'em-websocket' require 'sinat
谢谢 没有尝试,但不应该太难:
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
需要“em websocket”
需要“sinatra/基地”
需要“瘦”
嗯,跑吧
类应用程序'0.0.0.0',:port=>3001)do
#这里是Websocket代码
结束
#你也可以用彩虹!而不是瘦。
#任何基于EM的机架处理器都应该这样做。
精简::Server.start应用程序,“0.0.0.0”,3000
结束
此外,它还有一个websocket实现,可以直接使用瘦/彩虹!您可能能够提取,因此您甚至不需要在另一个端口上运行服务器。谢谢Konstantin。。。成功了!我不得不稍微修改一下你的代码。我在修改的地方添加了评论 -波尔
require'rubygems'#8080)do | ws |##FYI,您也可以将Padrino应用程序与EventMachine一起使用(因为它们是Sinatra应用程序的子集):
干杯,
Mike我偶然发现了这个github项目,它基本上是一个机架化的项目,实际上它与一个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
需要“rubygems”
需要“机架/网匣”
需要“sinatra/基地”
类WebSocketApp
玩得开心
科林我一直在用。它允许您在与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>
需要“sinatra”
需要“sinatra websocket”
设置:服务器“精简”
集合:套接字,[]
获取“/”do
如果!请求websocket?
雇员再培训局:索引
其他的
request.websocket do | ws|
ws.onopen do
发送(“你好,世界!”)
settings.sockets..这是将websocket与sinatra一起使用的最快的方法(在我看来),我能问一下与使用'em websocket',将sinatra::Base子类化,以及“手动”插入事件循环相比,这种方法带来了哪些缺点吗?还有谁能简单解释一下为什么“下一步”是什么这里需要吗?@@Simulare--有什么办法可以在负载平衡的设置中工作吗?我的意思是,从上面的例子来看,每个Sinatra进程都会有自己的“settings.sockets”数组,从而使进程变为有状态?非常可爱:)这很好。不过有一个问题,EventMachine套接字事件如何访问会话信息以验证事件是否来自经过适当身份验证的用户?根据我对@Konstanti Haase的回答的评论,我已经概述了这一点,这是一个新问题-请看,这就是我所做的。然而,我有一个相关的问题,那就是如何解码客户端传递给ws.onopen
的握手中返回的Rack::Server::Cookie
(在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
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>