Ich habe vorher gesagt, dass ich ein Tutorial zum Thema Event-Broadcasting zusammenstellen würde. Heute habe ich endlich Zeit, diesen Artikel zu schreiben. Dieses Tutorial basiert auf Laravel+Pusher+Vue, mit Event-Broadcasting als Kerntechnologie, sodass Sie es schnell erstellen können eine Echtzeit-Chatroom-Anwendung, werfen wir ohne weiteres einen Blick auf den spezifischen Inhalt.
Anwendungsinitialisierung
Installationskonfiguration
Installieren Sie zunächst eine neue Chatroom-Anwendung über Composer:
composer create-project laravel/laravel chatroom --prefer-dist
Seit Ihnen Sie müssen die Ereignisübertragung verwenden, daher müssen Sie den Kommentar vor dem Übertragungsdienstanbieter in config/app.php löschen:
Ändern Sie das Konfigurationselement BROADCAST_DRIVER in . env to pusher:
BROADCAST_DRIVER=pusher
Obwohl Laravel Pusher standardmäßig unterstützt, müssen wir dennoch das entsprechende PHP SDK installieren:
composer require pusher/pusher-php-server
Set Pusher Anmeldeinformationen
Greifen Sie auf die offizielle Pusher-Website zu, registrieren Sie sich und melden Sie sich beim Benutzer-Backend an, erstellen Sie eine neue Channels-App:
Nachdem die Erstellung abgeschlossen ist, können Sie Informationen zu App-Schlüsseln erhalten Sie auf der Sprungseite:
Füllen Sie die entsprechenden Felder in die entsprechenden Konfigurationselemente in .env im Stammverzeichnis der Chatroom-Anwendung aus.
Front-End-Ressourceninitialisierung
Wir verwenden Laravel Mix, um Front-End-CSS und JavaScript zu kompilieren:
npm install
Darüber hinaus bietet Laravel auch die JavaScript-Bibliothek Laravel Echo zum Abonnieren an und achten Sie auf Ereignisse:
npm install --save laravel-echo pusher-js
Nachdem die Installation abgeschlossen ist, müssen Sie Laravel Echo auch anweisen, Pusher zu verwenden. Laravel hat uns diese Implementierung in resources/assets/js/bootstrap.js bereitgestellt, aber das ist der Fall Standardmäßig auskommentiert. Sie müssen diesen Kommentar nur abbrechen:
rrreeBenutzerauthentifizierungs-Gerüstcode
Wir haben festgelegt, dass nur angemeldete Benutzer den Chatraum betreten können Um den Prozess zu vereinfachen, verwenden wir die Standard-Benutzerauthentifizierungsfunktion von Laravel:
import Echo from 'laravel-echo' window.Pusher = require('pusher-js'); window.Echo = new Echo({ broadcaster: 'pusher', key: process.env.MIX_PUSHER_APP_KEY, cluster: process.env.MIX_PUSHER_APP_CLUSTER, encrypted: true });
Der obige Befehl generiert für uns die Routing-, Ansichten-, Controller- und anderen Codes, die für das Benutzerauthentifizierungssystem erforderlich sind. Bevor die Funktion wirksam wird, müssen Sie den Datenbankmigrationsbefehl ausführen, um die entsprechende Datentabelle zu generieren, die datenbankbezogenen Konfigurationselemente in .env bearbeiten, um sicherzustellen, dass Sie korrekt eine Verbindung zur Datenbank herstellen können, und dann den folgenden Befehl ausführen:
php artisan make:auth
An diesem Punkt sind die Vorbereitungen für die Anwendungsinitialisierung abgeschlossen. Beginnen wir mit dem Schreiben von Geschäftscode.
Geschäftscode-Implementierung
Nachrichtenmodell
Erstellen Sie zunächst eine Modellklasse und die entsprechende Datenbankmigrationsdatei für die gesendete Nachricht:
php artisan migrate
Fügen Sie der neu generierten App-/Nachrichtenmodellklasse die folgende Codezeile hinzu, um die Stapelzuweisung zu erleichtern:
php artisan make:model Message -m
Schreiben Sie dann die Up-Methode der neu generierten Nachrichten entsprechend der Migrationsdatei in das Verzeichnis „databases/migrations“. :
/** * Fields that are mass assignable * * @var array */ protected $fillable = ['message'];
Führen Sie abschließend den Migrationsbefehl aus, um die Datentabellennachrichten zu generieren:
Schema::create('messages', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->unsigned(); $table->text('message'); $table->timestamps(); });
Zuordnung zwischen Benutzern und Nachrichten
Offensichtlich besteht eine Eins-zu-viele-Beziehung zwischen Benutzer und Nachrichten. Fügen Sie eine neue Zuordnungsmethode in der Benutzermodellklasse hinzu:
php artisan migrate
Definieren Sie als Nächstes die entsprechende Zuordnung in der Nachrichtenmodellklasse:
/** * A user can have many messages * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function messages() { return $this->hasMany(Message::class); }
Controller-Code
Erstellen control Der Controller ChatsController implementiert eine spezifische Geschäftslogik:
/** * A message belong to a user * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() { return $this->belongsTo(User::class); }
Schreiben Sie die neu generierte Controller-Klasse app/Http/Controllers/ChatsController. Der Code lautet wie folgt:
php artisan make:controller ChatsController
Der Controller bietet drei Geschäftsmethoden: index verwendet zum Anzeigen der Chatroom-Ansicht fetchMessages zum Abrufen aller Nachrichten und sendMessage zum Senden von Nachrichten.
Anwendungsrouten registrieren
Entsprechend registrieren wir drei Routen in Routen/web.php:
<?php namespace App\Http\Controllers; use Auth; use App\Message; use Illuminate\Http\Request; use Illuminate\Http\Response; class ChatsController extends Controller { public function __construct() { $this->middleware('auth'); // 登录用户才能访问 } /** * Show chats * * @return \Illuminate\Http\Response */ public function index() { return view('chat'); } /** * Fetch all messages * * @return Message */ public function fetchMessages() { return Message::with('user')->get(); } /** * Persist message to database * * @param Request $request * @return Response */ public function sendMessage(Request $request) { $user = Auth::user(); $message = $user->messages()->create([ 'message' => $request->input('message') ]); return ['status' => 'Message Sent!']; } }
Entfernen Sie die /home-Route entsprechend aus den registrierten Routen Passen Sie das Attribut $redirectTo in app/Http/Controllers/Auth/LoginController.php und app/Http/Controllers/Auth/RegisterController.php an:
Route::get('/', 'ChatsController@index'); Route::get('messages', 'ChatsController@fetchMessages'); Route::post('messages', 'ChatsController@sendMessage');
Chatroom-Ansicht
Für den Chatroom Zum Anzeigen des Codes haben wir geringfügige Anpassungen basierend auf dem Code-Snippet des Bootsnipp-Chatrooms vorgenommen. Erstellen Sie zunächst resources/views/chat.blade.php:
protected $redirectTo = '/';
Diese Ansicht wird verwendet, um die Hauptseite des Chatrooms anzuzeigen. Beachten Sie, dass wir einige Vue-Komponenten in der Ansicht verwenden. Die Chat-Nachrichtenkomponente wird zum Anzeigen aller Chat-Nachrichten und die Chat-Formularkomponente zum Senden von Nachrichten verwendet. Der Code für diese Komponenten wird später angegeben.
Bevor wir die Vue-Komponente schreiben, fügen wir etwas Stilcode für die Chat-Ansicht in der Vorlage resources/views/layouts/app.blade.php hinzu (bevor wir ihn dem
-Tag hinzufügen):@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading">聊天室</div> <div class="panel-body"> <chat-messages :messages="messages"></chat-messages> </div> <div class="panel-footer"> <chat-form v-on:messagesent="addMessage" :user="{{ Auth::user() }}" ></chat-form> </div> </div> </div> </div> </div> @endsection
Als nächstes erstellen Sie die ChatMessages.vue-Komponente in resources/assets/js/components:
<style> .chat { list-style: none; margin: 0; padding: 0; } .chat li { margin-bottom: 10px; padding-bottom: 5px; border-bottom: 1px dotted #B3A9A9; } .chat li .chat-body p { margin: 0; color: #777777; } .panel-body { overflow-y: scroll; height: 350px; } ::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); background-color: #F5F5F5; } ::-webkit-scrollbar { width: 12px; background-color: #F5F5F5; } ::-webkit-scrollbar-thumb { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); background-color: #555; } </style>
Dann erstellen Sie die ChatForm.vue-Komponente im selben Verzeichnis:
<template> <ul class="chat"> <li class="left clearfix" v-for="message in messages"> <div class="chat-body clearfix"> <div class="header"> <strong class="primary-font"> {{ message.user.name }} </strong> </div> <p> {{ message.message }} </p> </div> </li> </ul> </template> <script> export default { props: ['messages'] }; </script>
Endlich haben wir Dies muss hinzugefügt werden. Zwei Komponenten werden in der Vue-Stamminstanz registriert, die sich in resources/assets/js/app.js befindet:
<template> <div class="input-group"> <input id="btn-input" type="text" name="message" class="form-control input-sm" placeholder="在这里输入要发送的消息..." v-model="newMessage" @keyup.enter="sendMessage"> <span class="input-group-btn"> <button class="btn btn-primary btn-sm" id="btn-chat" @click="sendMessage"> 发送 </button> </span> </div> </template> <script> export default { props: ['user'], data() { return { newMessage: '' } }, methods: { sendMessage() { this.$emit('messagesent', { user: this.user, message: this.newMessage }); this.newMessage = '' } } } </script>
Ereignis zum Senden von Nachrichten senden
Um eine Interaktion in Echtzeit zu ermöglichen Im Chatroom ist die Übertragung bestimmter Ereignisse erforderlich. In diesem Fall lösen wir das MessageSent-Ereignis aus, wenn der Benutzer eine Nachricht sendet:
require('./bootstrap'); window.Vue = require('vue'); Vue.component('chat-messages', require('./components/ChatMessages.vue')); Vue.component('chat-form', require('./components/ChatForm.vue')); const app = new Vue({ el: '#app', data: { messages: [] }, created() { this.fetchMessages(); }, methods: { fetchMessages() { axios.get('/messages').then(response => { this.messages = response.data; }); }, addMessage(message) { this.messages.push(message); axios.post('/messages', message).then(response => { console.log(response.data); }); } } });
Schreiben Sie den Ereignisklassencode app/Events/MessageSent wie folgt:
<?php namespace App\Events; use App\Message; use App\User; use Illuminate\Broadcasting\Channel; use Illuminate\Queue\SerializesModels; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class MessageSent implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; /** * User that sent the message * * @var User */ public $user; /** * Message details * * @var Message */ public $message; /** * Create a new event instance. * @param User $user * @param Message $message * @return void */ public function __construct(User $user, Message $message) { $this->user = $user; $this->message = $message; } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { return new PrivateChannel('chat'); } }
由于只有登录用户才能访问我们的应用,所以我们定义了一个私有的频道 chat,只有登录用户才能连接上它。
接下来,我们需要修改 ChatsController 的 sendMessage() 来广播 MessageSent 事件:
public function sendMessage(Request $request) { $user = Auth::user(); $message = $user->messages()->create([ 'message' => $request->input('message') ]); broadcast(new MessageSent($user, $message))->toOthers(); return ['status' => 'Message Sent!']; }
然后在 routes/channels.php 中授权当前登录用户可以监听该私有频道:
Broadcast::channel('chat', function ($user) { return Auth::check(); });
现在,当一条消息发送后,MessageSent 事件就会被广播到 Pusher,使用 toOthers() 是为了将消息发送者从广播接收者中排除。
监听消息发送事件
MessageSent 事件在服务端被广播后,需要在客户端监听这个事件以便将最新发送消息更新到聊天室消息流中,我们可以通过在 resources/assets/js/app.js 中定义的 created() 方法中添加如下代码片段来实现这一功能:
created() { this.fetchMessages(); Echo.private('chat') .listen('MessageSent', (e) => { this.messages.push({ message: e.message.message, user: e.user }); }); },
我们通过 Laravel Echo 连接到 chat 频道监听 MessageSent 广播事件,如果有新消息则将其推送到当前聊天室消息流中显示。
在正式测试聊天室应用之前,还需要运行以下命令通过 Laravel Mix 来编译前面编写的 JavaScript 代码:
npm run dev
使用示例
完成上述所有业务代码编写工作后,接下来就是见证工作成果的时候了,在项目根目录下运行如下命令启动应用:
php artisan serve
然后在浏览器通过 http://127.0.0.1:8000/ 访问应用,由于系统需要登录后才能访问,所以首先会跳转到登录页面,我们需要先注册一个新用户,注册成功后页面即跳转到聊天室页面,我们发送一条测试消息。
为了测试多个用户聊天的效果,打开另一个浏览器或者在当前浏览器新开一个隐身窗口,还是重复上面的访问注册步骤(注册名不同),注册成功后跳转到聊天室页面,看到的效果和上面一样,我们再发条消息试试。
可以看到两个窗口消息是同步的,所以已经达到我们预期的实时聊天效果,实现了通过事件广播构建实时聊天室的功能。
以上就是本篇文章的全部内容了,更多laravel内容请关注laravel框架入门教程。
相关文章推荐:
laravel框架中TokenMismatchException的异常处理内容
Laravel 5.1框架中的ACL用户授权和权限检查功能的实现
相关课程推荐:
Das obige ist der detaillierte Inhalt vonEchtzeit-Chatroom: implementiert durch Event-Broadcast auf Basis von Laravel+Pusher+Vue. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!