Prerequisiti:
- Rubino 2.0.0+
- Rotaie 4.0.0+
- Redis
- Puma
Inizializzatore:
Crea un redis.rb
inizializzatore in config/initializers
directory, globalizzando un'istanza di redis
. È anche una buona idea impostare un heartbeat
thread (Va bene qualsiasi cosa da 5 secondi a 5 minuti, a seconda delle tue esigenze):
$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
Titolare:
Devi aggiungere due metodi al tuo ChatController
, pub
e sub
. Il ruolo di pub
è pubblicare eventi e messaggi di chat su redis
e sub
per iscriversi a questi eventi. Dovrebbe assomigliare a questo:
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
Nei tuoi routes
, rendi pub un POST
e sub un GET
e abbina il percorso a qualcosa come /chat/publish
e /chat/subscribe
.
Coffeescript/Javascript:
Supponendo che la tua pagina web effettiva per l'app di chat sia su /chat
, devi scrivere un po' di Javascript per inviare e ricevere effettivamente messaggi di chat.
Per facilità di comprensione, supponiamo che la tua pagina web abbia solo una casella di testo e un pulsante. Premendo il pulsante dovresti pubblicare il contenuto della casella di testo nel flusso della chat, possiamo farlo 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
Ora devi essere in grado di iscriverti e ricevere anche i messaggi di chat. Devi usare EventSource
per questo. Utilizzando EventSource , apri un canale per SSE in modo da poter ricevere eventi e utilizza tali dati per aggiornare la visualizzazione. In questo esempio, li registreremo solo sulla console javascript.
Il codice dovrebbe assomigliare a questo:
$(document).ready ->
source = new EventSource('/chat/subscribe')
source.addEventListener 'chat_event', (e) ->
console.log(e.data)
Nota: Inserisci entrambi i blocchi di codice sopra nel tuo controllername.coffee
file, per questo esempio dovrebbe essere chat.js.coffee
nel tuo app/assets/javascript
directory. Devi anche assicurarti che venga caricato nella pipeline degli asset. require
nel tuo application.js
file (se non stai già chiamando require tree .
).
Abilita richieste parallele:
Nel tuo ambiente di sviluppo, dovrai abilitare le richieste parallele aggiungendo queste due righe al tuo config/environments/development.rb
:
config.preload_frameworks = true
config.allow_concurrency = true
Ora avvia il browser, vai a /chat
e guarda la magia. Quando digiti un messaggio e fai clic sul pulsante, il messaggio verrà ricevuto da tutte le istanze di quella pagina web.
Bene, ecco come crei un'applicazione di chat di base in rails
utilizzando ActionController::Live
e Redis
. Il codice finale sarebbe ovviamente molto diverso a seconda delle tue esigenze, ma questo dovrebbe iniziare.
Alcune altre risorse che dovresti controllare:
- Fare l'amore tenero - È dal vivo?
- Railscasts - #401 - ActionController::Live
- SitePoint - Mini chat con Rails e SSE
- Github - mohanraj-ramanujam / live streaming
- Thoughtbot - Esempio di chat utilizzando SSE