服務端可自定義方法供客戶端遠程調用php
服務端遠程調用函數參數(順序,數量)變化, 不會致使客戶端服務端版本不兼容問題json
支持多種傳輸協議 (protocolbuffer, msgpack, json, serialize)socket
支持多種通信方式 (阻塞, 非阻塞, SSL阻塞, SSL非阻塞等)async
支持自定義傳輸協議 (引入Rpc\Protocol\Interface接口)函數
高冷, 必定要高冷, API設計必定要高冷this
/** * 傳輸相關 */ // 服務端非阻塞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; } }
// 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();