Swoole, PHP WebSockets + Http + Static

Setting up Swoole

I assume that either you run mac, or linux as windows isn’t on the picture yet as far as i know, the first thing you have to do is to install php7 on your machine.. if you run  on a debian based distro will do something like:

sudo apt-get install php7.2 php7.2-cli php7.2-common php7.2-json php7.2-opcache php7.2-mysql php7.2-zip php7.2-fpm php7.2-mbstring

Don’t install apache as we are not going to need it at all.

Step 1.

Download the source code from https://github.com/swoole/swoole-src extract the files or use from the terminal unzip swoole-src-master.zip

Step 2.

Open a terminal and type

[machine@user:~$] cd swoole-src-master
[machine@user:~$] sudo ./make.sh

The rest is pretty much guided by the makefile it self and you won’t need any further instructions for this i hope, except from loading the module in your php.ini after you done with the compile, so type

[machine@user:~$] php -i | grep ‘Configuration File

^this command will show you the path of your php ini, you have to edit it with your favorite text editor, nano, xedit, gedit etc. and insert extension=swoole.so

Step 3.

If you have done lets dive in into the code Save that as server.php and back from the terminal type:


[machine@user:~$] php ./server.php

<?php

$serverIP = "127.0.0.1";
$serverPORT = 8000;
$wwwDir = "./htdocs";

$server = new swoole_websocket_server($serverIP, $serverPORT);

$server->on('open', function (swoole_websocket_server $server, $request) {
    echo "server: handshake success with fd{$request->fd}n";
});

$server->on('message', function (swoole_websocket_server $server, $frame) {
    echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}n";
    $server->push($frame->fd, "This message is from swoole websocket server.");
});

$server->on('close', function ($ser, $fd) {
    echo "client {$fd} closedn";
});

$server->on('request', function ($ser, $fd) {
   global  $wwwDir;
   //set up some vars as you used them
    $_GET = $ser->get; 
    $_POST = $ser->post;
    $_JSON = json_decode($ser->rawContent(),true);


  if ($ser->server['request_uri'] == "/api-test") {
   $fd->status(200);
   $fd->end("Hello Worldn ");
    return;
   }  
   $local_path = $wwwDir.$ser->server['request_uri'];
    //lets see if its dir look for index.html, htm
   
     if (is_dir($local_path) && file_exists($local_path.'index.html')) {
 
        $local_path = $local_path.'index.html';
     }
     //we found something, serv it
     if (file_exists($local_path)) {
        $fd->sendfile($local_path);
     } else {
        $fd->status(404);
        $fd->end('Not found');
     }

});

$server->start();

?>

Well, thats all. This approach is far from perfect but its pretty much all you need to get into the spirit before you dive in into the coroutine library provides go-like coroutines and the rest of the goodies that comes with swoole.

Since sendfile() doesn’t support compression I decided to go ahead and write a minimal class for swoole that would serve all the files also with http/2  from the static directory using gzip compression if possible (depending on the browser-client if has been declared in the headers that it supports gzip, then will be used.

Also i added a function in the class that will compress strings for the messages, and of course a method for handling static files at the choose public www directory.

The example i uploaded starts a webserver along with a websocket server at both ports 80 and 443 https with ssl, i included some example-certs for testing. here it is: https://github.com/captainerd/swooleStatic

Leave a Reply