Pré-requisitos:
- Rubi 2.0.0+
- Trilhos 4.0.0+
- Redis
- Puma
Inicializador:
Crie um
redis.rb
arquivo inicializador no config/initializers
diretório, globalizando uma instância de redis
. Também é uma boa ideia configurar um heartbeat
thread (qualquer coisa de 5 segundos a 5 minutos está bem, dependendo dos seus requisitos):$redis = Redis.new
heartbeat_thread = Thread.new do
while true
$redis.publish("heartbeat","thump")
sleep 15.seconds
end
end
at_exit do
heartbeat_thread.kill
$redis.quit
end
Controlador:
Você precisa adicionar dois métodos ao seu
ChatController
, pub
e sub
. A função de pub
é publicar eventos de bate-papo e mensagens para redis
e sub
para se inscrever nesses eventos. Deve ser algo assim:class ChatController < ApplicationController
include ActionController::Live
skip_before_filter :verify_authenticity_token
def index
end
def pub
$redis.publish 'chat_event', params[:chat_data].to_json
render json: {}, status: 200
end
def sub
response.headers["Content-Type"] = "text/event-stream"
redis = Redis.new
redis.subscribe(['chat_event', 'heartbeat']) do |on|
on.message do |event, data|
response.stream.write "event: #{event}\ndata: #{data}\n\n"
end
end
rescue IOError
logger.info "Stream Closed"
ensure
redis.quit
response.stream.close
end
end
Em suas
routes
, faça publicar um POST
e sub um GET
, e corresponda o caminho a algo como /chat/publish
e /chat/subscribe
. Coffeescript/Javascript:
Supondo que sua página da Web real para o aplicativo de bate-papo esteja em
/chat
, você precisa escrever algum Javascript para enviar e receber mensagens de chat. Para facilitar o entendimento, vamos supor que sua página da Web tenha apenas uma caixa de texto e um botão. Apertar o botão deve publicar o conteúdo da caixa de texto no fluxo de bate-papo, podemos fazer isso usando AJAX:
$('button#send').click (e) ->
e.preventDefault()
$.ajax '/chat/publish',
type: 'POST'
data:
chat_data: {
message: $("input#message").val()
timestamp: $.now()
error: (jqXHR, textStatus, errorThrown) ->
console.log "Failed: " + textStatus
success: (data, textStatus, jqXHR) ->
console.log "Success: " + textStatus
Agora, você precisa ser capaz de se inscrever e receber as mensagens de bate-papo também. Você precisa usar
EventSource
por esta. Usando EventSource , abra um canal para SSE para que você possa receber eventos e use esses dados para atualizar a visualização. Neste exemplo, vamos registrá-los apenas no console javascript. O código deve ficar mais ou menos assim:
$(document).ready ->
source = new EventSource('/chat/subscribe')
source.addEventListener 'chat_event', (e) ->
console.log(e.data)
Observação: Coloque ambos os blocos de código acima em seu
controllername.coffee
arquivo, para este exemplo deve ser chat.js.coffee
em seu app/assets/javascript
diretório. Você também precisa ter certeza de que está sendo carregado no pipeline de ativos. require
em seu application.js
arquivo (se você ainda não estiver chamando require tree .
). Ativar solicitações paralelas:
Em seu ambiente de desenvolvimento, você terá que habilitar solicitações paralelas adicionando essas duas linhas ao seu
config/environments/development.rb
:config.preload_frameworks = true
config.allow_concurrency = true
Agora abra seu navegador, navegue até
/chat
e veja a magia. Quando você digita uma mensagem e clica no botão, a mensagem será recebida por todas as instâncias daquela página da web. Bem, é assim que você cria um aplicativo de bate-papo básico em
rails
usando ActionController::Live
e Redis
. O código final obviamente seria muito diferente dependendo de seus requisitos, mas isso deve ser o primeiro passo. Mais alguns recursos que você deve conferir:
- Tender Love Making - É ao vivo?
- Railscasts - #401 - ActionController::Live
- SitePoint - Mini Chat com Rails e SSEs
- Github - mohanraj-ramanujam / transmissão ao vivo
- Thoughtbot - Exemplo de bate-papo usando SSEs