RPC-PHP-SDK 設計

Feature

  • 服務端可自定義方法供客戶端遠程調用php

  • 服務端遠程調用函數參數(順序,數量)變化, 不會致使客戶端服務端版本不兼容問題json

  • 支持多種傳輸協議 (protocolbuffer, msgpack, json, serialize)socket

  • 支持多種通信方式 (阻塞, 非阻塞, SSL阻塞, SSL非阻塞等)async

  • 支持自定義傳輸協議 (引入Rpc\Protocol\Interface接口)函數

  • 高冷, 必定要高冷, API設計必定要高冷this

API

/**
 * 傳輸相關
 */
// 服務端非阻塞socket
class rpc_transport_server_socket
{
    protected $_port; //通信端口
    final public function __construct(int $port){
        $this->_port = $port;
    }
}
// 客戶端阻塞socket
class rpc_transport_client_socket
{
    protected $_host; //通信地址
    protected $_port; //通信端口
    final public function __construct(string $host, int $port) {
        $this->_host = $host;
        $this->_port = $port;
    }
}
// 客戶端非阻塞socket
class rpc_transport_async_client_socket extends rpc_transport_client_socket
{
    // do something
}
// 傳輸層抽象類
abstract class rpc_transport
{
    protected $_timeout; //傳輸超時, 支持浮點數, 單位:sec
    protected $_socket; //傳輸句柄
    abstract public function on(string $event, mixed $callback);
}
// 服務端傳輸
class rpc_transport_server extends rpc_transport
{
    final public function __construct(rpc_transport_server_socket $socket, float $timeout){
        $this->_socket = $socket;
        $this->_timeout = $timeout;
    }
    public static function factory(int $port, float $timeout){
        $this->_socket = new rpc_transport_server_socket($port);
        $this->_timeout = $timeout;
    }
    public function on(string $event, mixed $callback){
        SERVER->on(string $event, mixed $callback);
    }
}
// 客戶端傳輸
class rpc_transport_client extends rpc_transport
{
    final public function __construct(rpc_transport_client_socket $socket, float $timeout){
        $this->_socket = $socket;
        $this->_timeout = $timeout;
    }
    public static function factory(string $host, int $port, float $timeout){
        $this->_socket = new rpc_transport_client_socket($host, $port);
        $this->_timeout = $timeout;
    }
}
// 客戶端傳輸
class rpc_transport_async_client extends rpc_transport
{
    final public function __construct(rpc_transport_async_client_socket $socket, float $timeout){
        $this->_socket = $socket;
        $this->_timeout = $timeout;
    }
    public static function factory(string $host, int $port, float $timeout){
        $this->_socket = new rpc_transport_async_client_socket($host, $port);
        $this->_timeout = $timeout;
    }
    public function on(string $event, mixed $callback){
        CLIENT->on(string $event, mixed $callback);
    }
}
/**
 *  協議相關
 */
//傳輸協議工廠類
class rpc_protocol
{
    protected $_transport = null; //傳輸
    protected $_protocol = null; //協議(protocolbuffer, msgpack, json, serialize)
    private function __construct($protocol, rpc_transport $transport = NULL){
        return self::factory($protocol, $transport);
    }
    public static function factory($protocol, rpc_transport $transport = NULL){
        if(!isset($transport)) {
            $this->_transport = $transport;
        }
        if(class_exists('rpc_protocol_' . $protocol)) {
            $this->_protocol = new 'rpc_protocol_' . $protocol;
        }
        return $this;
    }
    public function getTransport(){
        return $this->_transport;
    }
    public function setTransport($transport){
        $this->_transport = $transport;
    }
    public function getProtocol(){
        return $this->_protocol;
    }
    public function setProtocol($protocol){
        $this->_protocol = $protocol;
    }
    public function pack($message) {
        return $this->_protocol->pack($message);
    }
    public function unpack($message){
        return $this->_protocol->unpack($message);
    }
}
//傳輸協議接口
interface rpc_protocol_interface
{
    public function pack($message);
    public function unpack($message);
}
//JSON傳輸協議(打個樣)
class rpc_protocol_json implements rpc_protocol_interface
{
    public function pack($message){
        ...
    }
    public function unpack($message){
        ...
    }
}
...
/**
 * 服務端
 */
// 服務端抽象類
abstract class rpc_server_service
{
    public function __call(){
        // do something
    }
}
// 服務端
class rpc_server
{
    final public function __construct(rpc_server_interface $server_interface, rpc_protocol $protocol);
}
/**
 * 客戶端
 */
// 客戶端
class rpc_client
{
    private $_protocol = null;
    public function __call(string $method, array $parameters){
        // call $server_interface
    }
    final public function __construct(rpc_protocol $protocol){
        $this->_protocol = $protocol;
    }
}    
//客戶端回調函數抽象類
abstract class rpc_async_client_callback
{
    private $_response = null;
    public function getResult() { 
        // 返回結果值
        return $this->_response; 
    } 
    public function onComplete($response){
        $this->_response = $response;
    }
    public function onError($error){
        throw new Exception($error);
    }
}
// 非阻塞客戶端
class rpc_async_client
{
    private $_protocol = null;
    private $_callback = null;
    public function __call(string $method, array $parameters){
        $callback = array_pop($parameters);
        $response = $this->_protocol->getTransport()->receive();
        $this->_protocol->getTransport()->on('complete', $callback->onComplete($response));
        $this->_protocol->getTransport()->on('error', $callback->onError($error));
    }
    final public function __construct(rpc_protocol $protocol){
        $this->_protocol = $protocol;
    }
}

Example

// server
class server_hello extends rpc_server_service {
    public function hello($message) {
        echo $message;
    }
}
$service = server_hello();
$server_transport = new rpc_transport_server(8080, 0.1);
$server_transport->on('connect', function(){
    echo "Server:Connect.\n";
});
$server_protocol = new rpc_protocol::factory('json', $server_transport);
$server = new rpc_server($server_protocol, $service);

$server->serve();

// client
$client_transport = new rpc_transport_client('127.0.0.1', 8080, 0.1);
$client_transport->on('connect', function(){
    echo "Client:Connect.\n";
});
$client_protocol = new rpc_protocol::factory('json', $client_transport);
$client = new rpc_client($client_protocol);

$client_transport->open();
$client->hello('world');
$client_transport->close();
相關文章
相關標籤/搜索