Prérequis :
- Rubis 2.0.0+
- Rail 4.0.0+
- Redis
- Puma
Initialisation :
Créer un redis.rb
fichier d'initialisation dans config/initializers
répertoire, globalisant une instance de redis
. C'est aussi une bonne idée de mettre en place un heartbeat
fil (tout ce qui va de 5 secondes à 5 minutes est acceptable, selon vos besoins) :
$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
Contrôleur :
Vous devez ajouter deux méthodes à votre ChatController
, pub
et sub
. Le rôle de pub
est de publier des événements de chat et des messages sur redis
, et sub
pour vous inscrire à ces événements. Cela devrait ressembler à ceci :
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
Dans vos routes
, faites de la pub un POST
et sous un GET
, et faites correspondre le chemin à quelque chose comme /chat/publish
et /chat/subscribe
.
Coffeescript / Javascript :
En supposant que votre page Web réelle pour l'application de chat se trouve sur /chat
, vous devez écrire du Javascript pour envoyer et recevoir des messages de chat.
Pour faciliter la compréhension, supposons que votre page Web ne comporte qu'une zone de texte et un bouton. Cliquer sur le bouton devrait publier le contenu de la zone de texte dans le flux de discussion, nous pouvons le faire en utilisant 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
Maintenant, vous devez pouvoir vous abonner et recevoir également les messages de chat. Vous devez utiliser EventSource
pour ça. Utiliser EventSource , ouvrez un canal pour SSE afin de pouvoir recevoir des événements et utilisez ces données pour mettre à jour la vue. Dans cet exemple, nous les enregistrerons uniquement dans la console javascript.
Le code devrait ressembler à ceci :
$(document).ready ->
source = new EventSource('/chat/subscribe')
source.addEventListener 'chat_event', (e) ->
console.log(e.data)
Remarque : Placez les deux blocs de code ci-dessus dans votre controllername.coffee
fichier, pour cet exemple, il devrait s'agir de chat.js.coffee
dans votre app/assets/javascript
annuaire. Vous devez également vous assurer qu'il est chargé dans le pipeline d'actifs. require
dans votre application.js
file (si vous n'appelez pas déjà require tree .
).
Activer les requêtes parallèles :
Dans votre environnement de développement, vous devrez activer les requêtes parallèles en ajoutant ces deux lignes à votre config/environments/development.rb
:
config.preload_frameworks = true
config.allow_concurrency = true
Lancez maintenant votre navigateur, accédez à /chat
et voir la magie. Lorsque vous tapez un message et cliquez sur le bouton, le message sera reçu par toutes les instances de cette page Web.
Eh bien, c'est ainsi que vous créez une application de chat de base dans rails
en utilisant ActionController::Live
et Redis
. Le code final serait évidemment très différent selon vos besoins, mais cela devrait vous aider à démarrer.
Quelques autres ressources que vous devriez consulter :
- Tender Love Making – Est-ce en direct ?
- Railscasts - #401 - ActionController::Live
- SitePoint - Mini chat avec Rails et SSE
- Github - mohanraj-ramanujam / diffusion en direct
- Thoughtbot – Exemple de chat utilisant des SSE