Rails Rails 4 与 Socket.IO 的集成

qsun · 2014年03月24日 · 最后由 hooopo 回复于 2014年03月24日 · 6133 次阅读

Rails 和 node.js 各有所长,Rails 在快速原型实现速度上远远比相对年轻的 node.js 快很多。大量的第三方库使得写 Rails 程序非常简单。但是在大量链接情况和实时应用的情况下编写 node.js 相对简单,尤其是有 socket.io/engine.io/sock.js 这些逆天的跨平台实时库。

在 Rails 2/3 的时期,如果不是大量使用客户端 Javascript,页面切换会较为频繁,使得 Socket.io 这种实时前端结构不是很好集成 - 每次页面切换都会造成 socket 断开重连。

Rails 4 引入了 Turbolinks,这个特性(库)有可能造成前端对象、内存泄漏,但是同样的,这个 Turbolinks 使得页面不再切换,socket.io 这种库不需要在页面跳转的时候重新连接了。

我刚刚做了一点小小的实验,完成了一个 Rails 4 + Turbolinks + socket.io 的原型,请大家提提意见。实现的功能很简单,/pages/create动作可以发送广播信息,/pages/{new,recv}接收广播信息,并且在 console 打出。

Rails 处理基本页面,使用 node.js 的 express 模块实现了一个反向代理服务器,为 Rails 提供代理。

结构如下

浏览器  <====> node.js (express + socket.io) <====> Rails

node.js 代码

var express = require('express');
var app = express();
var server = app.listen(3001);
var request = require('request');
var io = require('socket.io').listen(server);
app.use(express.bodyParser());

app.use('/broadcast', function (req, res) {
    var data = req.body.data;
    res.end();
    io.sockets.emit('broadcast', data);
});

app.use('/', function(req, res) {
    var url = "http://127.0.0.1:3000" + req.url;
    var r = null;
    
    if (req.method == 'POST') {
        r = request.post({uri: url, json: req.body});
    } else {
        r = request(url);
    }
    req.pipe(r).pipe(res);
});

application.html.erb</head>之前加入 socket.io 相关代码

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect();
  socket.on('broadcast', function (data) {
    console.log(data);
  });
</script>

最后,实现pages_controller.rbcreate 


def create
    content = params[:content]
    Net::HTTP.post_form(URI('127.0.0.1:3001/broadcast'),
                          "data" => content,
                        )
    redirect_to :action => :recv 
end

测试打开两个窗口,一个窗口在 pages/recv,一个窗口发送消息。最好的是接受窗口由于 Turbolinks 的作用,随意点击链接跳转都不会让 socket.io 重新链接。

其他解决方法

  1. 使用多线程模式的 Ruby 是一个解决方法,faye 当然很好,但是多线程的 Ruby 总感觉怪怪的,客户端:线程 1:1 的结构总感觉心里不踏实。
  2. EventMachine 理论上和 node.js 应该差不多,但是很多人都说是坑

你需要的是N2O

#1 楼 @bhuztez 你好执着!一氧化二氮吗?

faye 不是一般都用 node.js 的么……

#2 楼 @hooopo 当 Nitrogen 开始燃烧就有了 N2O

#4 楼 @bhuztez 笑气不是这么合成的... 氮气燃烧会变成 NO/NO₂, 而 N₂O 加热会分解成 NO 和 N₂ ...

#5 楼 @luikore 对啊,因为 N2 烧起来不给力啊

#5 楼 @luikore 不是加热硝酸铵么..

需要 登录 后方可回复, 如果你还没有账号请 注册新账号