Terjemahan artikel disiapkan khusus untuk siswa kursus "Framework Laravel" .
Pengguna web modern berharap mendapat informasi tentang semua yang terjadi dalam aplikasi. Anda tidak ingin menjadi situs web yang bahkan tidak memiliki daftar drop-down notifikasi, yang sekarang dapat ditemukan tidak hanya di semua situs jejaring sosial, tetapi umumnya di mana-mana saat ini.Untungnya, dengan Laravel dan Pusher, penerapan fungsi ini cukup sederhana.Pemberitahuan waktu nyata
Untuk memberikan pengalaman pengguna yang positif, pemberitahuan harus ditampilkan secara real time. Salah satu pendekatan adalah dengan secara teratur mengirim permintaan AJAX ke server dan menerima pemberitahuan terbaru, jika ada.Pendekatan terbaik adalah dengan menggunakan kemampuan WebSockets dan menerima notifikasi ketika dikirim. Inilah yang akan kami terapkan dalam artikel ini.Pendorong
Pusher adalah layanan web untuk mengintegrasikan fungsi dua arah real-time melalui WebSockets ke dalam aplikasi web dan seluler.Ini memiliki API yang sangat sederhana, tetapi kita akan membuatnya lebih mudah dengan Laravel Broadcasting dan Laravel Echo.Pada artikel ini, kami akan menambahkan notifikasi real-time ke blog yang ada.Proyek
Inisialisasi
Pertama, kami mengkloning blog Laravel sederhana:git clone https:
Kemudian kita akan membuat database MySQL dan mengatur variabel lingkungan untuk memberikan akses aplikasi ke database.Copy Mari env.example
di .env
dan memperbarui variabel yang terkait dengan database.cp .env.example .envDB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
Sekarang mari kita instal dependensi proyek menggunakancomposer install
Dan jalankan perintah migrasi dan isi untuk mengisi basis data dengan beberapa data:php artisan migrate --seed
Jika Anda menjalankan aplikasi dan pergi ke /posts
, Anda dapat melihat daftar posting yang dihasilkan.Periksa aplikasi, daftarkan pengguna dan buat beberapa pesan. Ini adalah aplikasi yang sangat sederhana, tetapi sangat bagus untuk demonstrasi.Berlangganan Pengguna
Kami ingin memberikan kesempatan kepada pengguna untuk berlangganan satu sama lain, jadi kami harus membuat hubungan banyak-ke-banyak di antara pengguna untuk mewujudkan hal ini.Mari kita buat tabel pivot yang menautkan pengguna ke pengguna. Mari lakukan migrasi baru followers
:php artisan make:migration create_followers_table --create=followers
Kami perlu menambahkan beberapa bidang ke migrasi ini: user_id
untuk mewakili pengguna yang berlangganan, dan bidang follows_id
untuk mewakili pengguna yang mereka berlangganan.Perbarui migrasi sebagai berikut:public function up()
{
Schema::create('followers', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->index();
$table->integer('follows_id')->index();
$table->timestamps();
});
}
Sekarang mari kita beralih ke membuat tabel:php artisan migrate
Mari menambahkan metode hubungan ke model User
.
class extends Authenticatable
{
public function followers()
{
return $this->belongsToMany(self::class, 'followers', 'follows_id', 'user_id')
->withTimestamps();
}
public function follows()
{
return $this->belongsToMany(self::class, 'followers', 'user_id', 'follows_id')
->withTimestamps();
}
}
Sekarang setelah model User
memiliki hubungan yang diperlukan, ia followers
mengembalikan semua pelanggan pengguna, dan follows
mengembalikan semua orang kepada siapa pengguna berlangganan.Kami akan memerlukan beberapa fungsi tambahan yang memungkinkan pengguna untuk berlangganan ke pengguna lain - follow
, dan untuk memeriksa apakah pengguna berlangganan ke pengguna tertentu - isFollowing
.
class extends Authenticatable
{
public function follow($userId)
{
$this->follows()->attach($userId);
return $this;
}
public function unfollow($userId)
{
$this->follows()->detach($userId);
return $this;
}
public function isFollowing($userId)
{
return (boolean) $this->follows()->where('follows_id', $userId)->first(['id']);
}
}
Baik. Setelah menyiapkan model, Anda perlu membuat daftar pengguna.daftar pengguna
Mari kita mulai dengan mengidentifikasi rute yang diperlukan./...
Route::group(['middleware' => 'auth'], function () {
Route::get('users', 'UsersController@index')->name('users');
Route::post('users/{user}/follow', 'UsersController@follow')->name('follow');
Route::delete('users/{user}/unfollow', 'UsersController@unfollow')->name('unfollow');
});
Maka sudah saatnya membuat pengontrol baru untuk pengguna:php artisan make:controller UsersController
Kami akan menambahkan metode untuk itu index
:
use App\User;
class UsersController extends Controller
{
public function index()
{
$users = User::where('id', '!=', auth()->user()->id)->get();
return view('users.index', compact('users'));
}
}
Metode ini perlu diperkenalkan. Mari kita buat tampilan users.index
dan letakkan markup berikut di dalamnya:@extends('layouts.app')
@section('content')
<div class="container">
<div class="col-sm-offset-2 col-sm-8">
<!-- Following -->
<div class="panel panel-default">
<div class="panel-heading">
All Users
</div>
<div class="panel-body">
<table class="table table-striped task-table">
<thead>
<th>User</th>
<th> </th>
</thead>
<tbody>
@foreach ($users as $user)
<tr>
<td clphpass="table-text"><div>{{ $user->name }}</div></td>
@if (auth()->user()->isFollowing($user->id))
<td>
<form action="{{route('unfollow', ['id' => $user->id])}}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" id="delete-follow-{{ $user->id }}" class="btn btn-danger">
<i class="fa fa-btn fa-trash"></i>Unfollow
</button>
</form>
</td>
@else
<td>
<form action="{{route('follow', ['id' => $user->id])}}" method="POST">
{{ csrf_field() }}
<button type="submit" id="follow-user-{{ $user->id }}" class="btn btn-success">
<i class="fa fa-btn fa-user"></i>Follow
</button>
</form>
</td>
@endif
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
@endsection
Sekarang Anda dapat mengunjungi halaman /users
untuk melihat daftar pengguna.Ikuti dan Berhenti Ikuti
Dalam UsersController
metode yang hilang follow
dan unfollow
. Mari kita implementasikan untuk menyelesaikan bagian ini.
class UsersController extends Controller
{
public function follow(User $user)
{
$follower = auth()->user();
if ($follower->id == $user->id) {
return back()->withError("You can't follow yourself");
}
if(!$follower->isFollowing($user->id)) {
$follower->follow($user->id);
$user->notify(new UserFollowed($follower));
return back()->withSuccess("You are now friends with {$user->name}");
}
return back()->withError("You are already following {$user->name}");
}
public function unfollow(User $user)
{
$follower = auth()->user();
if($follower->isFollowing($user->id)) {
$follower->unfollow($user->id);
return back()->withSuccess("You are no longer friends with {$user->name}");
}
return back()->withError("You are not following {$user->name}");
}
}
Kami selesai dengan fungsi ini. Sekarang kita dapat berlangganan pengguna dan berhenti berlangganan dari mereka di halaman /users
.Notifikasi
Laravel menyediakan API untuk mengirim pemberitahuan di berbagai saluran. Email, SMS, pemberitahuan web, dan jenis pemberitahuan lainnya dapat dikirim menggunakan kelas Pemberitahuan .Kami akan memiliki dua jenis pemberitahuan:- Pemberitahuan berlangganan: dikirim ke pengguna saat pengguna lain berlangganan
- Posting pemberitahuan: dikirim ke pelanggan pengguna ini ketika posting baru diterbitkan.
Pemberitahuan Berlangganan
Menggunakan perintah artisan, kami dapat membuat migrasi untuk pemberitahuan:php artisan notifications:table
Ayo lakukan migrasi dan buat tabel ini.php artisan migrate
Kami akan mulai dengan pemberitahuan berlangganan. Mari kita jalankan perintah ini untuk membuat kelas notifikasi:php artisan make:notification UserFollowed
Kemudian kami memodifikasi file kelas notifikasi yang baru saja kami buat:class UserFollowed extends Notification implements ShouldQueue
{
use Queueable;
protected $follower;
public function __construct(User $follower)
{
$this->follower = $follower;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'follower_id' => $this->follower->id,
'follower_name' => $this->follower->name,
];
}
}
Dengan beberapa baris kode ini, kita sudah dapat mencapai banyak hal. Pertama, kami mengharuskan instance $follower
diterapkan ketika pemberitahuan ini dihasilkan.Dengan menggunakan metode ini via
, kami memberi tahu Laravel untuk mengirim pemberitahuan ini melalui saluran database
. Ketika Laravel menemukan ini, itu membuat entri baru di tabel notifikasi.user_id
dan type
notifikasi diatur secara otomatis, ditambah kami dapat memperluas notifikasi dengan data tambahan. Itu untuk apa toDatabase
. Array yang dikembalikan akan ditambahkan ke bidang data
notifikasi.Dan akhirnya, berkat implementasinyaShouldQueue
, Laravel akan secara otomatis menempatkan notifikasi ini dalam antrian yang akan berjalan di latar belakang, yang akan mempercepat respons. Ini masuk akal karena kami akan menambahkan panggilan HTTP saat kami menggunakan Pusher nanti.Mari menerapkan pemberitahuan berlangganan pengguna.
use App\Notifications\UserFollowed;
class UsersController extends Controller
{
public function follow(User $user)
{
$follower = auth()->user();
if ( ! $follower->isFollowing($user->id)) {
$follower->follow($user->id);
$user->notify(new UserFollowed($follower));
return back()->withSuccess("You are now friends with {$user->name}");
}
return back()->withSuccess("You are already following {$user->name}");
}
}
Kami dapat memanggil metode notifikasi untuk model Pengguna karena sudah menggunakan fitur Notifiable.Model apa pun yang ingin Anda beri tahu harus menggunakannya untuk mendapatkan akses ke metode pemberitahuan.Kami menandai pemberitahuan saat dibaca.Pemberitahuan akan berisi beberapa informasi dan tautan ke sumber. Misalnya: ketika pengguna menerima pemberitahuan tentang pesan baru, pemberitahuan tersebut harus berisi teks informatif, mengarahkan pengguna ke pesan ketika ditekan dan ditandai sebagai sudah dibaca.Kami akan membuat layer yang akan memeriksa apakah ada kejadian dalam permintaan ?read=notification_id
dan menandainya sebagai sudah dibaca.Mari kita buat layer ini dengan perintah berikut:php artisan make:middleware MarkNotificationAsRead
Lalu mari kita letakkan kode ini dalam metode handle
interlayer:class MarkNotificationAsRead
{
public function handle($request, Closure $next)
{
if($request->has('read')) {
$notification = $request->user()->notifications()->where('id', $request->read)->first();
if($notification) {
$notification->markAsRead();
}
}
return $next($request);
}
}
Agar lapisan kami dieksekusi untuk setiap permintaan, kami akan menambahkannya ke $middlewareGroups
.
class Kernel extends HttpKernel
{
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\MarkNotificationAsRead::class,
],
];
}
Setelah itu, mari kita tampilkan notifikasi.Tampilkan pemberitahuan
Kita perlu menunjukkan daftar notifikasi menggunakan AJAX, dan kemudian memperbaruinya secara real time menggunakan Pusher. Pertama, mari kita tambahkan metode notifications
ke controller:
class UsersController extends Controller
{
public function notifications()
{
return auth()->user()->unreadNotifications()->limit(5)->get()->toArray();
}
}
Kode ini akan mengembalikan 5 notifikasi terakhir yang belum dibaca. Kami hanya perlu menambahkan rute agar dapat diakses.
Route::group([ 'middleware' => 'auth' ], function () {
Route::get('/notifications', 'UsersController@notifications');
});
Sekarang tambahkan daftar drop-down untuk notifikasi di header.<head>
<!--
<!-- Scripts -->
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
<!-- id JavaScript -->
@if(!auth()->guest())
<script>
window.Laravel.userId = <?php echo auth()->user()->id; ?>
</script>
@endif
</head>
<body>
<!--
@if (Auth::guest())
<li><a href="{{ url('/login') }}">Login</a></li>
<li><a href="{{ url('/register') }}">Register</a></li>
@else
<!--
<li class="dropdown">
<a class="dropdown-toggle" id="notifications" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span class="glyphicon glyphicon-user"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="notificationsMenu" id="notificationsMenu">
<li class="dropdown-header">No notifications</li>
</ul>
</li>
<!-- // ... // -->
Kami juga menambahkan variabel global window.Laravel.userId
ke skrip untuk mendapatkan ID pengguna saat ini.JavaScript dan SASS
Kita akan menggunakan Laravel Mix untuk mengkompilasi JavaScript dan SASS. Pertama, kita perlu menginstal paket npm.npm install
Sekarang mari kita tambahkan kode ini ke app.js
:window._ = require('lodash');
window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');
var notifications = [];
const NOTIFICATION_TYPES = {
follow: 'App\\Notifications\\UserFollowed'
};
Ini hanya inisialisasi. Kami akan menggunakan notifikasi untuk menyimpan semua objek notifikasi, apakah itu diambil melalui AJAX atau Pusher.Seperti yang mungkin sudah Anda tebak, ini NOTIFICATION_TYPES
berisi jenis pemberitahuan.Sekarang, mari kita dapatkan ("GET") pemberitahuan melalui AJAX.
$(document).ready(function() {
if(Laravel.userId) {
$.get('/notifications', function (data) {
addNotifications(data, "#notifications");
});
}
});
function addNotifications(newNotifications, target) {
notifications = _.concat(notifications, newNotifications);
notifications.slice(0, 5);
showNotifications(notifications, target);
}
Berkat kode ini, kami menerima pemberitahuan terbaru dari API kami dan memasukkannya ke daftar drop-down.Di dalam, addNotifications
kami menggabungkan pemberitahuan yang ada dengan yang baru menggunakan Lodash , dan hanya mengambil 5 yang terakhir, yang akan ditampilkan.Kami membutuhkan beberapa fungsi lagi untuk menyelesaikan pekerjaan.
function showNotifications(notifications, target) {
if(notifications.length) {
var htmlElements = notifications.map(function (notification) {
return makeNotification(notification);
});
$(target + 'Menu').html(htmlElements.join(''));
$(target).addClass('has-notifications')
} else {
$(target + 'Menu').html('<li class="dropdown-header">No notifications</li>');
$(target).removeClass('has-notifications');
}
}
Fungsi ini membuat garis semua pemberitahuan dan menempatkannya di daftar turun bawah.Jika tidak ada pemberitahuan yang diterima, cukup "Tidak ada pemberitahuan" ditampilkan.Itu juga menambahkan kelas ke tombol drop-down, yang hanya berubah warna ketika ada notifikasi. Agak seperti notifikasi Github.Akhirnya, beberapa fungsi pembantu untuk membuat string notifikasi.
function makeNotification(notification) {
var to = routeNotification(notification);
var notificationText = makeNotificationText(notification);
return '<li><a href="' + to + '">' + notificationText + '</a></li>';
}
function routeNotification(notification) {
var to = '?read=' + notification.id;
if(notification.type === NOTIFICATION_TYPES.follow) {
to = 'users' + to;
}
return '/' + to;
}
function makeNotificationText(notification) {
var text = '';
if(notification.type === NOTIFICATION_TYPES.follow) {
const name = notification.data.follower_name;
text += '<strong>' + name + '</strong> followed you';
}
return text;
}
Sekarang kita tambahkan ini ke file kita app.scss
:
color:
}
Mari kompilasi aset:npm run dev
Sekarang jika Anda mencoba berlangganan ke pengguna, ia akan menerima pemberitahuan. Ketika dia mengkliknya, dia akan dialihkan ke /users
, dan pemberitahuan itu sendiri menghilang.Pemberitahuan Posting Baru
Kami akan memberi tahu pelanggan ketika pengguna menerbitkan posting baru.Mari kita mulai dengan membuat kelas notifikasi.php artisan make:notification NewPost
Mari kita modifikasi kelas yang dihasilkan sebagai berikut:
use App\Post;
use App\User;
class NewArticle extends Notification implements ShouldQueue
{
protected $following;
protected $post;
public function __construct(User $following, Post $post)
{
$this->following = $following;
$this->post = $post;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'following_id' => $this->following->id,
'following_name' => $this->following->name,
'post_id' => $this->post->id,
];
}
}
Selanjutnya kita perlu mengirim pemberitahuan. Ada beberapa cara untuk melakukan ini.Saya suka menggunakan pengamat Eloquent.Mari kita buat pengamat untuk Post dan dengarkan acara-acaranya. Kami akan membuat kelas baru:app/Observers/PostObserver.php
namespace App\Observers;
use App\Notifications\NewPost;
use App\Post;
class PostObserver
{
public function created(Post $post)
{
$user = $post->user;
foreach ($user->followers as $follower) {
$follower->notify(new NewPost($user, $post));
}
}
}
Kemudian daftarkan pengamat di AppServiceProvider
:
use App\Observers\PostObserver;
use App\Post;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Post::observe(PostObserver::class);
}
}
Sekarang kita hanya perlu memformat pesan untuk ditampilkan di JS:
const NOTIFICATION_TYPES = {
follow: 'App\\Notifications\\UserFollowed',
newPost: 'App\\Notifications\\NewPost'
};
function routeNotification(notification) {
var to = `?read=${notification.id}`;
if(notification.type === NOTIFICATION_TYPES.follow) {
to = 'users' + to;
} else if(notification.type === NOTIFICATION_TYPES.newPost) {
const postId = notification.data.post_id;
to = `posts/${postId}` + to;
}
return '/' + to;
}
function makeNotificationText(notification) {
var text = '';
if(notification.type === NOTIFICATION_TYPES.follow) {
const name = notification.data.follower_name;
text += `<strong>${name}</strong> followed you`;
} else if(notification.type === NOTIFICATION_TYPES.newPost) {
const name = notification.data.following_name;
text += `<strong>${name}</strong> published a post`;
}
return text;
}
Dan voila! Pengguna diberitahu tentang langganan dan posting baru! Cobalah sendiri!Keluar secara real time dengan Pusher
Saatnya menggunakan Pusher untuk menerima notifikasi waktu nyata melalui soket web.Daftarkan akun Pusher gratis di pusher.com dan buat aplikasi baru....
BROADCAST_DRIVER=pusher
PUSHER_KEY=
PUSHER_SECRET=
PUSHER_APP_ID=
Tetapkan parameter untuk akun Anda di file konfigurasi broadcasting
:
'connections' => [
'pusher' => [
'options' => [
'cluster' => 'eu',
'encrypted' => true
],
],
Kemudian kita akan mendaftar App\Providers\BroadcastServiceProvider
di array providers
.
'providers' => [
App\Providers\BroadcastServiceProvider
],
Sekarang kita perlu menginstal SDK PHP dan Laravel Echo dari Pusher:composer require pusher/pusher-php-server
npm install --save laravel-echo pusher-js
Kita perlu mengatur data notifikasi untuk disiarkan. Mari modifikasi notifikasi UserFollowed
:
class UserFollowed extends Notification implements ShouldQueue
{
public function via($notifiable)
{
return ['database', 'broadcast'];
}
public function toArray($notifiable)
{
return [
'id' => $this->id,
'read_at' => null,
'data' => [
'follower_id' => $this->follower->id,
'follower_name' => $this->follower->name,
],
];
}
}
Dan NewPost
:
class NewPost extends Notification implements ShouldQueue
{
public function via($notifiable)
{
return ['database', 'broadcast'];
}
public function toArray($notifiable)
{
return [
'id' => $this->id,
'read_at' => null,
'data' => [
'following_id' => $this->following->id,
'following_name' => $this->following->name,
'post_id' => $this->post->id,
],
];
}
}
Hal terakhir yang perlu kita lakukan adalah memperbarui JS kita. Buka app.js
dan tambahkan kode berikut
window.Pusher = require('pusher-js');
import Echo from "laravel-echo";
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'your-pusher-key',
cluster: 'eu',
encrypted: true
});
var notifications = [];
$(document).ready(function() {
if(Laravel.userId) {
window.Echo.private(`App.User.${Laravel.userId}`)
.notification((notification) => {
addNotifications([notification], '#notifications');
});
}
});
Dan itu saja. Pemberitahuan ditambahkan secara real time. Sekarang Anda dapat bermain dengan aplikasi dan melihat bagaimana notifikasi diperbarui.Kesimpulan
Pusher memiliki API yang sangat user-friendly yang membuat implementasi acara real-time menjadi sangat sederhana. Dalam kombinasi dengan pemberitahuan Laravel, kami dapat mengirim pemberitahuan melalui beberapa saluran (email, SMS, Slack, dll.) Dari satu tempat. Dalam panduan ini, kami menambahkan fungsionalitas untuk melacak aktivitas pengguna di blog sederhana dan memperbaikinya menggunakan alat-alat di atas untuk mendapatkan fungsionalitas real-time yang lancar.Pusher dan Laravel memiliki lebih banyak notifikasi: bersama-sama, layanan memungkinkan Anda untuk mengirim pesan pub / sub secara real time ke browser, ponsel, dan perangkat IOT. Ada juga API untuk mendapatkan status pengguna online / offline.Silakan lihat dokumentasinya (dokumen Pusher, Tutorial Pusher , Laravel docs ) untuk informasi lebih lanjut tentang penggunaannya dan potensi sebenarnya.Jika Anda memiliki komentar, pertanyaan atau rekomendasi, jangan ragu untuk membagikannya di komentar di bawah!
Pelajari lebih lanjut tentang kursus.