Bouw een realtime chatapplicatie met modulus en Laravel 5

In deze tutorial laat ik je zien hoe je een real-time chat-applicatie implementeert met Laravel 5, PostgreSQL en Pusher. Vervolgens zullen we deze applicatie samen in Modulus implementeren.

We gebruiken Laravel 5 voor de back-endservice, HTML5 en jQuery voor een eenvoudige front-end applicatie, PostgreSQL voor de database en Pusher voor real-time communicatie tussen de server en clients. De algemene architectuur zal als volgt zijn:

Het scenario

  1. Een gebruiker opent de chattoepassing in een browser en geeft een bijnaam om door te gaan met de chat.
  2. De gebruiker voert tekst in en klikt op de Sturen knop.
  3. Het bericht zal worden afgehandeld door een dienst die is geschreven met Laravel 5 en zal worden bewaard in de database. 
  4. Het aanhoudende bericht wordt verzonden naar Pusher om een ​​nieuwe berichtgebeurtenis te activeren om dat bericht naar verbonden clients uit te zenden.
  5. Het nieuwe bericht wordt door de clients opgehaald en de chatberichtenlijst wordt vernieuwd voor alle verbonden clients. 

We zullen zeer bruikbare onderwerpen behandelen met dit scenario, zelfs als dit een zeer eenvoudige toepassing is. 

Milieu voorbereiding

Laravel Project Setup

Laten we eerst Laravel installeren, zodat we een chatservice kunnen schrijven voor onze applicatie. We zullen Composer gebruiken om Laravel en gerelateerde pakketten eenvoudig te installeren. Raadpleeg de website van Composer voor meer informatie over de installatie van Composer. Nadat u Composer hebt geïnstalleerd, opent u een opdrachtprompt en voert u de volgende opdracht uit om Laravel 5 te installeren:

componist global vereist "laravel / installer = ~ 1.1"

U ziet de uitvoer als volgt:

We zijn klaar om een ​​Laravel-project te genereren. Voer de volgende code uit om een ​​projectstructuur voor de chattoepassing te genereren.

laravel nieuwe RealtimeChatLaravel

Hiermee wordt een Laravel-project met boilerplate gegenereerd en ziet u de volgende mapstructuur:

Database

Onze applicatie zal communiceren met een database, en het zal PostgreSQL zijn. In dit project zullen we ElephantSQL gebruiken, een bedrijf dat PostgreSQL as a Service levert. U kunt verschillende soorten databases gebruiken met Laravel, zoals SQLite, MySQL, PostgreSQL en SQL Server. Ik heb PostgreSQL gekozen omdat, wanneer we ons project in Modulus implementeren, je geen interne database zoals de bovenstaande databasetypen kunt gebruiken. Ik gebruik liever een database die het als een service biedt. Met ElephantSQL kun je een aantal van de goede functies van PostgreSQL uitproberen met een gratis abonnement. 

U kunt een gratis plan van ElephantSQL gaan gebruiken om aan uw behoeften te voldoen. Wanneer u klaar bent met het maken van uw account en het maken van een database, weet u welke database-informatie u wilt hostnameDatabase naam, Gebruikersnaam, en Wachtwoord. Noteer die informatie om in Laravel te gebruiken voor databaseconfiguratie.

Pusher

Dit bedrijf biedt een service om evenementen te activeren voor real-time communicatie. Je kunt naar de Pusher-website gaan om er een te krijgen. Na het succesvol maken van een account en het maken van applicaties, kunt u enkele referenties krijgen zoals App-ID, App Secret, en App-sleutel. We zullen in de komende secties over hun gebruik praten.

Nginx

Om een ​​PHP-toepassing in Modulus te kunnen uitvoeren, moet een webserver zijn geconfigureerd voor uw toepassing. We zullen de volgende Nginx-configuratie gebruiken:

server luister 8080; servernaam modulus_app_url; root / mnt / app / public; index index.html index.php; locatie / try_files $ uri $ uri / /index.php?$query_string;  locatie ~ \ .php $ fastcgi_split_path_info ^ (. + \. php) (/.+) $; fastcgi_pass unix: /mnt/home/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name; fastcgi_index index.php; include fastcgi_params; 

We hebben de nodige omgevingsinstellingen voltooid om door te gaan met de ontwikkeling. Laten we naar het ontwerpgedeelte gaan.

Projectontwerp van Scratch

Model

Als u ooit eerder een ORM-framework hebt gebruikt, bent u bekend met dit onderwerp. In Laravel-projecten worden domeinmodellen geplaatst in de app / map standaard. In deze toepassing zullen we CRUD-bewerkingen uitvoeren op berichten, en dit betekent dat we een Bericht model-. 

Als u een model wilt maken, maakt u eenvoudig een klasse die de extensie uitbreidt Model klasse, een abstracte klasse in het Laravel-kernpakket Verlichten \ Database \ Welsprekend. Maak een bestand met de naam Message.php onder de app / map en plaats de volgende inhoud in het bestand:

Met dit model kunnen we eenvoudig verschillende databasegerelateerde bewerkingen uitvoeren. Bijvoorbeeld wanneer u de volgende query uitvoert:

het geeft je alle berichten uit de database. Hoe bepaalt het echter de tabelnaam die het in het resultaat zal ophalen? Het gebruikt de $ table waarde in de modelklasse. Wanneer u een nieuw bericht maakt, slaat het uw berichtmodel direct op naar de berichten tafel. We zullen in detail ingaan op modellen in de sectie Controller.

controleur

De controller is de plaats waar uw toepassingsgedrag is gedefinieerd. We voeren enkele berichtgerelateerde bewerkingen uit als ChatController bestaat in onze applicatie. We zullen vier eindpunten hebben voor onze applicatie:

  1. GET / login: voor het weergeven van de inlogpagina
  2. GET / chat: voor het weergeven van de chatpagina
  3. GET / berichten: voor het weergeven van de laatste vijf berichten die op de chatpagina worden weergegeven wanneer de gebruiker deze voor het eerst opent
  4. POST / berichten: voor het opslaan van een nieuw bericht

Om een ​​controller te maken, maakt u eenvoudig een klasse onder App \ Http \ Controllers en maak die klasse een Laravel-specifieke klasse uitbreiden controleur die bestaat in App \ Http \ Controllers. Wanneer u de /Log in of / chatten eindpunt, zullen ze hun eigen sjablonen maken onder resources / uitzicht. U kunt dat doen door de volgende acties te gebruiken.

class ChatController breidt Controller uit openbare functie getLogin () return view ("login");  openbare functie getChat () return view ("chat");  openbare functie saveMessage () if (Request :: ajax ()) $ data = Input :: all (); $ message = new Message; $ message-> author = $ data ["author"]; $ message-> message = $ data ["message"]; $ Bericht-> save (); Pusher :: trigger ('chat', 'message', ['message' => $ message]);  openbare functie lijstBerichten (bericht $ bericht) terugkeer antwoord () -> json ($ message-> orderBy ("created_at", "DESC") -> take (5) -> get ()); 

De eerste en tweede acties zullen specifieke pagina's weergeven. De derde actie is voor het opslaan van berichten. In deze actie wordt het eerste aanvraagtype gecontroleerd. Als het een AJAX-aanvraag is, krijgt het alle aanvraagtekst als een associatieve array. Deze array wordt gebruikt om het nieuw aangemaakte modelbericht in te vullen. 

Dan de opslaan() methode wordt direct uitgevoerd op het model om de database op te slaan. Telkens wanneer een nieuw bericht in de database wordt opgeslagen, wordt hetzelfde bericht naar Pusher verzonden door de bericht evenement. Wanneer u een gebeurtenis activeert, worden alle verbonden clients op de hoogte gebracht. Om de. Te gebruiken Pusher klasse in uw Laravel-projecten, kunt u het volgende doen:

  1. Pusher-gerelateerde pakketten vereisen via componist vereist vinkla / pusher.
  2. Voeg het Pusher-pakket toe, dat is Vinkla \ Pusher \ PusherServiceProvider :: klasse, naar de config / app.php.
  3. Gebruik Pusher-klassen in uw controllers, zoals Vinkla \ Pusher \ Gevels \ Pusher;, boven de controllerklasse.

Je bent in orde met de pakketten, maar hoe zit het met de Pusher-configuratie? U moet leveranciers in uw projecten publiceren met behulp van de volgende opdracht:

php artisan verkoper: publiceren

Met deze opdracht wordt een configuratiebestand gemaakt config / pusher.php, en u moet de vereiste inloggegevens opgeven die u kunt vinden in uw Push-dashboard. Het configuratiebestand ziet er als volgt uit:

'verbindingen' => ['main' => ['auth_key' => 'auth_key', 'secret' => 'geheim', 'app_id' => 'app_id', 'options' => [], 'host' => null, 'poort' => null, 'timeout' => null,], 'alternative' => ['auth_key' => 'uw-auth-sleutel', 'geheim' => 'uw geheim', 'app_id' => 'uw-app-id', 'opties' => [], 'host' => null, 'poort' => null, 'timeout' => null,],]

Het vierde eindpunt is voor het weergeven van de laatste vijf berichten die op de chatpagina worden weergegeven voor nieuw toegetreden gebruikers. De magische code is:

openbare functie listMessages (Message $ message) return response () -> json ($ message-> orderBy ("created_at", "DESC") -> take (5) -> get ()); 

In deze code, de Bericht model wordt geïnjecteerd in de actie of het uitvoeren van database-gerelateerde bewerkingen met behulp van $ message. Eerste orde berichten door gemaakt bij in aflopende volgorde en neem dan de laatste vijf. Het resultaat wordt geretourneerd in JSON-indeling met behulp van reactie () -> json (...)

We hebben het gehad over controllers en acties, maar hoe worden deze acties uitgevoerd wanneer een gebruiker naar een specifieke URL gaat? U kunt uw routeconfiguraties toevoegen aan het bestand app / Http / routes.php. U ziet een voorbeeld hieronder:

In dit gebruik worden de aanvraag-URI en verzoekmethode toegewezen aan de naam van de controller en de actienaam.

Dat is alles met de controllers. Laten we overschakelen naar het View-gedeelte.

Uitzicht

In dit gedeelte hebben we de Blade-sjabloonengine van Laravel gebruikt. Eigenlijk is er geen template engine-spul in onze projecten, maar als u waarden van de controller naar weergaven wilt verzenden, kunt u dit project direct gebruiken. 

We hebben twee weergavepagina's: login.blade.php en chat.blade.php. Zoals je ziet, is er een blade-sleutelwoord binnen de bestandsnamen van de weergave om aan te geven dat dit wordt gebruikt voor de Blade-sjabloonengine. 

De eerste is gewoon voor de inlogoperatie, dus laten we het hebben over de babbelen pagina. In dit viewbestand staan ​​JavaScript-bibliotheken van derden die worden bediend door een CDN-type jQuery, jQuery Cookie, bootstrap, en Pusher. We hebben een chatformulier om berichten te verzenden en Laravel zet een metabeschrijving op de pagina:

We sturen echter een chatbericht via AJAX en er zijn geen tokens in de AJAX-aanvraagheaders. We bieden een oplossing door het volgende codefragment te gebruiken:

$ .ajaxSetup (headers: 'X-CSRF-Token': $ ('meta [name = _token]'). attr ('content'));

Wanneer u een AJAX-verzoek verzendt, wordt dit token in de koptekst geplaatst. 

Om in realtime naar het berichtkanaal te luisteren, hebben we het volgende gebruikt:

var pusher = new Pusher ('app_id'); var channel = pusher.subscribe ('chat'); channel.bind ('message', function (data) var message = data.message; $ (".media-list li"). first (). remove (); $ (". media-lijst"). ('
  • '+ message.message +'
    '+ message.author +' | '+ message.created_at +'
  • '); );

    Allereerst hebben we een Pusher object met een APP_ID constructeur. En dan is een klant geabonneerd op het kanaal. Wanneer een nieuw evenement met de naam bericht aankomt, wordt een callback-functie uitgevoerd in de binden() functie. Het berichtenlijstgebied wordt vernieuwd met de nieuwe berichten. 

    Ten slotte, wanneer een nieuwe gebruiker de chatpagina opent, worden de laatste vijf berichten weergegeven in het berichtenlijstgebied met de volgende code:

    $ .get ("/ messages", functie (berichten) refreshMessages (messages));

    U kunt de broncode raadplegen om de volledige broncode van de weergavepagina's te analyseren.

    Deployment

    We zullen Modulus gebruiken voor het hosten van onze applicatie. 

    Modulus is een van de beste PaaS voor het implementeren, schalen en bewaken van uw toepassing in de taal van uw keuze. Voordat u doorgaat met de implementatie, gaat u naar Modulus en maakt u een account aan.

    voorwaarden

    Deployment is zeer eenvoudig in Modulus. Het enige dat u hoeft te doen is een Node.js-module installeren en een opdracht uitvoeren. Ook kun je je project zipen en uploaden naar Modulus. We geven de voorkeur aan de eerste optie in deze zelfstudie. 

    Ik neem aan dat u Node.js en npm al op uw computer hebt geïnstalleerd. Open eenvoudigweg een opdrachtregelprogramma en voer het uit npm install-g modulus. Na een succesvolle installatie meldt u zich aan bij uw Modulus-account met de Modulus CLI: modulus login. Als u zich wilt aanmelden met GitHub, kunt u gebruiken modulus login - github

    Nadat je bent ingelogd, maak een project met deze opdracht: modulus project creëer "RealtimeChatLaravel". U hebt een toepassing gemaakt op de zijde Modulus. 

    Het laatste dat u hoeft te doen is een map maken in de hoofdmap van uw project genaamd -sites-enabled, en plaats hier de Nginx-configuratie die we hierboven in de Nginx-sectie hebben genoemd -sites-enabled map. 

    Laten we uw project onder deze toepassing in Modulus implementeren. Uitvoeren modulus deploy om de implementatie te starten en het is klaar! Deze opdracht zal uw projectbestanden uploaden naar Modulus, en het zal ook de webserver configureren met behulp van de Nginx-configuratie die u in de -sites-enabled map. 

    Na een succesvolle implementatie krijgt u een bericht RealtimeChatLaravel loopt op http://realtimechatlaravel-51055.onmodulus.net/cha. Ga naar deze URL om een ​​werkende demo te zien. 

    Modulus CLI heeft zeer nuttige opdrachten om te gebruiken in de sectie Implementatie en runtime. U kunt bijvoorbeeld de logs van uw hardloopproject bijsturen modulus project logs staart, stel een omgevingsvariabele in met modulus env-set , enz. U kunt de volledige lijst met opdrachten zien met behulp van modulus hulp

    Conclusie

    Als u een PHP-webtoepassing bouwt, zult u onvermijdelijk webservers moeten gebruiken zoals Apache of NGINX; Als u Modulus gebruikt, kunt u zich eenvoudig concentreren op uw PHP-project. Met modulus kunt u uw webserverconfiguratie in uw project plaatsen, zodat dit van invloed is op het gebruik van uw code. 

    In deze zelfstudie hebben we ons gericht op de realtime chattoepassing en hebben we gezien dat de andere aspecten van de toepassing dankzij Modulus zeer eenvoudig te verwerken waren.