Recentemente precisei criar um chat para integrar com a aplicação da empresa que trabalho. Sim, mais um desenvolvimento de chat. Como dizem por ai, chat é o novo Hello World.
Já tinha ouvido falar do Faye, até o Ryan Bates fez um Railscasts sobre o assunto.
O Faye tem módulos para Ruby e Node.js.
Minha primeira tentativa foi utilizar a versão ruby do Faye. Essa versão nada mais é que uma aplicação Rack. Funcionou muito bem, até chegar em produção. O servidor que ele utiliza é o thin, e para a quantidade de requests que minha aplicação faz ao chat o servidor não durava 3 minutos em pé.
Depois de muito quebrar a cabeça resolvi partir para a versão em Node.js do Faye que resolveu perfeitamente esse problema. Vou mostrar abaixo como fiz para utilizando Faye, Node.js e Rails:
Vamos ao código
Primeiro você precisa ter o Node.js e o NPM instalados.
Na raiz da aplicação, instale o faye utilizando o npm:
$ npm install faye
Logo em seguida, também na raiz da aplicação, criei o arquivo abaixo:
faye_server.js
var http = require('http')
, faye = require('faye');
var Logger = {
incoming: function(message, callback) {
console.log(message);
console.log('====================');
callback(message);
}
};
var bayeux = new faye.NodeAdapter({mount: '/faye', timeout: 60});
bayeux.addExtension(Logger);
bayeux.listen(9292);
Para testar se o faye está corretamente instalado e funcionando, rode o servidor:
$ node faye_server.js
E abra no seu nevegador a URL http://localhost:9292/faye.js. Se um arquivo JavaScript for carregar, então o Faye está funcionando corretamente. #WIN
Client-side
No seu arquivo de layouts (ex.: application.html.erb) você precisa adicionar o JavaScript do Faye:
<%= javascript_include_tag "http://localhost:9292/faye.js" %>
Agora basta criar uma instância para o Client do Faye e o canal que receberá as mensagens do nosso chat:
application.js
$(function() {
var faye_client = new Faye.Client('http://localhost:9292/faye');
faye_client.subscribe('/chat' , function(data) {
eval(data);
});
});
Back-end
Criei um simples formulário que faz um POST para MessagesController::create utilizando AJAX:
app/views/messages/index.html.erb
<h1>Messages</h1>
<div id="messages">
<ol></ol>
</div>
<%= form_for @message, remote: true do |f| %>
<%= f.label :content %>
<%= f.text_field :content %>
<%= f.submit "Send" %>
<% end %>
E no controller MessagesController:
class MessagesController < ApplicationController
def index
@message = Message.new
end
def create
@message = Message.create(params[:message])
end
end
Simples, certo?
O segredo está na view app/views/messages/create.js.erb:
<% broadcast "/chat" do %>
$("#messages ol").append($("<li><%= @message.content %></li>"));
<% end %>
$("#message_content").val('');
Seguindo a dica do Ryan Bates, criei um helper para facilitar o envio das mensagens para o Faye Server. Ele será responsável em fazer o broadcast para todos os usuários conectados no chat.
app/helpers/messages_helper.rb
module MessagesHelper
def broadcast(channel, &block)
message = { channel: channel, data: capture(&block) }
uri = URI.parse("http://localhost:9292/faye")
Net::HTTP.post_form(uri, message: message.to_json)
end
end
Como este helper está usando o Net::HTTP, precisamos adicioná-lo na nossa aplicação. Eu normalmente faço o require dessa lib no arquivo config/application.rb:
# ...
require 'rails/all'
require 'net/http'
# ...
Com isso nosso chat está pronto!
Lógico que na minha aplicação existem processos um pouco mais complexos, lidando com chat privado (estilo Facebook) e autenticação de usuários. Mas para exemplo, esse caso mais simples vale.
Você pode baixar a aplicação completa diretamente do meu GitHub:
https://github.com/willian/faye_chat_example
Fácil, não!?

1 comentário para "Faye – Como eu criei um simples chat usando Rails"
Que coincidência, estou mesmo estudando node.js + Faye no momento e gostando bastante