Laravel (5.7) Вещание
Во многих современных веб-приложениях WebSockets используются для реализации обновляемых в реальном времени пользовательских интерфейсов. Когда некоторые данные обновляются на сервере, сообщение обычно отправляется через соединение WebSocket для обработки клиентом. Это обеспечивает более надежную и эффективную альтернативу постоянному опросу вашего приложения на предмет изменений.
Чтобы помочь вам в создании приложений такого типа, Laravel облегчает «трансляцию» ваших событий через соединение WebSocket. Трансляция ваших событий Laravel позволяет вам совместно использовать одни и те же имена событий между вашим серверным кодом и вашим клиентским JavaScript-приложением.
Конфиг обзора:
Вы должны будете убедиться, что ваша конфигурация настроена так, чтобы вводить ваши учетные данные Pusher.
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true,
],
],
AppProvidersBroadcastServiceProvider.php
Через документы:
Перед трансляцией каких-либо событий вам необходимо сначала зарегистрировать AppProvidersBroadcastServiceProvider. В свежих приложениях Laravel вам нужно только раскомментировать этого провайдера в массиве провайдера вашего файла конфигурации config / app.php. Этот провайдер позволит вам регистрировать широковещательные маршруты авторизации и обратные вызовы.
маршруты / broadcasting.php
Широковещательные маршруты - это в основном простые охранники, которые проверяют сущность перед тем, как разрешить частное соединение. Пользователи должны быть авторизованы перед подключением к частным каналам. Нам нужен только канал аутентификации по умолчанию для доступа к нашим уведомлениям для этой демонстрации.
Канальные маршруты - это обратные вызовы авторизации, используемые для проверки, может ли аутентифицированный пользователь прослушивать канал. Вместо того, чтобы возвращать данные, они возвращают авторизованный статус для частного канала. По сути, это маршруты, которые отвечают только статусом охраны.
Конечная точка: 'http: // localhost / broadcasting / auth'
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
** Название каждого маршрута отражает пространство имен объекта, который требует авторизации.
Поставщик услуг вещания
Для того, чтобы использовать наши API маршруты с маршрутами вещания. Сначала мы должны обновить наш BroadcastServiceProvider, чтобы использовать «auth: api» вместо «web».
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
* @return void
*/
public function boot()
{
Broadcast::routes(["middleware" => ["auth:api"]]);
require base_path('routes/channels.php');
}
}
Метод входа
Вы можете загрузить уведомления текущего пользователя при входе в систему. Это позволит вам помещать существующие уведомления в ваш компонент без дополнительного HTTP-запроса. (Вам нужно будет присвоить свойство вашим реактивным данным)
response.data.currentUser.notifications
return response(array(
'currentUser' => $user->loadMissing('notifications'),
));
Настройка компонентов
Давайте настроим наши компоненты леса. Нам нужно будет импортировать наши библиотеки JS, а также настроить свойства и шаблон.
import Echo from 'laravel-echo'
import Pusher from 'pusher-js'
export default {
name: 'laravel-echo',
data() {
return {
echo: null
}
},
computed: {
//Add computed properties
currentUser: { ...},
isConnected: { ...},
notifications: { ...},
},
watch: {
//Add watchers...
},
methods: {
//Add methods...
}
}
<template>
<div id="laravel-echo">
<template v-if="isConnected">
<ul v-for="object in notifications">
{{ object }}
</ul>
<button @click="disconnect">Disconnect</button>
</template>
<template v-else-if="currentUser">
<button @click="connect">Connect</button>
</template>
</div>
</template>
Вычисленные свойства
Далее нам понадобится наш аутентифицированный пользователь, а также состояние нашего соединения и свойство реактивного хранилища. В этом примере я использую Vuex State Management. (вы можете использовать локальные свойства вместо вычисленных, если вы не используете Vuex)
currentUser: {
cache: false,
get(){ return this.$store.getters.currentUser }
},
notifications: {
cache: false,
get(){ return this.$store.getters.notifications.reverse() }
},
isConnected: {
cache: false,
get(){
return (this.echo && this.echo.connector.pusher.connection.connection !== null)
}
},
(currentUser, isConnected)
Мы можем наблюдать за нашим состоянием и автоматически подключаться, когда компонент загружен и присутствует currentUser, а также автоматически отключаться, когда пользователь имеет значение null .
watch: {
currentUser: {
handler(currentUser){
(currentUser !== null ? this.connect() : this.disconnect())
}
},
isConnected: {
handler(isConnected){
this.$emit('broadcasting:status', isConnected)
}
}
},
Добавить метод: connect ()
В этом примере мы будем использовать собственную аутентификацию api_token Laravel вместо web & CSRF. / ** Connect Echo ** /
connect(){
if(!this.echo){
this.echo = new Echo({
broadcaster: 'pusher',
key: 'XXX',
cluster: 'us2',
encrypted: true,
authEndpoint: 'http://localhost/broadcasting/auth',
auth: {
headers: {
Authorization: null
}
},
//csrfToken: null,
//namespace: 'App',
})
this.echo.connector.pusher.connection.bind('connected', (event) => this.connect(event))
this.echo.connector.pusher.connection.bind('disconnected', () => this.disconnect())
}
this.echo.connector.pusher.config.auth.headers.Authorization ='Bearer ' + this.currentUser.api_token
this.echo.connector.pusher.connect()
}
Добавить метод: bindChannels ()
Метод bindChannels () связывает обратные вызовы канала, которые фиксируют каждое сообщение в нашем $ store (или назначает локальные свойства). * Обратите внимание, что Echo предоставляет метод специально для обработки уведомлений. ** Поскольку мы имеем дело с типом Array, вам нужно добавить () новый элемент в массив.
/ ** Связать каналы ** /
bindChannels(){
let vm = this
this.echo.private('App.User' + '.' + this.currentUser.id)
.notification((object) => vm.$store.commit('addNotification', object))
},
or for local data use:
this.echo.private('App.User' + '.' + this.currentUser.id)
.notification((object) => vm.notifications.push(object))
Добавить метод: disconnect ()
Метод disconnect () позволит нам включить / выключить наше соединение.
/ ** Отключить Эхо ** /
disconnect(){
if(!this.echo) return
this.echo.disconnect()
},
Использование компонента:
Если вы используете Vue Router, как я, вы захотите поместить его в свой корневой компонент, чтобы он продолжал работать, пока пользователи перемещаются по приложению.
<router-view/>...
<broadcasting ref="broadcasting"/>
this.$refs.broadcasting.connect()
this.$refs.broadcasting.disconnect()
Часть 3: Уведомления
php artisan make:notification TestBroadcastNotification
В этом примере мы используем уведомления.
<?php namespace App\Notifications;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\BroadcastMessage;
class TestBroadcastNotification extends Notification
{
use Queueable;
public $object;
/**
* Create a new notification instance.
* @param $object object
* @return void
*/
public function __construct($object)
{
$this->object = $object;
}
/**
* Get the notification's delivery channels.
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return [
//'database', (migration required)
//'mail',
'broadcast',
];
}
/**
* Get the broadcastable representation of the notification.
* @param mixed $notifiable
* @return BroadcastMessage
*/
public function toBroadcast($notifiable)
{
$timestamp = Carbon::now()->addSecond()->toDateTimeString();
return new BroadcastMessage(array(
'notifiable_id' => $notifiable->id,
'notifiable_type' => get_class($notifiable),
'data' => $this->object,
'read_at' => null,
'created_at' => $timestamp,
'updated_at' => $timestamp,
));
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return (array) $this->object;
}
}
Метод toBroadcast ()
Поскольку наше уведомление еще не сохранено в базе данных, нам нужно будет смоделировать наш объект уведомления, чтобы он соответствовал тому, что загружено из нашей базы данных, когда мы обычно запрашиваем уведомления пользователя. Мы можем использовать Carbon для создания временной метки в 1 секунду в будущем, чтобы соответствовать нашему фактическому уведомлению, когда оно будет окончательно сохранено. (если у вас есть лучший способ справиться с этим, пожалуйста, поделитесь!)
$timestamp = Carbon::now()->addSecond()->toDateTimeString();
return new BroadcastMessage(array(
'notifiable_id' => $notifiable->id,
'notifiable_type' => get_class($notifiable),
'data' => $this->object,
'read_at' => null,
'created_at' => $timestamp,
'updated_at' => $timestamp,
));
Добавить: Тестовый маршрут
маршруты / api.php
Route::any('test', function(){
$user = \App\User::findOrFail(1);
$data = (object) array(
'test' => 123,
);
$user->notify(new \App\Notifications\TestBroadcastNotification($data));
return response()->json($data);
});
Предыдущий: Laravel (5.7) Artisan Console
Далее: Laravel (5,7) Кэш
Новый контент: Composer: менеджер зависимостей для PHP , R программирования