Förhandskrav:
- Ruby 2.0.0+
- Rails 4.0.0+
- Redis
- Puma
Initiering:
Skapa en redis.rb
initializer-fil i config/initializers
katalog, globalisera en instans av redis
. Det är också en bra idé att ställa in ett heartbeat
tråd (Allt från 5 sekunder till 5 minuter är okej, beroende på dina krav):
$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
Kontrollenhet:
Du måste lägga till två metoder till din ChatController
, pub
och sub
. Rollen för pub
är att publicera chatthändelser och meddelanden till redis
och sub
att prenumerera på dessa evenemang. Det borde se ut ungefär så här:
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
I dina routes
, gör pub ett POST
och sub en GET
, och matcha sökvägen till något som /chat/publish
och /chat/subscribe
.
Coffeescript / Javascript:
Förutsatt att din faktiska webbsida för chattappen är på /chat
, måste du skriva lite Javascript för att faktiskt skicka och ta emot chattmeddelanden.
För att underlätta förståelsen, låt oss anta att din webbsida bara har en textruta och en knapp. Om du trycker på knappen bör innehållet i textrutan publiceras i chattströmmen, det kan vi göra med 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
Nu måste du också kunna prenumerera och ta emot chattmeddelanden. Du måste använda EventSource
för detta. Använder EventSource , öppna en kanal för SSE så att du kan ta emot händelser och använd den informationen för att uppdatera vyn. I det här exemplet kommer vi bara att logga dem till javascript-konsolen.
Koden bör se ut ungefär så här:
$(document).ready ->
source = new EventSource('/chat/subscribe')
source.addEventListener 'chat_event', (e) ->
console.log(e.data)
Obs! Placera båda kodblocken ovan i din controllername.coffee
fil, för det här exemplet bör det vara chat.js.coffee
i din app/assets/javascript
katalog. Du måste också se till att den laddas i tillgångspipelinen. require
det i din application.js
fil (om du inte redan anropar require tree .
).
Aktivera parallella förfrågningar:
I din utvecklingsmiljö måste du aktivera parallella förfrågningar genom att lägga till dessa två rader i din config/environments/development.rb
:
config.preload_frameworks = true
config.allow_concurrency = true
Starta nu din webbläsare, bläddra till /chat
och se magin. När du skriver ett meddelande och klickar på knappen kommer meddelandet att tas emot av alla instanser av den webbsidan.
Så här gör du en grundläggande chattapplikation i rails
med ActionController::Live
och Redis
. Den slutliga koden skulle uppenbarligen vara väldigt olika beroende på dina krav, men detta borde få dig igång.
Några fler resurser du bör kolla in:
- Tender Love Making - Är det live?
- Railscasts - #401 - ActionController::Live
- SitePoint - Minichatt med Rails och SSE
- Github - mohanraj-ramanujam / livestream
- Thoughtbot – Chattexempel med hjälp av SSE