Erstellen Sie mit Rails 5 API Action Cable und ReactJS ein Chat-System mit mehreren privaten Räumen und einer Gruppen-Chat-Option

Bitte beachten Sie, dass dieser Beitrag kein Tutorial ist und Kenntnisse über Rails 5 ActionCable und ReactJS / Javascript zur Erstellung einer benutzerdefinierten Bibliothek erfordert.

Eine der großartigen Funktionen von Rails 5 ist ActionCable. Mit ActionCable können Sie alle denkbaren Echtzeitfunktionen über den Websocket erstellen. Während ich mich bemühte, ein Chat-System aufzubauen, hatte ich im Internet mehrere Beispiele dafür gefunden, wie man mit Rails 5 ActionCable eine Chat-App erstellt, aber sie sind extrem einfach, um das Konzept auch für echte Chat-Anwendungen anzuwenden. Ich glaube, dies ist das erste Beispiel im Internet, das Ihnen zeigt, wie Sie ein solches Chat-System aufbauen können:

  • Rails 5 API-Backend und ein ReactJS-Frontend
  • Mehrere private Räume
  • Beliebige positive Anzahl von Benutzern in einem Raum (nicht nur 1–1) oder Gruppenchat

Das Chat-System, das mein talentierter Freund Tim Chang und ich aufgebaut haben, hat:

  1. Mehrere private Chatrooms
  2. Mehrere Chat-Benutzer pro Raum
  3. Online- / Offline-Status jedes Benutzers
  4. Echtzeitstatus „Tippen…“
  5. Echtzeit-Lesebestätigung
So sieht unser Endergebnis aus. (Dieser Beispielartikel zeigt Ihnen jedoch nicht die Front-End-Arbeit.)

In diesem kurzen Beitrag zeige ich Ihnen nur die Grundlagen von # 1 und # 2. Bitte hinterlasse mir einen Kommentar, wenn ich dir zeigen soll, wie man # 3, # 4 und # 5 baut. Ich verwende Rails 5 als Back-End-API und ReactJS-Bibliothek im Front-End.

Backend

Bei der Erstellung generiert Rails die Channels-Ordner und -Dateien, in denen die ganze Magie in Echtzeit abläuft :)

app / channels / application_cable / channel.rb
app / channels / application_cable / connection.rb

Authentifizierung

Lassen Sie uns zunächst die Websocket-Verbindungsanforderungen an Ihren Rails-Server in connection.rb authentifizieren.

Abhängig vom Authentifizierungs-Gem oder -Dienst, den Sie in Ihrem Projekt verwenden, sollte die find_verified_user-Methode an Ihre Anforderungen angepasst werden. Ich habe eine Methode namens valid_token? um das Access-Token und die client_id zu überprüfen, die mit der Websocket-Anforderung übergeben wurden. Wenn die Anforderung nicht authentifiziert ist, wird sie abgelehnt.

Datenstruktur

Die Idee ist sehr einfach: Ein Chatroom, der mehrere Nachrichten enthält, jede Nachricht hat einen Inhalt und einen Absender. Beachten Sie, dass eine Nachricht keinen "Empfänger" hat. Auf diese Weise kann ein Raum beliebig viele Benutzer haben, da Sie sich nicht um den Empfänger der Nachrichten kümmern müssen, da alle Nachrichten der Absender in einem Raum angezeigt werden, unabhängig davon, wie viele Teilnehmer sich im Raum befinden. Das ist also die Datenstruktur, die ich verwende:

  • Konversation (Raum): has_many Nachrichten, Benutzer und hat eine ID
  • Nachricht: gehört zu einer Konversation, hat einen Absender, hat den Textinhalt
  • Absender: ist ein Benutzer

Als Ergebnis habe ich 3 Modelle erstellt:

Aktionsauslöser

Wenn ein Client eine Verbindung herstellt (abonniert) oder eine Nachricht sendet (spricht), reagiert das Backend mit Aktionen. Im Ordner app / channels erstelle ich eine Datei mit dem Namen room_channel.rb.

Wie Sie im Kommentar sehen können, wird die Sendung noch nicht gesendet, nachdem ein Kunde „gesprochen“ hat. Es wird nur eine neue Nachricht mit ihrem Inhalt und ihren Daten erstellt. Die Aktionskette beginnt, nachdem die Nachricht in der Datenbank gespeichert wurde. Schauen wir uns das Nachrichtenmodell noch einmal an:

after_create_commit {MessageBroadcastJob.perform_later (self)}

Skalierbarkeit

Dieser Rückruf wird erst aufgerufen, nachdem die Nachricht erstellt und in die Datenbank geschrieben wurde. Ich verwende Hintergrundjobs, um diese Aktion zu skalieren. Stellen Sie sich vor, Sie haben Tausende von Clients, die gleichzeitig Nachrichten senden (dies ist ein Chat-System, warum nicht?). Die Verwendung eines Hintergrundjobs ist hier eine Voraussetzung.

Hier ist, wenn der Rundfunk passiert. ActionCable sendet die Nutzlast mit der bereitgestellten Nutzlast an den angegebenen Raum.

ActionCable.server.broadcast (Raumname, Nutzlast)

Kabeltrasse

Sie müssen Ihrer routes.rb die / cable-Websocket-Route hinzufügen, damit Ihr Client diesen Endpunkt zum Senden und Empfangen von Nachrichten anrufen kann.

ActionCable.server einhängen => '/ cable'

Und das war's für die Backend-Seite! Werfen wir einen Blick auf die ReactJS-Front-End-Bibliothek.

Client-Bibliothek

Bitte beachten Sie, dass Sie abhängig von den Besonderheiten Ihres Projekts das Konzept dieses Codes in dieser Bibliothek verstehen und an Ihre Bedürfnisse anpassen müssen.

Installieren Sie zuerst das ActionCableJS über npm.

Erstellen Sie eine ChatConnection.js-Datei als einen der Dienste in Ihrer ReactJs-App.

Hier ist also der Haken: In createRoomConnection versucht der Client, eine Verbindung zu dem RoomChannel herzustellen (zu abonnieren), den wir im Backend erstellt haben. Sobald die Verbindung hergestellt ist (zu abonnieren), wird sie vom Raumnamen ChatRoom-id gestreamt (siehe room_channel). rb oben nochmal) Sobald es verbunden ist, gibt es 2 Methoden, die häufig aufgerufen werden. Können Sie raten, welche?

Sie sind: empfangen und sprechen!

Die empfangene Methode wird aufgerufen, wenn eine Nachricht vom Server an den Client gesendet wird, während speak aufgerufen wird, wenn der Client eine Nachricht an den Server sendet.

Voila! Das ist es. Auch dies ist kein fertiges Tutorial, da jedes Projekt anders ist, aber ich hoffe, es gibt Ihnen eine Idee, wie Sie ein Chat-System mit mehreren privaten Chat-Räumen aufbauen können und mehrere Benutzer pro Raum. Bitte lassen Sie mich im Kommentarbereich wissen, wenn Sie Fragen haben.