>백엔드 개발 >PHP 문제 >PHP를 사용하여 간단한 RPC 클라이언트를 구현하는 방법

PHP를 사용하여 간단한 RPC 클라이언트를 구현하는 방법

PHPz
PHPz원래의
2023-04-24 14:53:00803검색

RPC(Remote Procedure Call)는 프로그램이 다른 공간이나 기계에서 서브루틴을 호출할 수 있도록 하는 컴퓨터 통신 프로토콜입니다. 이 프로토콜을 사용하면 RPC 프로토콜의 클라이언트와 서버를 구현해야 하는 경우 로컬 함수를 호출하는 것처럼 원격 서비스에서 함수를 호출할 수 있습니다.

이 기사에서는 PHP를 사용하여 간단한 RPC를 구현하는 방법을 소개합니다. 가볍고 간단한 프로토콜인 JSON-RPC 프로토콜을 사용합니다.

  1. 준비

코드 작성을 시작하기 전에 다음 사항을 알아야 합니다.

  • JSON-RPC 프로토콜은 무엇이며 그 특성은 무엇입니까?
  • PHP 소켓 프로그래밍, 특히 소켓 소켓 사용.
  • PHP용 JSON 구문 분석 및 직렬화.
  1. PHP는 간단한 RPC 클라이언트를 구현합니다

PHP를 사용하여 요청을 보내고 응답을 받는 간단한 RPC 클라이언트를 구현할 수 있습니다. 작업 흐름은 다음과 같습니다.

  • 소켓 소켓을 만듭니다.
  • socket_create() 함수를 사용하여 소켓을 만듭니다.
  • socket_connect() 함수를 사용하여 서버에 연결하세요.
  • 요청 정보를 서버로 보냅니다.
  • 서버에서 반환된 결과를 읽으려면 소켓_read() 함수를 사용하세요.

다음은 구현 예입니다.

class RpcClient
{
    private $url;
    private $port;
    private $timeout;
    private $socket;

    public function __construct($url, $port, $timeout = 30)
    {
        $this->url = $url;
        $this->port = $port;
        $this->timeout = $timeout;
        $this->connect();
    }

    private function connect()
    {
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($this->socket === false) {
            throw new Exception("unable to create socket: " . socket_strerror(socket_last_error()));
        }
        $result = socket_connect($this->socket, $this->url, $this->port);
        if ($result === false) {
            throw new Exception("unable to connect socket: " . socket_strerror(socket_last_error()));
        }
    }

    public function call($function_name, $parameters = [])
    {
        $request_body = json_encode([
            "jsonrpc" => "2.0",
            "method" => $function_name,
            "params" => $parameters,
            "id" => 1
        ]);

        $result = $this->send($request_body);
        $response = json_decode($result, true);
        if ($response['id'] != 1) {
            throw new Exception("incorrect response ID (expected: 1, actual: " . $response['id'] . ")");
        }

        if (isset($response['error'])) {
            throw new Exception("server returned error: " . print_r($response, true));
        }

        return $response['result'];
    }

    private function send($request_body)
    {
        $result = socket_write($this->socket, $request_body . "\n", strlen($request_body) + 1);
        if ($result === false) {
            throw new Exception("unable to send request: " . socket_strerror(socket_last_error()));
        }

        $response = "";
        do {
            $buffer = socket_read($this->socket, 1024);
            $response .= $buffer;
            if (strlen($buffer) < 1024) {
                break;
            }
        } while(true);

        return $response;
    }
}

위 코드에서 connect() 메소드는 소켓을 생성하고,socket_connect()를 사용하여 RPC 서버에 연결합니다. call() 메소드는 JSON 형식으로 요청 정보를 전송하고, send() 메소드는 요청 정보를 서버로 전송하고 서버의 응답 결과를 반환합니다.

RpcClient 개체를 생성할 때 서버가 수신 대기하는 주소와 포트 및 연결 대기 시간 초과 기간을 전달해야 합니다.

  1. PHP는 간단한 RPC 서버를 구현합니다

