menu

Engine - Push websocket from API Laravel with Thruway Part-1


Artikel pertama ditahun baru, setelah lama istirahat menulis saatnya codedoct kembali membagikan ilmu tentang pengkodingan.

Pada artikel sebelumnya kita sudah membuat sebuah engine websocket menggunakan Ratchet yang di push melalui API dengan framework Laravel. Dan ada beberapa masalah yang muncul ketika menggunakan Ratchet ini salah satunya adalah Ratchet saat tulisan ini dibuat hanya support menggunakan WAMPv1 yang ini berarti Ratchet hanya bisa menggunakan AutobahnJS versi 0.8 seperti yang sudah kita buat pada artikel sebelumnya.

Sedangkan ada masalah yang muncul jika kita menggunakan AutobahnJS versi 0.8 yaitu tidak ada support untuk auto reconnect client ke server websocket, itulah sebabnya kita harus menaikan versi AutobahnJS menjadi versi 0.9 sayangnya AutobahnJS versi 0.9 ini mempunyai minimal requirement WAMPv2 yang itu artinya AutobahnJS versi 0.9 ini tidak support dengan Ratchet karena kekurangan itulah maka artikel ini akan menjadi penyempurna artikel sebelumnya, yaitu dengan membuat engine push websocket menggunakan Thruway (engine yang lebih baru dibandingkan Ratchet).

Requirements yang codedoct gunakan adalah,
  1. Laravel versi 5.4
  2. PHP versi 5.6
  3. Thruway voryx versi 0.5
  4. ZMQ versi 0.3
Sebelum memulai, pastikan ZeroMQ sudah terinstall pada PHP dan web server, jika belum klik disini(MAC OS) atau disini(Ubuntu OS).

Oke langsung saja kita mulai eksperimennya.
Pertama, download Thruway dan dependencies,
$ php composer.phar require voryx/thruway
$ php composer.phar require thruway/pawl-transport

Kemudian, buat file command laravel untuk dijalankan di server dengan cara,

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

Syntax di atas akan secara otomatis membuat file baru dengan nama WebSocketServer.php pada path app/Console/Commands/ edit file tersebut sehingga akan tampak seperti ini,
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use React\EventLoop\Factory;
use React\ZMQ\Context;

use Thruway\Peer\Router;
use Thruway\Peer\Client;
use Thruway\Transport\RatchetTransportProvider;

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';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->info("start server");
        $loop = Factory::create();
        $pusher = new Client("codedoct", $loop);

        $pusher->on('open', function ($session) use ($loop) {
           $context = new Context($loop);
           $pull = $context->getSocket(\ZMQ::SOCKET_PULL);
           $pull->bind('tcp://127.0.0.1:5555');

           $pull->on('message', function ($msg) use ($session) {
              $msg_data = json_decode($msg, true);
              if (isset($msg_data['type'])) {
                 $session->publish($msg_data['type'], [$msg_data]);
              }
           });
        });

        $router = new Router($loop);
        $router->addInternalClient($pusher);
        $router->addTransportProvider(
           new RatchetTransportProvider("0.0.0.0", 8080)
        );
        $router->start();
    }
}

Code websocket server diatas akan kita panggil melalui command php artisan untuk itu kita harus menambahkannya pada kernel laravel, yang terletak pada path app/Console/ dengan nama file Kernel.php edit bagian command menjadi seperti ini,
/**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        Commands\WebSocketServer::class,
    ];

Oke jika semua sudah selesai saatnya kita coba run WebSocketServer nya dengan cara,
$ php artisan websocket:init

Sehingga akan tampak seperti ini tampilannya,


===DONE!===