Voraussetzungen:
- Rubin 2.0.0+
- Rails 4.0.0+
- Redis
- Puma
Initialisierer:
Erstellen Sie eine redis.rb
initializer-Datei in config/initializers
Verzeichnis und globalisiert eine Instanz von redis
. Es ist auch eine gute Idee, einen heartbeat
einzurichten Thread (Alles zwischen 5 Sekunden und 5 Minuten ist in Ordnung, abhängig von Ihren Anforderungen):
$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
Verantwortlicher:
Sie müssen Ihrem ChatController
zwei Methoden hinzufügen , pub
und sub
. Die Rolle von pub
ist das Veröffentlichen von Chat-Ereignissen und Nachrichten auf redis
, und sub
um diese Veranstaltungen zu abonnieren. Es sollte etwa so aussehen:
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 Ihren routes
, machen pub ein POST
und sub ein GET
, und gleichen Sie den Pfad mit etwas wie /chat/publish
ab und /chat/subscribe
.
Kaffeeskript / Javascript:
Angenommen, Ihre eigentliche Webseite für die Chat-App befindet sich unter /chat
, müssen Sie etwas Javascript schreiben um tatsächlich Chatnachrichten zu senden und zu empfangen.
Nehmen wir zum besseren Verständnis an, Ihre Webseite hat nur ein Textfeld und eine Schaltfläche. Wenn Sie auf die Schaltfläche klicken, sollte der Inhalt des Textfelds im Chat-Stream veröffentlicht werden. Wir können dies mit AJAX tun:
$('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
Jetzt müssen Sie auch die Chat-Nachrichten abonnieren und empfangen können. Sie müssen EventSource
verwenden dafür. Verwenden von EventSource , öffnen Sie einen Kanal für SSE, damit Sie Ereignisse empfangen können, und verwenden Sie diese Daten, um die Ansicht zu aktualisieren. In diesem Beispiel werden wir sie nur in der Javascript-Konsole protokollieren.
Der Code sollte in etwa so aussehen:
$(document).ready ->
source = new EventSource('/chat/subscribe')
source.addEventListener 'chat_event', (e) ->
console.log(e.data)
Hinweis: Platzieren Sie die beiden obigen Codeblöcke in Ihrer controllername.coffee
Datei, für dieses Beispiel sollte es chat.js.coffee
sein in Ihrem app/assets/javascript
Verzeichnis. Sie müssen auch sicherstellen, dass es in die Asset-Pipeline geladen wird. require
es in Ihrer application.js
Datei (falls Sie nicht bereits require tree .
aufrufen ).
Parallele Anfragen aktivieren:
In Ihrer Entwicklungsumgebung müssen Sie parallele Anfragen aktivieren, indem Sie diese beiden Zeilen zu Ihrer config/environments/development.rb
hinzufügen :
config.preload_frameworks = true
config.allow_concurrency = true
Starten Sie jetzt Ihren Browser und navigieren Sie zu /chat
und sehe die Magie. Wenn Sie eine Nachricht eingeben und auf die Schaltfläche klicken, wird die Nachricht von allen Instanzen dieser Webseite empfangen.
Nun, so erstellen Sie eine einfache Chat-Anwendung in rails
mit ActionController::Live
und Redis
. Der endgültige Code würde natürlich je nach Ihren Anforderungen sehr unterschiedlich sein, aber dies sollte Ihnen den Einstieg erleichtern.
Einige weitere Ressourcen, die Sie sich ansehen sollten:
- Zärtliches Liebesspiel - ist es live?
- Railscasts - #401 - ActionController::Live
- SitePoint - Mini-Chat mit Rails und SSEs
- Github - mohanraj-ramanujam / Livestream
- Thoughtbot – Chat-Beispiel mit SSEs