Rumah  >  Artikel  >  rangka kerja php  >  Swoole Advanced: Menggunakan Coroutines untuk Menulis Pelayan Serentak

Swoole Advanced: Menggunakan Coroutines untuk Menulis Pelayan Serentak

WBOY
WBOYasal
2023-06-14 23:39:12708semak imbas

Dalam senario aplikasi rangkaian serentak tinggi, Swoole, sebagai rangka kerja komunikasi proses jarak jauh, semakin digemari oleh pembangun. Swoole menyediakan API pengaturcaraan rangkaian yang kaya, membenarkan pembangun menggunakan coroutine untuk pengaturcaraan tak segerak, meningkatkan keupayaan pemprosesan serentak. Artikel ini akan memperkenalkan cara menulis pelayan serentak ringkas menggunakan Swoole dan coroutine.

1. Persediaan persekitaran

Sebelum kita mula, kita perlu memasang sambungan Swoole Untuk kaedah pemasangan, sila rujuk dokumentasi rasmi Swoole. Artikel ini menggunakan versi PHP7.2.

2. Rangka kerja program pelayan

Kita perlu menggunakan pelayan TCP Swoole. >

    Dalam aplikasi rangkaian, biasanya perlu untuk menentukan format penghantaran data standard. Dalam contoh ini, kita boleh menggunakan format protokol tersuai, seperti yang ditunjukkan di bawah:
  1. class MyProtocol {
        const HEADER_SIZE = 4;
        const MAX_PACKAGE_SIZE = 1024 * 1024;
    
        public static function encode($data) {
            $package = json_encode($data, JSON_UNESCAPED_UNICODE);
            return pack('N', strlen($package)) . $package;
        }
    
        public static function decode($buffer) {
            if(strlen($buffer) < self::HEADER_SIZE) {
                return false;
            }
    
            $length = unpack('N', substr($buffer, 0, self::HEADER_SIZE))[1];
            if($length > self::MAX_PACKAGE_SIZE) {
                return false;
            }
    
            if(strlen($buffer) < self::HEADER_SIZE + $length) {
                return false;
            }
    
            $package = substr($buffer, self::HEADER_SIZE, $length);
            return json_decode($package, true);
        }
    }
  2. Format protokol mengandungi pengepala 4-bait untuk menyimpan panjang paket data dan data sebenar perwakilan rentetan JSON. Format ini boleh menyokong jenis mesej yang berbeza dan mencapai kebolehpercayaan dan kebolehskalaan penghantaran.

Tentukan pemprosesan perniagaan

    Pemprosesan logik perniagaan ditakrifkan dalam fungsi panggil balik kelas Pelayan, seperti ditunjukkan di bawah:
  1. class Server {
        private $serv;
    
        public function __construct() {
            $this->serv = new SwooleServer('0.0.0.0', 9501);
            $this->serv->set(array(
                'worker_num' => 4,
                'daemonize' => false,
                'max_conn' => 10000,
                'dispatch_mode' => 3,
                'open_tcp_keepalive' => 1,
                'tcp_keepidle' => 600,
                'tcp_keepinterval' => 60,
                'tcp_keepcount' => 5,
            ));
            $this->serv->on('Connect', array($this, 'onConnect'));
            $this->serv->on('Receive', array($this, 'onReceive'));
            $this->serv->on('Close', array($this, 'onClose'));
            $this->serv->start();
        }
    
        public function onConnect($serv, $fd, $reactorId) {
            echo "Client: {$fd}-{$reactorId} Connect.
    ";
        }
    
        public function onReceive($serv, $fd, $reactorId, $data) {
            $message = MyProtocol::decode($data);
            if($message) {
                // Handle message & reply to client
                $this->serv->send($fd, MyProtocol::encode(array('status' => 0, 'message' => 'OK')));
            } else {
                // Invalid message, close connection
                $this->serv->close($fd);
            }
        }
    
        public function onClose($serv, $fd, $reactorId) {
            echo "Client: {$fd}-{$reactorId} Close.
    ";
        }
    }
    
    new Server();
  2. Untuk setiap sambungan, pelayan perlu Tentukan tiga kaedah untuk mengendalikan operasi seperti menyambung, menerima mesej, menutup sambungan, dsb., dan bertindak balas dengan sewajarnya.

3. Menggunakan coroutine

Swoole menyediakan API coroutine untuk mengurus aliran kawalan dalam pengaturcaraan tak segerak dan menyediakan pengalaman pengaturcaraan segerak. Fungsi coroutine boleh dilaksanakan melalui API siri coroutine. Berikut ialah kod baharu selepas menggunakan coroutine, yang menggunakan coroutine untuk mengendalikan operasi IO tak segerak seperti sambungan klien dan penerimaan mesej:

class Server {
    private $serv;

    public function __construct() {
        $this->serv = new SwooleServer('0.0.0.0', 9501);
        $this->serv->set(array(
            'worker_num' => 4,
            'daemonize' => false,
            'max_conn' => 10000,
            'dispatch_mode' => 3,
            'open_tcp_keepalive' => 1,
            'tcp_keepidle' => 600,
            'tcp_keepinterval' => 60,
            'tcp_keepcount' => 5,
        ));
        $this->serv->on('Connect', array($this, 'onConnect'));
        $this->serv->on('Receive', array($this, 'onReceive'));
        $this->serv->on('Close', array($this, 'onClose'));
        $this->serv->start();
    }

    public function onConnect($serv, $fd, $reactorId) {
        go(function() use($fd, $reactorId) {
            echo "Client: {$fd}-{$reactorId} Connect.
";
        });
    }

    public function onReceive($serv, $fd, $reactorId, $data) {
        go(function() use($serv, $fd, $reactorId, $data) {
            $message = MyProtocol::decode($data);
            if($message) {
                // Handle message & reply to client
                $serv->send($fd, MyProtocol::encode(array('status' => 0, 'message' => 'OK')));
            } else {
                // Invalid message, close connection
                $serv->close($fd);
            }
        });
    }

    public function onClose($serv, $fd, $reactorId) {
        go(function() use($fd, $reactorId) {
            echo "Client: {$fd}-{$reactorId} Close.
";
        });
    }
}

new Server();

Gunakan go(function()) untuk menambah tugasan pada coroutines untuk pelaksanaan jumlah kod dikurangkan, manakala fungsi panggil balik yang tidak perlu dan operasi rumit pengurusan manual proses kawalan dielakkan.

4. Bagaimana untuk menggunakan

Melalui alat baris arahan yang disediakan oleh Swoole, kami hanya boleh menguruskan proses menjalankan pelayan. Sebagai contoh, kami memulakan pelayan TCP Swoole seperti berikut:

php server.php

Jika anda perlu memastikan pelayan berjalan di latar belakang, anda boleh menetapkan pilihan daemonize:

php server.php --daemonize

Gunakan alat baris arahan disediakan oleh Swoole untuk memulakan, memulakan semula dan Hentikan pelayan dan operasi lain:

swoole_server [start|stop|reload|restart|shutdown]

Dengan menggunakan Swoole, kami boleh melaksanakan aplikasi rangkaian serentak yang cekap dengan mudah. Pelayan TCP Swoole yang ditulis menggunakan coroutine bukan sahaja memudahkan struktur kod, tetapi juga mempunyai prestasi yang lebih tinggi Berbanding dengan pelayan berbilang proses atau berbilang benang tradisional, ia boleh memperoleh prestasi pemprosesan yang lebih baik dan menjimatkan penggunaan sumber pelayan dengan ketara.

Atas ialah kandungan terperinci Swoole Advanced: Menggunakan Coroutines untuk Menulis Pelayan Serentak. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn