menu

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


Melanjutkan tutorial sebelumnya, tutorial kali ini kita akan membuat handling pusher yang akan mengirimkan chat/notif ke websocket server, sekaligus membuat handling untuk client side nya.

Oke hal pertama yang dilakukan adalah membuat routes sebagai url target untuk mengirimkan chat/notif,
<?php
Route::group(['prefix' => 'chat', 'namespace' => 'Chat'], function () {
 Route::post('blast', 'ChatController@pushChat');
});

Setelah itu buat Controller untuk API yang akan mempush chat/notifikasi kita berinama ChatController.php dan isikan code berikut,
<?php

namespace App\Http\Controllers\Chat;

use App\Http\Controllers\Controller;

class ChatController extends Controller
{
 public function pushChat()
    {
        //websocket
        $result['type'] = 'chat';
        $result['data'] = 'hello world';
        $context = new \ZMQContext();
        $socket  = $context->getSocket(\ZMQ::SOCKET_PUSH, 'my pusher');
        $socket->connect("tcp://127.0.0.1:5555");
        $socket->send(json_encode($result));
        
        return response()->json(true);
    }
}

Untuk sisi clientnya kita akan membuat sebuah halaman web sebagai client untuk menerima chat/notifikasi dari API, buat file dengan nama chat-pusher.blade.php isi dengan code berikut,


Karena file nya sangat besar dan membuat error blogger, silahkan copy filenya dari sini,

Kemudian test pada postman, jika kita trigger di postman API yang sudah kita buat tadi maka pada sisi client buka pada browser url page chat-pusher.blade.php sehingga akan muncul seperti gambar dibawah,




===DONE!===




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!===