Heim > PHP-Framework > Laravel > Hauptteil

Echtzeit-Chatroom: implementiert durch Event-Broadcast auf Basis von Laravel+Pusher+Vue

不言
Freigeben: 2018-07-31 15:48:54
Original
5373 Leute haben es durchsucht

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
Nach dem Login kopieren

Seit Ihnen Sie müssen die Ereignisübertragung verwenden, daher müssen Sie den Kommentar vor dem Übertragungsdienstanbieter in config/app.php löschen:

Echtzeit-Chatroom: implementiert durch Event-Broadcast auf Basis von Laravel+Pusher+Vue

Ä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
Nach dem Login kopieren

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:

Echtzeit-Chatroom: implementiert durch Event-Broadcast auf Basis von Laravel+Pusher+Vue

Nachdem die Erstellung abgeschlossen ist, können Sie Informationen zu App-Schlüsseln erhalten Sie auf der Sprungseite:

Echtzeit-Chatroom: implementiert durch Event-Broadcast auf Basis von Laravel+Pusher+Vue

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
Nach dem Login kopieren

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
Nach dem Login kopieren

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:

rrree

Benutzerauthentifizierungs-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
});
Nach dem Login kopieren

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
Nach dem Login kopieren

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
Nach dem Login kopieren
Nach dem Login kopieren

Fügen Sie der neu generierten App-/Nachrichtenmodellklasse die folgende Codezeile hinzu, um die Stapelzuweisung zu erleichtern:

php artisan make:model Message -m
Nach dem Login kopieren

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'];
Nach dem Login kopieren

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();
});
Nach dem Login kopieren

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
Nach dem Login kopieren
Nach dem Login kopieren

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);
}
Nach dem Login kopieren

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);
}
Nach dem Login kopieren

Schreiben Sie die neu generierte Controller-Klasse app/Http/Controllers/ChatsController. Der Code lautet wie folgt:

php artisan make:controller ChatsController
Nach dem Login kopieren

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(&#39;auth&#39;);  // 登录用户才能访问
    }
    /**
     * Show chats
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view(&#39;chat&#39;);
    }
    /**
     * Fetch all messages
     *
     * @return Message
     */
    public function fetchMessages()
    {
        return Message::with(&#39;user&#39;)->get();
    }
    /**
     * Persist message to database
     *
     * @param  Request $request
     * @return Response
     */
    public function sendMessage(Request $request)
    {
        $user = Auth::user();
        $message = $user->messages()->create([
            &#39;message&#39; => $request->input(&#39;message&#39;)
        ]);
        return [&#39;status&#39; => &#39;Message Sent!&#39;];
    }
}
Nach dem Login kopieren

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(&#39;/&#39;, &#39;ChatsController@index&#39;);
Route::get(&#39;messages&#39;, &#39;ChatsController@fetchMessages&#39;);
Route::post(&#39;messages&#39;, &#39;ChatsController@sendMessage&#39;);
Nach dem Login kopieren

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 = &#39;/&#39;;
Nach dem Login kopieren

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(&#39;layouts.app&#39;)
@section(&#39;content&#39;)
    <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
Nach dem Login kopieren

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>
Nach dem Login kopieren

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: [&#39;messages&#39;]
    };
</script>
Nach dem Login kopieren

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: [&#39;user&#39;],
        data() {
            return {
                newMessage: &#39;&#39;
            }
        },
        methods: {
            sendMessage() {
                this.$emit(&#39;messagesent&#39;, {
                    user: this.user,
                    message: this.newMessage
                });
                this.newMessage = &#39;&#39;
            }
        }    
    }
</script>
Nach dem Login kopieren

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(&#39;./bootstrap&#39;);
window.Vue = require(&#39;vue&#39;);
Vue.component(&#39;chat-messages&#39;, require(&#39;./components/ChatMessages.vue&#39;));
Vue.component(&#39;chat-form&#39;, require(&#39;./components/ChatForm.vue&#39;));
const app = new Vue({
    el: &#39;#app&#39;,
    data: {
        messages: []
    },
    created() {
        this.fetchMessages();
    },
    methods: {
        fetchMessages() {
            axios.get(&#39;/messages&#39;).then(response => {
                this.messages = response.data;
            });
        },
        addMessage(message) {
            this.messages.push(message);
            axios.post(&#39;/messages&#39;, message).then(response => {
                console.log(response.data);
            });
        }
    }
});
Nach dem Login kopieren

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(&#39;chat&#39;);
    }
}
Nach dem Login kopieren

由于只有登录用户才能访问我们的应用,所以我们定义了一个私有的频道 chat,只有登录用户才能连接上它。

接下来,我们需要修改 ChatsController 的 sendMessage() 来广播 MessageSent 事件:

public function sendMessage(Request $request)
{
    $user = Auth::user();
    $message = $user->messages()->create([
        &#39;message&#39; => $request->input(&#39;message&#39;)
    ]);
    broadcast(new MessageSent($user, $message))->toOthers();
    return [&#39;status&#39; => &#39;Message Sent!&#39;];
}
Nach dem Login kopieren

然后在 routes/channels.php 中授权当前登录用户可以监听该私有频道:

Broadcast::channel(&#39;chat&#39;, function ($user) {
    return Auth::check();
});
Nach dem Login kopieren

现在,当一条消息发送后,MessageSent 事件就会被广播到 Pusher,使用 toOthers() 是为了将消息发送者从广播接收者中排除。

监听消息发送事件

MessageSent 事件在服务端被广播后,需要在客户端监听这个事件以便将最新发送消息更新到聊天室消息流中,我们可以通过在 resources/assets/js/app.js 中定义的 created() 方法中添加如下代码片段来实现这一功能:

created() {
    this.fetchMessages();
    Echo.private(&#39;chat&#39;)
        .listen(&#39;MessageSent&#39;, (e) => {
            this.messages.push({
                message: e.message.message,
                user: e.user
            });
        });
},
Nach dem Login kopieren

我们通过 Laravel Echo 连接到 chat 频道监听 MessageSent 广播事件,如果有新消息则将其推送到当前聊天室消息流中显示。

在正式测试聊天室应用之前,还需要运行以下命令通过 Laravel Mix 来编译前面编写的 JavaScript 代码:

npm run dev
Nach dem Login kopieren

使用示例

完成上述所有业务代码编写工作后,接下来就是见证工作成果的时候了,在项目根目录下运行如下命令启动应用:

php artisan serve
Nach dem Login kopieren

然后在浏览器通过 http://127.0.0.1:8000/ 访问应用,由于系统需要登录后才能访问,所以首先会跳转到登录页面,我们需要先注册一个新用户,注册成功后页面即跳转到聊天室页面,我们发送一条测试消息。

为了测试多个用户聊天的效果,打开另一个浏览器或者在当前浏览器新开一个隐身窗口,还是重复上面的访问注册步骤(注册名不同),注册成功后跳转到聊天室页面,看到的效果和上面一样,我们再发条消息试试。

可以看到两个窗口消息是同步的,所以已经达到我们预期的实时聊天效果,实现了通过事件广播构建实时聊天室的功能。

以上就是本篇文章的全部内容了,更多laravel内容请关注laravel框架入门教程。

相关文章推荐:

laravel框架中TokenMismatchException的异常处理内容

Laravel 5.1框架中的ACL用户授权和权限检查功能的实现

相关课程推荐:

2017年最新的五个Laravel视频教程推荐

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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage