Tạo websocket bằng thư viện Ratchet Websocket trong Laravel

Trong hướng dẫn này, chúng ta sẽ thảo luận về Cách tạo websocket trong Laravel bằng cách sử dụng Thư viện Plugin Web Ratchet. Các ứng dụng phổ biến có sử dụng web socket như chat realtime, notification realtime, các dạng chart có dữ liệu động,… Không những thế, việc sử dụng các chức năng realtime còn tăng tính trải nghiệm người dùng. Vì vậy, nếu bạn đang tìm kiếm hướng dẫn về cách xây dựng websocket trong Laravel, thì bạn đã đến đúng nơi vì ở đây, mình sẽ xây dựng chức năng đó bằng cách sử dụng LaravelRatchet Web Socket.

Ratchet WebSocket là gì?

Ratchet WebSocket là Thư viện PHP cung cấp các công cụ cho nhà phát triển để tạo ứng dụng web thời gian thực trong đó máy khách và máy chủ được kết nối hai chiều, vì vậy máy khách trực tiếp gửi tin nhắn đến máy khách khác thông qua Web Socket này. Nó sẽ tạo đường hầm giữa hai hoặc nhiều khách hàng và họ có thể gửi và nhận tin nhắn trong thời gian thực. Ratchet WebSocket này sẽ tạo kết nối liên tục từ trình duyệt đến máy chủ và khi kết nối đã được thiết lập thì kết nối đó sẽ được mở cho đến khi máy khách hoặc máy chủ quyết định đóng nó. Vì vậy, trong chế độ kết nối mở, máy khách gửi tin nhắn cho máy khách khác.

Cài Đặt

Tải xuống và cài đặt thư viện Ratchet WebSocket

Trong Laravel, mình đã sử dụng Thư viện Ratchet WebSocket để tạo chức năng đổ thông báo theo thời gian thực. Vì vậy, trong phần này, mình sẽ tải xuống và cài đặt Thư viện Ratchet WebSocket. Để tải xuống Thư viện Ratchet WebSocket. Mình đã đi tới dấu nhắc lệnh và chạy lệnh sau.

composer require cboden/ratchet

Lệnh này sẽ tải xuống và cài đặt Thư viện Ratchet Websocket nằm trong thư mục vendor.

Sau đó để tạo một command dùng để khởi động websocket, chúng ta sử dụng lệnh sau:

php artisan make:command WebSocketServer --command=websocket:init

Sau khi chạy lệnh trên, hệ thống sẽ tạo ra file WebSocketServer.php nằm trong thư mục app/Console/Commands. Tiếp theo đó bạn vào file vừa tạo và thêm vào nội dung sau:

app/Console/Commands/WebSocketServer.php

<?php

namespace App\Console\Commands;
use Illuminate\Console\Command;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use React\EventLoop\Factory;
use App\Http\Controllers\SocketController;

class WebSocketServer extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'websocket:init';
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';
    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        //return 0;
        $server = IoServer::factory(
            new HttpServer(
                new WsServer(
                    new SocketController()
                )
            ),
            6001
        );
        $server->run();
    }
}

Máy chủ WebSocket này sẽ được chạy trên cổng 6001. Tiếp theo chúng ta phải tạo file SocketController.php như sau:

php artisan make:controller SocketController

Để websocket có thể nhận/gửi và xử lý thông tin, ta sẽ khai báo các nội dung sau trong file SocketController.php

app/Http/Controllers/SocketController.php

<?php

namespace App\Http\Controllers\v1;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class SocketController extends Controller implements MessageComponentInterface
{
    protected $clients;
    public function __construct()
    {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn)
    {
        $this->clients->attach($conn);
        echo "New connection! ({$conn->resourceId})\n";
        foreach($this->clients as $client)
        {
            if($client->resourceId == $conn->resourceId)
            {
                $client->send('Hi Client!');
            }
        }
    }
    public function onMessage(ConnectionInterface $conn, $msg)
    {
        $body = collect(json_decode($msg, true));
        foreach($this->clients as $client)
        {
            $client->send(json_encode($body));
        }
    }

    public function onClose(ConnectionInterface $conn)
    {
        $this->clients->detach($conn);
        foreach($this->clients as $client)
        {
            echo "Connection {$conn->resourceId} has disconnected\n";
            if($client->resourceId == $conn->resourceId)
            {
                $client->send("Connection {$conn->resourceId} has disconnected\n");
            }
        }
    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {
        echo "An error has occurred: {$e->getMessage()} \n";
        $conn->close();
    }
}
  • Hàm onOpen sẽ gửi tin nhắn thông báo đến bạn một khi bạn thực hiện kết nối thành công.
  • Hàm onMessage sẽ nhận tin nhắn khi có một kết nối đang mở, tại nơi đây bạn có thể xử lý các thông tin và lọc dữ liệu, gửi đi tin nhắn đích đến người sử dụng, đây là nơi đóng vai trò như là một controller xử lý các tác vụ và trả ra kết quả.
  • Hàm onClose sẽ đóng kết nối
  • Hàm onError sẽ đóng kết nối khi có lỗi không may xảy ra trong quá trình sử dụng websocket

Để khởi động websocket ta gõ lệnh:

php artisan websocket:init

Để kiểm tra xem websocket có hoạt động hay không, bạn sử dụng postman tạo Websocket Request như hình

Ô Messages hiển thị trạng thái connected tức là đã kết nối thành công, từ đây bạn có thể coding theo ý muốn của bạn, tạo chức năng đổ thông báo realtime.

Như vậy, mình đã hoàn thành thành bài hướng dẫn về cách tạo websocket dành cho Laravel. Thật không khó để triển khai phải không nào.

Chúc các bạn thành công!

Tài liệu kham khảo

  1. https://www.webslesson.info/2022/09/real-time-laravel-ratchet-websocket-chat-application.html
  2. http://socketo.me/
One thought on “Tạo websocket bằng thư viện Ratchet Websocket trong Laravel”
Leave a Comment