>  기사  >  PHP 프레임워크  >  Swoole Advanced: 코루틴을 사용하여 동시 서버 작성

Swoole Advanced: 코루틴을 사용하여 동시 서버 작성

WBOY
WBOY원래의
2023-06-14 23:39:12749검색

고동시성 네트워크 애플리케이션 시나리오에서 장거리 프로세스 통신 프레임워크인 Swoole은 개발자들 사이에서 점점 더 선호되고 있습니다. Swoole은 풍부한 네트워크 프로그래밍 API를 제공하므로 개발자는 비동기 프로그래밍에 코루틴을 사용하여 동시 처리 기능을 향상시킬 수 있습니다. 이 기사에서는 Swoole과 코루틴을 사용하여 간단한 동시 서버를 작성하는 방법을 소개합니다.

1. 환경 설정

시작하기 전에 Swoole 확장 프로그램을 설치해야 합니다. 설치 방법은 Swoole 공식 문서를 참조하세요. 이 글은 PHP7.2 버전을 사용합니다.

2. 서버 프로그램 프레임워크

Swoole의 TCP 서버를 사용해야 합니다. 구체적인 구현에서는 다음 측면을 고려해야 합니다.

  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);
    }
}

프로토콜 형식에는 패킷 길이를 저장하는 4바이트 헤더와 실제 데이터를 나타내는 JSON 문자열이 포함되어 있습니다. 이 형식은 다양한 메시지 유형을 지원하고 전송 안정성과 확장성을 달성할 수 있습니다.

  1. 비즈니스 처리 정의

비즈니스 논리 처리는 아래와 같이 Server 클래스의 콜백 함수에 정의됩니다.

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();

각 연결에 대해 서버는 연결 처리, 메시지 수락, 닫기 등 세 가지 메서드를 정의해야 합니다. 연결 및 기타 작업을 수행하고 이에 따라 응답합니다.

3. 코루틴 사용

Swoole은 비동기 프로그래밍에서 제어 흐름을 관리하고 동기 프로그래밍 경험을 제공하는 코루틴 API를 제공합니다. 코루틴 함수는 코루틴 시리즈 API를 통해 구현할 수 있습니다. 다음은 코루틴을 사용하여 클라이언트 연결 및 메시지 수신과 같은 비동기 IO 작업을 처리하는 코루틴을 사용한 후의 새로운 코드입니다.

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();

go(function())을 사용하여 코루틴에 실행할 작업을 추가하여 실행량을 줄입니다. 코드의 불필요한 콜백 기능과 수동 관리 제어 프로세스의 번거로운 작업을 피하면서.

4. 배포 방법

Swoole에서 제공하는 명령줄 도구를 사용하면 서버 실행 과정을 간단하게 관리할 수 있습니다. 예를 들어 Swoole TCP 서버를 시작하는 방법은 다음과 같습니다.

php server.php

서버를 백그라운드에서 계속 실행해야 하는 경우 데몬화 옵션을 설정할 수 있습니다.

php server.php --daemonize

Swoole에서 제공하는 명령줄 도구를 사용하여 시작합니다. , 재시작 및 서버 중지:

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

Swoole을 사용하면 효율적인 동시 네트워크 애플리케이션을 쉽게 구현할 수 있습니다. 코루틴을 사용하여 작성된 Swoole TCP 서버는 코드 구조를 단순화할 뿐만 아니라 기존 다중 프로세스 또는 다중 스레드 서버와 비교하여 더 높은 성능을 제공하며 더 나은 처리 성능을 얻을 수 있으며 서버의 리소스 소비를 크게 줄일 수 있습니다.

위 내용은 Swoole Advanced: 코루틴을 사용하여 동시 서버 작성의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.