12/08/2018, 15:10

Real-time Apps with Laravel 5.1 and Event Broadcasting

Trong Laravel gồm có broadcasting event, cái làm cho nó dễ dàng để tạo các ứng dụng thời gian thực trong PHP. Với chức năng mới này, một ứng dụng có thể sinh ra các sự kiện thời gian thực dựa vào các giải pháp cloud-based real-time PubSub khác nhau, như Pusher hoặc Redis. Trong bài viết này tôi ...

Trong Laravel gồm có broadcasting event, cái làm cho nó dễ dàng để tạo các ứng dụng thời gian thực trong PHP. Với chức năng mới này, một ứng dụng có thể sinh ra các sự kiện thời gian thực dựa vào các giải pháp cloud-based real-time PubSub khác nhau, như Pusher hoặc Redis.

Trong bài viết này tôi sẽ tạo ví dụ đơn giản và biến nó thành một ứng dụng reat-time sử dụng broadcasting events của Laravel.

Download and Install App

Chúng ta sẽ bắt đầu code trong thư mục todo-app bằng việc clone một git repo:

git clone https://github.com/cwt137/l51-todo-app todo-app

Sau khi clone hoàn thành, vào trong thư mục todo-app. Chúng ta cần để cài đặt tất cả các Dependencies của ứng dụng bằng cách chạy câu lệnh sau:

composer install

Sau khi tất cả các Dependencies được cài đặt, bạn phải thiết lập database của bạn bằng chạy lệnh:

php artisan migrate

Adding Real-time Capabilities to the App

Thêm reat-time sẽ cho phép của sổ trình duyệt của bạn cập nhập nội dung mà không phải refresh lại trang. Trong ví dụ này chúng ta sẽ định nghĩa 3 class Laravel event. Event đầu tiên là event ItemCreated, cái được kích hoạt khi một item mới được tạo. Tiếp theo là event ItemUpdate, cái được kích hoạt khi một item được cập nhập. Cuối cùng là event ItemDeleted, cái được kích hoạt khi một item bị xóa.

Broadcasting Events

Để làm được broadcasting events, chúng ta sẽ tạo ra các Laravel event, chúng ta sẽ implement một interface ShouldBroadcast. Nếu Laravel thấy rằng một lớp event implement ShouldBroadcast nó biết rằng nó là một broadcasting event. Interface này yêu cầu chúng ta phải định nghĩa một phương thức bên trong lớp event của chúng ta được gọi là broadcastOn. Nó sẽ trả về một mảng các chuỗi, đó là những kênh mà event này được phát sóng.

Để tạo class event chúng ta cần chạy các lệnh sau:

php artisan make:event ItemCreated
php artisan make:event ItemUpdated
php artisan make:event ItemDeleted

Mở file app/Events/ItemCreated.php và thay thế nội dung với code dưới dây:

<?php

namespace AppEvents;

use AppItem;
use AppEventsEvent;
use IlluminateQueueSerializesModels;
use IlluminateContractsBroadcastingShouldBroadcast;

class ItemCreated extends Event implements ShouldBroadcast
{
    use SerializesModels;

    public $id;

    /**
     * Create a new event instance.
     *
     * @param Item $item
     * @return void
     */
    public function __construct(Item $item)
    {
        $this->id = $item->id;
    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        return ['itemAction'];
    }
}

Hệ thống event của Laravel sẽ sắp xếp object này và broadcast nó ra hệ thống real-time cloud sử dụng kênh itemAction. Mở file app/Events/ItemUpdated.php và thay thế nội dung với code dưới đây:

<?php

namespace AppEvents;

use AppItem;
use AppEventsEvent;
use IlluminateQueueSerializesModels;
use IlluminateContractsBroadcastingShouldBroadcast;

class ItemUpdated extends Event implements ShouldBroadcast
{
    use SerializesModels;

    public $id;
    public $isCompleted;

    /**
     * Create a new event instance.
     *
     * @param Item $item
     * @return void
     */
    public function __construct(Item $item)
    {
        $this->id = $item->id; 
        $this->isCompleted = (bool) $item->isCompleted;
    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        return ['itemAction'];
    }
}

Mở file app/Events/ItemDeleted.php và thay thế nội dung với code dưới đây:

<?php

namespace AppEvents;

use AppItem;
use AppEventsEvent;
use IlluminateQueueSerializesModels;
use IlluminateContractsBroadcastingShouldBroadcast;

class ItemDeleted extends Event implements ShouldBroadcast
{
    use SerializesModels;

    public $id;

    /**
     * Create a new event instance.
     *
     * @param Item $item
     * @return void
     */
    public function __construct(Item $item)
    {
        $this->id = $item->id;
    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        return ['itemAction'];
    }
}

Database Events