서버에서 RPC 프로토콜을 구현하려면 다음 단계가 필요합니다.

  • 리스닝 소켓을 만듭니다.
  • socket_bind() 함수를 사용하여 소켓을 특정 IP 주소 및 포트 번호에 바인딩합니다.
  • socket_listen() 함수를 사용하여 소켓을 수신합니다.
  • 클라이언트 연결 요청을 수락하고 새 소켓을 반환하려면 소켓_accept() 함수를 사용하세요.
  • 클라이언트의 요청 정보를 파싱하고 해당 기능을 실행합니다.
  • 클라이언트에게 응답 정보를 보냅니다.

다음은 간단한 RPC 서버의 예입니다.

class RpcServer
{
    private $url;
    private $port;
    private $timeout;
    private $socket;

    public function __construct($url, $port, $timeout = 30)
    {
        $this->url = $url;
        $this->port = $port;
        $this->timeout = $timeout;
        $this->listen();
    }

    private function listen()
    {
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($this->socket === false) {
            throw new Exception("unable to create socket: " . socket_strerror(socket_last_error()));
        }

        $result = socket_bind($this->socket, $this->url, $this->port);
        if ($result === false) {
            throw new Exception("unable to bind socket to $this->url:$this->port: " . socket_strerror(socket_last_error()));
        }

        $result = socket_listen($this->socket, 5);
        if ($result === false) {
            throw new Exception("unable to listen on socket: " . socket_strerror(socket_last_error()));
        }

        while (true) {
            $client = socket_accept($this->socket);
            $request_string = socket_read($client, 1024);
            $response_string = $this->handle_request($request_string);
            socket_write($client, $response_string, strlen($response_string));
            socket_close($client);
        }
    }

    private function handle_request($request_string)
    {
        $request = json_decode($request_string, true);
        $method = $request['method'];
        $params = $request['params'];

        if (!function_exists($method)) {
            return json_encode([
                "jsonrpc" => "2.0",
                "id" => $request['id'],
                "error" => [
                    "code" => -32601,
                    "message" => "Method not found"
                ]
            ]);
        }

        $result = call_user_func_array($method, $params);

        return json_encode([
            "jsonrpc" => "2.0",
            "id" => $request['id'],
            "result" => $result
        ]);
    }
}

위 코드에서 listening() 메서드는 소켓을 생성하고 소켓_bind()를 사용하여 지정된 IP 주소와 포트에 바인딩합니다. 그런 다음 소켓에서 수신 대기하기 위해 소켓_listen()이 호출되고, 클라이언트 연결 요청을 수락하고, 소켓_accept() 함수를 사용하여 통신을 위한 새 소켓을 반환합니다.

다음으로 서버는 클라이언트의 요청 정보를 분석하고 클라이언트가 요청한 메서드가 존재하는지 확인하고, 존재하지 않으면 오류 코드를 반환합니다. 메소드가 존재하면 서버는 해당 기능을 실행하고 결과를 클라이언트에 보냅니다.

RpcServer 개체를 생성할 때 서버가 수신 대기하는 주소와 포트 및 연결 대기 시간 초과 기간을 전달해야 합니다.

  1. 요약

이 기사에서는 PHP를 사용하여 간단한 RPC 애플리케이션을 구현하고 JSON-RPC 프로토콜을 사용하여 통신하는 방법을 배웠습니다. 이 기사의 연구를 통해 우리는 RPC 프로토콜의 기본 원리를 이해하고 소켓 프로그래밍의 기본 사용법을 이해하며 PHP의 JSON 구문 분석 및 직렬화 방법을 마스터하고 RPC 프로토콜 및 관련 응용 프로그램 시나리오를 심층적으로 연구할 수 있습니다.

위 내용은 PHP를 사용하여 간단한 RPC 클라이언트를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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