Vereisten vooraf:
- Ruby 2.0.0+
- Rails 4.0.0+
- Opnieuw
- Puma
Initialisator:
Maak een redis.rb
initialisatiebestand in de config/initializers
directory, globaliseren van een instantie van redis
. Het is ook een goed idee om een heartbeat
. in te stellen thread (alles van 5 seconden tot 5 minuten is oké, afhankelijk van uw vereisten):
$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
Controller:
U moet twee methoden toevoegen aan uw ChatController
, pub
en sub
. De rol van pub
is het publiceren van chatgebeurtenissen en berichten naar redis
, en sub
om u op deze evenementen te abonneren. Het zou er ongeveer zo uit moeten zien:
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
In je routes
, maak pub een POST
en sub een GET
, en koppel het pad aan iets als /chat/publish
en /chat/subscribe
.
Coffeescript / Javascript:
Ervan uitgaande dat uw daadwerkelijke webpagina voor de chat-app op /chat
staat , moet je wat Javascript write schrijven om daadwerkelijk chatberichten te verzenden en ontvangen.
Laten we voor het gemak eens aannemen dat uw webpagina alleen een tekstvak en een knop heeft. Als u op de knop drukt, wordt de inhoud van het tekstvak in de chatstream gepubliceerd, dat kunnen we doen met 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 moet je je ook kunnen abonneren en de chatberichten kunnen ontvangen. Je moet EventSource
. gebruiken voor deze. EventSource gebruiken , open een kanaal voor SSE zodat u gebeurtenissen kunt ontvangen en gebruik die gegevens om de weergave bij te werken. In dit voorbeeld loggen we ze alleen in de javascript-console.
De code zou er ongeveer zo uit moeten zien:
$(document).ready ->
source = new EventSource('/chat/subscribe')
source.addEventListener 'chat_event', (e) ->
console.log(e.data)
Opmerking: Plaats beide codeblokken hierboven in uw controllername.coffee
bestand, voor dit voorbeeld moet het chat.js.coffee
. zijn in uw app/assets/javascript
map. U moet er ook voor zorgen dat het wordt geladen in de activapijplijn. require
het in uw application.js
bestand (als je require tree .
).
Schakel parallelle verzoeken in:
In uw ontwikkelomgeving moet u parallelle verzoeken inschakelen door deze twee regels toe te voegen aan uw config/environments/development.rb
:
config.preload_frameworks = true
config.allow_concurrency = true
Start nu uw browser, blader naar /chat
en zie de magie. Wanneer u een bericht typt en op de knop klikt, wordt het bericht door alle instanties van die webpagina ontvangen.
Welnu, dit is hoe je een basischattoepassing maakt in rails
met behulp van ActionController::Live
en Redis
. De uiteindelijke code zou natuurlijk heel anders zijn, afhankelijk van uw vereisten, maar dit zou u op weg moeten helpen.
Nog enkele bronnen die u moet bekijken:
- Tender Love Making - Is it Live?
- Railscasts - #401 - ActionController::Live
- SitePoint - Minichat met Rails en SSE's
- Github - mohanraj-ramanujam / live-stream
- Thoughtbot - Chatvoorbeeld met SSE's