Có một vài vị trí trong project chúng ta có thể bắn các sự kiện cho project. Chúng ta có thể làm điều đó bên trong controller, hoặc bên trong database event triggers. Trong ví dụ này, chúng ta sẽ sử dụng trong database triggers, bằng cách đặt event bắn bên trong tầng database, làm cho nó có thể bắn các sự kiện khi một chương trình command-line được xây dựng hoặc khi một ứng dụng được xây dựng như một cron job. Eloquent, the database library, bắn các event mỗi khi một model được tạo ra, lưu sau khi cập nhật, hoặc xóa. Chúng ta sẽ lắng nghe những event đó vì vậy chúng ta có thể bắn các broadcasting event. Điều này sẽ được thực hiện thông qua một service provider. Mở file app/Providers/AppServiceProvider.php và thay thế nội dung với code sau:

<?php

namespace AppProviders;

use Event;
use AppItem;
use AppEventsItemCreated;
use AppEventsItemUpdated;
use AppEventsItemDeleted;
use IlluminateSupportServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Item::created(function ($item) {
            Event::fire(new ItemCreated($item));
        });

        Item::updated(function ($item) {
            Event::fire(new ItemUpdated($item));
        });

        Item::deleted(function ($item) {
            Event::fire(new ItemDeleted($item));
        });
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Pusher

Các dịch vụ đám mây thời gian thực, chúng ta sẽ sử dụng trong ví dụ này là Pusher. Hỗ trợ cho các dịch vụ này được xây dựng vào trong Laravel và dễ để thiết lập.

Registration

Chúng ta phải đăng ký tài khoản để có các thông tin cấu hình. Sau khi đăng ký trên Pusher website, hãy vào màn hình quản trị và tạo ra một ứng dụng mới có tên gọi là todo-app. Hãy chú ý đến app_id, key và secret, chúng ta sẽ cần nó sau:

Pusher PHP Server Library

Đối với ứng dụng của chúng ta để sử dụng Pusher, chúng ta phải thêm thư viện đến dự án của chúng tôi. Điều này được thực hiện thông qua lệnh composer.

composer require 'pusher/pusher-php-server:2.2.1'

JavaScript

Chúng ta sẽ thêm Javascript vào trang home của chúng ta. Mở file resources/views/index.blade.php và thêm code dưới đây:

<script src='http://js.pusher.com/2.2/pusher.min.js'></script>
<script>
    var pusher = new Pusher('{{ env(PUSHER_KEY) }}');
</script>
<script src='js/pusher.js'></script>

Đoạn mã trên tải các thư viện client Pusher Javascript, thể hiện đối tượng Pusher bằng cách thông qua key của chúng ta vào constructor. Trong ứng dụng, các item bị xóa và thêm vào dựa trên các event xảy ra trên trang (form submit, delete icon clicked, etc). Đây là lý do tại sao khi chúng tôi mở hai cửa sổ trình duyệt, cả hai đã không được cập nhật. Một cửa sổ trình duyệt không thể nhìn thấy những gì đang xảy ra trong cửa sổ trình duyệt khác. Để thực hiện các ứng dụng thời gian thực, chúng ta sẽ thêm và xóa các mục dựa trên các event đến từ Pusher.

Tạo file public/js/pusher.js và điền code dưới đây:

(function($, pusher, addItem, removeItem) {

var itemActionChannel = pusher.subscribe('itemAction');

itemActionChannel.bind('AppEventsItemCreated', function(data) {
     addItem(data.id, false);
});

itemActionChannel.bind('AppEventsItemUpdated', function(data) {
    removeItem(data.id);
    addItem(data.id, data.isCompleted);
});

itemActionChannel.bind('AppEventsItemDeleted', function(data) {
    removeItem(data.id);
});
})(jQuery, pusher, addItem, removeItem);

Ứng dụng theo dõi kênh itemAction. Theo mặc định, Lavavel sử dụng tên class của đối tượng event như tên Pusher event. Các mã Javascript ở trên để thiết lập lắng nghe cho ba event AppEventItemCreated, AppEventItemUpdated, và AppEventItemDeleted. Có các callback có thể xử lý những gì sẽ xảy ra khi những event này được kích hoạt.

Testing the Realtime App

Để test ứng dụng, bạn cần có key của Pusher. Mở file .env và điền code dưới đây:

PUSHER_KEY=YOUR_PUSHER_KEY
PUSHER_SECRET=YOUR_PUSHER_SECRET
PUSHER_APP_ID=YOUR_PUSHER_APP_ID

Điều này sẽ thiết lập biến môi trường. Giá trị YOUR_PUSHER_KEY, YOUR_PUSHER_SECRET, YOUR_PUSHER_APP_ID tương ứng với key, secret and app_id trong Pusher của bạn.

Final Thoughts

Với các chức năng broadcasting events mới xây dựng vào Laravel 5.1, nó bây giờ đã dễ dàng hơn cho các nhà phát triển PHP để tạo ra các ứng dụng thời gian thực. Khả năng xử lý thời gian thực mới này mở ra nhiều khả năng mà chỉ có sẵn cho các ứng dụng được viết cho các nền tảng khác như Node.js.

Nguồn: Real-time Apps with Laravel 5.1 and Event Broadcasting

0