Blocking Model for unix Network Model

Posted by andriy on Fri, 03 Dec 2021 18:38:35 +0100

My five handwritten network models, welcome comments and suggestions from all gods;

Environment preparation: php7.4, swoole4.8.2. (Here I use mac)

        Hobrew installation: Install Homebrew Tutorial-Accent Maple-Blog Park in China under mac

        php installation: Install php7.4+mysql5.7+nginx environment under mac_ And don't ask for future - CSDN blog

        swoole installation: Swoole4 Documentation , I'm using pecl. There may be minor problems with the mac installation, so leave a comment

Use composer here to manage our command space

        composer installation: Composer Installation and Use | Newbie Tutorial , find the appropriate installation method

Create a new folder and perform composer init initialization. (Always return, fill in the information if there is no information)

  Initialization succeeded, generating the following files and folders

  I've modified the namespace in composer.json here. I need to execute the composer dump-autoload command and regenerate the autoload file, otherwise I won't find the class

Create the following files and folders first

First, workerbase.php is an abstract base class that defines some basic methods

<?php
namespace Ztms;

/**
 * Basic abstract class
 */
abstract class WorkerBase
{
    protected $server;

    protected $events = [];

    protected $config;

    protected $type = "tcp";

    public function __construct($host, $port)
    {
        //Set up socket s
        $this->server = stream_socket_server("tcp://".$host.":".$port);
        // echo "tcp://".$host.":".$port."\n";
        var_dump("tcp://".swoole_get_local_ip()['en0'].":".$port." Start service ";
    }

    /**
     * Different models are implemented differently
     * @var [type]
     */
    protected abstract function accept();

     /**
     * Add Events
     * @method on
     * @param  [type] $event [description]
     * @param  [type] $call  [description]
     * @return [type]        [description]
     */
    public function on($event, $call)
    {
        $this->events[strtolower($event)] = $call;
    }

    public function set(){}

    /**
     * Send information
     * @method send
     * @param  [type] $client [description]
     * @param  [type] $data   [description]
     * @return [type]         [description]
     */
    public function send($client, $data)
    {
        fwrite($client, $data);
        // \fread
    }

    public function close($client)
    {
        \fclose($client);
    }

    public function start()
    {
        // var_dump($this->events);
        // Var_dump ($this->events,'Events registered by the output service');
        
        $this->accept();
    }

}

  worker.php is the blocking model, which while keeps him listening

<?php
namespace Ztms\Blocking;

use Ztms\WorkerBase;
/**
 * Blocking Model
 */
class Worker extends WorkerBase
{
    protected function accept()
    {
        while (true) {
            // Listen for connections
            $conn = stream_socket_accept($this->server);
            
            if (!empty($conn)) {
                // Trigger Connection Establishment Event
                $this->events['connect']($this, $conn);

                // Receive service information
                $data = fread($conn, 65535);
                $this->events['receive']($this, $conn, $data);
            }

             if (!empty($conn) && \get_resource_type($conn) == "Unknown") {
                // Disconnect
                $this->events['close']($this, $conn);
             }
        }
    }
}

server.php is a server

<?php

require_once __DIR__."/../../vendor/autoload.php";

use Ztms\Blocking\Worker;

$server = new Worker('0.0.0.0', 9500);

$server->on('connect', function($server, $client){
    echo "1 We connected successfully"."\n";
});

$server->on('receive', function(Worker $server, $client, $data){
    //Accept client messages
    echo '2'.$data."\n";
    //Server sends to client
    $server->send($client, "3 Roll, you scumbag man, you said the same thing to others");
    sleep(20);//To better see the effect, pretend to sleep for 20 seconds here
    $server->close($client);
});

$server->on('close', function($server, $client){
    echo "4 The client had to disconnect"."\n";
});
$server->start();

client.php is a client

<?php

require_once __DIR__."/../../vendor/autoload.php";
// Connect server
$fp = stream_socket_client("tcp://192.168.0.102:9500");

fwrite($fp, "There's always been a saying that you want to be my girlfriend!");

var_dump(fread($fp, 65535));

ok, now let's start the service and go to the test/blocking directory to execute php server.php

  The service starts successfully, opens two more windows, enters the test/blocking directory, and executes time php client.php

You can see that the client in the upper right corner has received a message from the server. The server has set up the connection to close for 20 seconds, so the client in the lower right corner must wait for the connection of the client in the upper right corner to close before it can execute. The client in the upper right corner has finished executing and will start executing the lower right corner, as shown in the figure.

  So far the test has been successful, I just want to say here, the blocking model is not a slag man. He did say to many people that he was my girlfriend, but they said it after the breakup, so he is not a slag man.

Topics: PHP Linux network swoole