menu

Engine - Deploy websocket server Laravel in EC2(AWS) part-2


Melanjutkan tutorial sebelumnya kita sudah mensetting port pada EC2 server dan menjalankan serverpilot. Nah tibalah pada masalah secure website yang menggunakan "https", ada dua cara untuk mengatasi masalah ini.

Yang pertama dengan menyediakan secure websocket server dengan code seperti dibawah,
<?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 React\Socket\SecureServer;
use React\Socket\Server;
use App\Http\Controllers\WebSocketController;
class WebSocketSecureServer extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'websocketsecure: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()
    {
        $loop   = Factory::create();
        $webSock = new SecureServer(
            new Server('0.0.0.0:8091', $loop),
            $loop,
            array(
                'local_cert'        => 'C:/xampp/apache/conf/ssl.crt/server.crt', // path to your cert
                'local_pk'          => 'C:/xampp/apache/conf/ssl.key/server.key', // path to your server private key
                'allow_self_signed' => TRUE, // Allow self signed certs (should be false in production)
                'verify_peer' => FALSE
            )
        );
        // Ratchet magic
        $webServer = new IoServer(
            new HttpServer(
                new WsServer(
                    new WebSocketController()
                )
            ),
            $webSock
        );
        $loop->run();
    }
}

Tapi saya tidak menganjurkan menggunakan cara diatas dikarenakan cara itu hanya berlaku untuk websocket yang menggunakan ratchet jika suatu saat kita akan menggunakan websocket lain maka kita harus mensetup untuk secure servernya juga, sangat merepotkan bukan?. Maka dari itu codedoct menyarankan untuk mensetting langsung pada servernya dengan cara mengalihkan secure connection "wss" ke unsecure connection "ws" dengan menggunakan server proxy.

Oke kita mulai saja setup secure connectionnya,
Pertama, silahkan enabled modul proxy nya terlebih dahulu dengan cara,
$ sudo a2enmod proxy
$ sudo a2enmod proxy_http
$ sudo a2enmod ssl
$ sudo service apache2 restart

Kemudian, karna saya menggunakan apache2 untuk menjalankan server web yang saya miliki maka buka apache.conf dengan cara,
$ vim /etc/apache2/apache2.conf

Selanjutnya tambahkan code dibawah pada baris paling atas,
ProxyRequests off
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off

ProxyPass /wss2/ ws://<ip public>:8080/

Setelah itu ubah connection websocket pada halaman client menjadi seperti ini,
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>user 1</title>
 </head>
 <body>
  <button onclick="register()">Register</button><br>
  <button onclick="send()">Send</button>

  <script>
   var conn = new WebSocket('wss://<url domain>/wss2/');

   conn.onopen = function(e) {
      console.log("Connection established!");
      setInterval(register, 60000);//1minute keep connection
   };

   conn.onmessage = function(e) {
      console.log(e.data);
   };

   function register() {
    conn.send(JSON.stringify({command: "register", userId: "1"}));
   }

   function send() {
    conn.send(JSON.stringify({command: "message", to: "2", from: "1", data: {message: "halo user 2"}}));
   }
  </script>
 </body>
</html>

Dan untuk mengetestnya kita tidak bisa menggunakan IP public dari server EC2 yang kita miliki karena jika dipaksa untuk mengakses dengan https maka secure connection websocket akan error karena ketidak mampuan dari server yang di akses melalui IP public untuk melakukan self-signed certificates.

Untuk itu kita harus menggunakan domain yang telah di integrasikan dengan sebuah CDN dalam hal ini codedoct menggunakan cloudflare bisa baca disini untuk setupnya.

Terakhir silahkan akses kembali page websocket anda menggunakan url domain anda dengan secure connection "https".

===DONE!===