Broadcasting Laravel

LAMP Nov 18, 2020

Khái niệm: Laravel-echo là một công cụ hỗ trợ kết hợp công nghệ Websockets với ứng dụng giúp cho ta có thể tạo nên những ứng dụng realtime cực đơn giản chỉ với vài thao tác đơn giản ta đã có thể xây dựng được một ứng dụng realtime cho project của mình.

Bắt đầu nào :)
Đầu tiên để laravel-echo có thể hoạt động được ta cần phải cài đặt một số package sau:
Redis

composer require predis/predis

Socket.io

npm install --save-dev socket.io-client

Laravel-Echo

$ npm install -g laravel-echo-server

Sau khi install laravel-echo thành công mình sẽ phải chạy thêm lệnh nữa để khởi tạo máy chủ socket

$ laravel-echo-server init

Sau khi khởi tạo socket xong thì ta sẽ có một file mới trong dự án đó là file
laravel-echo-server.json tại thư mục root của dự án.
Như vậy là đã xong các bước setup môi trường. Mình có thể run máy chủ socket bằng câu lệnh sau:
$ laravel-echo-server start

Config:
.env

BROADCAST_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_PORT=6379

/resources/js/boostrap.js

import Echo from "laravel-echo"

window.io = require('socket.io-client');

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'
});

Tại đây chúng ta sẽ lắng nghe socket trên cổng 6001
/config/database.php

'redis' => [
    'client' => env('REDIS_CLIENT', 'predis'),
    ...
],

Trước khi broadcasting bất cứ một event nào. Ta phải đăng ký sử dụng Broadcast trong Provider. Thông thường phần config này sẽ bị comment trong provider, mình sẽ bỏ comment đi nhé

/*
 * Application Service Providers...
 */
....
App\Providers\BroadcastServiceProvider::class,
....

Bây giờ mình sẽ tạo Event để push đi một sự kiện bất kì nhé

php artisan make:event TestBroadcastingEvent

Thao tác này sẽ tạo ra một lớp để chúng ta có thể gửi một sự kiện ra phía client, Class này sẽ implements ShouldBroadcast

class ExampleEvent implements ShouldBroadcast

Bây giờ mình sẽ định nghĩa tên channel mà chúng ta sẽ phát đi

public function broadcastOn()
{
    return new Channel('test-event');
}

Ở đây test-event chính là tên channel nhé, lát nữa bên client mình sẽ lắng event nghe tại kênh này

Bây giờ mình sẽ định nghĩa một function nữa để chúng ta có thể gửi đi dữ liệu mà chúng ta cần

public function broadcastWith()
{
    return [
        'data' => 'key'
    ];
}

Ở đây khi mình gửi đi một sự kiện TestBroadcastingEvent thì mình sẽ gửi kèm thêm data là một mảng bao gồm key làm "data" và value là "key"

Controller:
Mình sẽ gửi đi một sự kiện đó là event(new EventName)

event(new TestBroadcastingEvent());

Như vậy là đã xong việc của ta, bây giờ chỉ đơn giản là chúng ta sẽ lắng nghe sự kiện này bên phía client bằng socket.io
Tại component

window.Echo.channel('laravel_database_test-event')
    .listen('TestBroadcastingEvent', (e) => {
        console.log(e);
    });

Ở đây, khi chúng ta gọi đến Controller thì mình sẽ gửi đi một sự kiện có tên là
TestBroadcastingEvent và bên phía client sẽ lắng nghe cái event mà ta vừa gửi đi. Ở đây Echo.channel('laravel_database_test-event') chính là tên channel mà chúng ta gửi đi, sở dĩ tên channel nó có thêm prefix là laravel-database là do trong file /config/database.php

'redis' => [

        'client' => env('REDIS_CLIENT', 'predis'),

        'options' => [
            'cluster' => env('REDIS_CLUSTER', 'redis'),
            'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
        ],

    ],

Chúng ta thấy option->prefix => env('REDIS_PREFIX',Str::slug(env('APP_NAME', 'laravel'), '_').'database'),
như vậy là nó được nối thêm tiền tố là env(APP_NAME) . '_'.'database'. Vì thế khi socket lắng nghe channel thì chúng ta cũng phải thêm vào. listen('TestBroadcastingEvent) là lớp sự kiện của mình.
Đến bước này coi như chúng ta đã có thể realtime rồi đó ::)

( Chú ý: ngoài việc setup như trên thì ta cũng cần phải cài một máy chủ redis thì bên socket mới có thể nghe được sự kiện mà chúng ta gửi đi nhé. phần này mọi người có thể search rồi tự install nhé :)
install redis server : https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-20-04 )

Run Project
+ php artisan serve
+ php artisan queue:work
+ laravel-echo-server start
(chú ý: nếu bạn đang code trên môi trường ubuntu thì mặc định redis-server luôn được start trên cổng :6379 . Mình sẽ không phải bật redis-server, còn nếu bạn code trên môi trườn window thì mình sẽ phải start redis bằng câu lệnh redis-server nhé.

Result
Mình mở 2 tab trên trình duyệt rồi gọi đến controller nơi mà broadcasting bật console.log

{data: 'key', socket: null}

Tổng kết
Như vậy việc tạo nên một ứng dụng realtime bằng laravel-echo cũng khá đơn giản, không quá phức tạp, mong rằng bài viết này của mình có thể giúp được gì đó trong khi làm dự án của bạn. Bye bye :)




Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.