PHP code example of naivic / oswserver

1. Go to this page and download the library: Download naivic/oswserver library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

naivic / oswserver example snippets


namespace Grpc\Interconnect;

use OpenSwoole\GRPC;

class HostService implements HostInterface
{
    public function Message(GRPC\ContextInterface $ctx, MessageRequest $request): MessageResponse
    {
        // Log the request
        $ip = $ctx->getValue( \OpenSwoole\Http\Request::class )->server["remote_addr"];
        \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Received GRPC Message from $ip, contains ".var_export($request->getMessage(), true) );

        // Get instance of main server class
        $serv = $ctx->getValue( 'WORKER_CONTEXT' )->getValue( \MyServer::class );

        // Send message to client via websocket connection
        [$success, $msg] = $serv->sendMsgToClient( "msg", $request->getName(), $request->getMessage(), $ip, null );

        // Reply to gRPC peer
        $message = new \Grpc\Interconnect\MessageResponse();
        $message->setMessage( $msg );
        $message->setSuccess( $success );
        return $message;
    }
}

class MyServer extends \Naivic\OswServer {

    // Our gRPC port, as well as the gRPC peer port we will be sending our requests to
    const PORT_GRPC = 9501;

}

class MyServer extends \Naivic\OswServer {

    ...

    public $peer = null;

    public function onStart( \OpenSwoole\HTTP\Server $server ) {
        // Get gRPC peer IP from environment variable
        $this->peer = $_ENV["PEER"];
        \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Server starts with peer {$this->peer}" );

        // Call parent class to provide standard initialization (mandatory)
        parent::onStart( $server );
    }

}

class MyServer extends \Naivic\OswServer {

    ...

    public function sendMsgToClient( $type, $name, $text, $ip, $skip ) {
        $sent = 0;
        foreach( $this->server->connections as $conn ) {
            if( $conn !== $skip ) {
                if( $this->server->isEstablished($conn) ) {
                    if( $this->server->push( $conn, json_encode([ "type" => $type, "name" => $name, "text" => $text]) ) ) {
                        $sent++;
                        $log = "Message type '$type' with text '$text' from {$ip} was sent to client connection {$conn}";
                        \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, $log );
                    } else {
                        \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Cannot push message to client connection {$conn}" );
                    }
                }
            }
        }
        if( $sent == 0 ) {
            $log = "Message type '$type' with text '$text' from {$ip} was not sent to client, because connection was closed";
            \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, $log );
            return [false, $msg];
        }
        return [true, "The message has been sent to {$sent} client connection".($sent>1?'s':'')];
    }

}

class MyServer extends \Naivic\OswServer {

    ...

    public function processRequestHttp( \OpenSwoole\GRPC\Context $context, \OpenSwoole\HTTP\Request $rawRequest, \OpenSwoole\HTTP\Response $rawResponse ) {
        $path = $context->getValue( 'path' );
        \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Have got HTTP Request $path" );
        switch( $path ) {
            case "/" :
                $fname = dirname(__FILE__).'/root.html';
                $rawResponse->write( file_get_contents( $fname ) );
                $rawResponse->status(200, "OK");
                break;
            default  : $rawResponse->status(404, "Not Found");
        }
        $rawResponse->end();
    }
}

class MyServer extends \Naivic\OswServer {

    ...

    public function processRequestWs( \OpenSwoole\Server $server, \OpenSwoole\WebSocket\Frame $frame ) {
        \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Received message from client: '{$frame->data}'" );
        $json = json_decode( $frame->data, true );
        $message = new \Grpc\Interconnect\MessageRequest();
        $message->setMessage( $json['text']??'' );
        $message->setName( $json['name']??'' );
        $this->sendMsgToClient( "echo", "", $message->getMessage(), 'localhost', $frame->fd );
        try {
            $conn = (new \OpenSwoole\GRPC\Client( $this->peer, static::PORT_GRPC ))->connect();
            $out = (new \Grpc\Interconnect\HostClient( $conn ))->Message( $message );
            $conn->close();
            if( $out->getSuccess() ) {
                \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Client's message '{$frame->data}' was sent to peer {$this->peer}, peer response: '{$out->getMessage()}'" );
                $this->sendMsgToClient( "info", "", $out->getMessage(), 'localhost', null );
            } else {
                \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Client's message '{$frame->data}' was not accepted by peer {$this->peer}, peer reason: '{$out->getMessage()}'" );
                $this->sendMsgToClient( "error", "", "message not delivered, user is currently disconnected", 'localhost', null );
            }
        } catch ( \Throwable $e ) {
            \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Client's message '{$frame->data}' was not sent to peer {$this->peer} because of gRPC exception: ".$e->getMessage() );
            $this->sendMsgToClient( "error", "", "message not delivered, server is currently offline", 'localhost', null );
        }
    }
}

class MyServer extends \Naivic\OswServer {

    ...

    public function processRequestGrpc( \OpenSwoole\GRPC\Context $context, \OpenSwoole\HTTP\Request $rawRequest, \OpenSwoole\HTTP\Response $rawResponse ) {

        // Additional logging of gRPC requests
        \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Have got GRPC Request {$context->getValue('path')}" );

        // Call parent class to provide standatd request processing
        parent::processRequestGrpc( $context, $rawRequest, $rawResponse );
    }
}

class MyServer extends \Naivic\OswServer {

    ...

    public function onOpen( \OpenSwoole\Server $server, \OpenSwoole\Http\Request $request ) {
        \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Client connection registered: {$request->fd}" );
    }

    public function onClose( \OpenSwoole\Server $server, int $fd ) {
        \OpenSwoole\Util::LOG( \OpenSwoole\Constant::LOG_INFO, "Client connection close: {$fd}" );
    }
}

$serv = (new \MyServer('0.0.0.0', MyServer::PORT_GRPC)
    ->register( \Grpc\Interconnect\HostService::class )
    ->start()

class MyServer extends \Naivic\OswServer {

    ...

    const PORT_HTTP = 8080;

}

$serv = (new \MyServer('0.0.0.0', MyServer::PORT_GRPC)) // gRPC
    ->register(\Grpc\Interconnect\HostService::class) // Register gRPC service
    ->addlistener("0.0.0.0", MyServer::PORT_HTTP, OpenSwoole\Constant::SOCK_TCP) // Add listener to another port for HTTP+WebSocket
    ->start()
;