您好,登錄后才能下訂單哦!
這篇文章主要介紹“Swoft 2.0.6怎么實現Rpc服務客戶端以及非Swoft框架外部調用”,在日常操作中,相信很多人在Swoft 2.0.6怎么實現Rpc服務客戶端以及非Swoft框架外部調用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Swoft 2.0.6怎么實現Rpc服務客戶端以及非Swoft框架外部調用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
1.首先啟動http跟rpc服務。
我這里是直接用docker-compose開啟服務的。
大家也可以進入swoft容器用命令開啟服務。
http命令:php bin/swoft http:start
rpc命令:php bin/swoft rpc:start
2.RPC Server 配置參數
RPC 服務啟動有單獨啟動和集成其它服務(Http/Websocket)兩種方式,無論那種方式都首先要在 bean.php 配置RPC。
'rpcServer' => [ 'class' => ServiceServer::class, 'port' => 18307, ],
3.Http server 啟動中集成 RPC 服務,其listener 單獨監聽一個RPC服務,且同時可以監聽多個 RPC 服務中
'httpServer' => [ 'class' => HttpServer::class, 'port' => 18306, 'listener' => [ 'rpc' => bean('rpcServer') ], 'process' => [ // 'monitor' => bean(MonitorProcess::class) // 'crontab' => bean(CrontabProcess::class) ], 'on' => [ // SwooleEvent::TASK => bean(SyncTaskListener::class), // Enable sync task SwooleEvent::TASK => bean(TaskListener::class), // Enable task must task and finish event SwooleEvent::FINISH => bean(FinishListener::class) ], /* @see HttpServer::$setting */ 'setting' => [ 'task_worker_num' => 12, 'task_enable_coroutine' => true, 'worker_num' => 6 ] ],
5.定義接口并實現接口,才能提供RPC服務。注意里面的版本號定制注解@Service()
6.定義接口
<?php declare(strict_types=1); /** * This file is part of Swoft. * * @link https://swoft.org * @document https://swoft.org/docs * @contact group@swoft.org * @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE */ namespace App\Rpc\Service; use App\Rpc\Lib\UserInterface; use Exception; use Swoft\Co; use Swoft\Rpc\Server\Annotation\Mapping\Service; /** * Class UserService * * @since 2.0 * * @Service() */ class UserService implements UserInterface { /** * @param int $id * @param mixed $type * @param int $count * * @return array */ public function getList(int $id, $type, int $count = 10): array { return ['name' => ['list']]; } /** * @param int $id * * @return bool */ public function delete(int $id): bool { return false; } /** * @return void */ public function returnNull(): void { return; } /** * @return string */ public function getBigContent(): string { $content = Co::readFile(__DIR__ . '/big.data'); return $content; } /** * Exception * @throws Exception */ public function exception(): void { throw new Exception('exception version'); } /** * @param string $content * * @return int */ public function sendBigContent(string $content): int { return strlen($content); } }
7.按版本實現不同的接口需求
/** * Class UserService * * @since 2.0 * * @Service() */
/** * Class UserServiceV2 * * @since 2.0 * * @Service(version="1.2") */
不同的實現,需要定義不同的唯一版本號,如果存在相同,加載之后的服務會覆蓋之前的服務
8.RPC Client配置參數
同樣也是在bean.php中配置,如以下是一個user 服務
'user' => [ 'class' => ServiceClient::class, 'host' => '127.0.0.1', 'port' => 18307, 'setting' => [ 'timeout' => 0.5, 'connect_timeout' => 1.0, 'write_timeout' => 10.0, 'read_timeout' => 0.5, ], 'packet' => bean('rpcClientPacket') ], 'user.pool' => [ 'class' => ServicePool::class, 'client' => bean('user'), ],
8.客戶調用
<?php declare(strict_types=1); /** * This file is part of Swoft. * * @link https://swoft.org * @document https://swoft.org/docs * @contact group@swoft.org * @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE */ namespace App\Http\Controller; use App\Rpc\Lib\UserInterface; use Exception; use Swoft\Co; use Swoft\Exception\SwoftException; use Swoft\Http\Server\Annotation\Mapping\Controller; use Swoft\Http\Server\Annotation\Mapping\RequestMapping; use Swoft\Rpc\Client\Annotation\Mapping\Reference; /** * Class RpcController * * @since 2.0 * * @Controller() */ class RpcController { /** * @Reference(pool="user.pool") * * @var UserInterface */ private $userService; /** * @Reference(pool="user.pool", version="1.2") * * @var UserInterface */ private $userService2; /** * @RequestMapping("getList") * * @return array */ public function getList(): array { $result = $this->userService->getList(12, 'type'); $result2 = $this->userService2->getList(12, 'type'); return [$result, $result2]; } /** * @RequestMapping("returnBool") * * @return array */ public function returnBool(): array { $result = $this->userService->delete(12); if (is_bool($result)) { return ['bool']; } return ['notBool']; } /** * @RequestMapping() * * @return array */ public function bigString(): array { $string = $this->userService->getBigContent(); return ['string', strlen($string)]; } /** * @RequestMapping() * * @return array * @throws SwoftException */ public function sendBigString(): array { $content = Co::readFile(__DIR__ . '/../../Rpc/Service/big.data'); $len = strlen($content); $result = $this->userService->sendBigContent($content); return [$len, $result]; } /** * @RequestMapping() * * @return array */ public function returnNull(): array { $this->userService->returnNull(); return [null]; } /** * @RequestMapping() * * @return array * * @throws Exception */ public function exception(): array { $this->userService->exception(); return ['exception']; } }
9.地址欄訪問效果。
我這里的ip是自己http服務的ip,大家根據自己的實際修改即可。
10.如何實現非Swoft框架調用
需要注意swoft框架的默認消息協議是json-rpc,而且默認消息協議是以 \r\n\r\n
結尾的。
其他框架代碼例子如下,可以自行封裝:
<?php const RPC_EOL = "\r\n\r\n"; function request($host, $class, $method, $param, $version = '1.0', $ext = []) { $fp = stream_socket_client($host, $errno, $errstr); if (!$fp) { throw new Exception("stream_socket_client fail errno={$errno} errstr={$errstr}"); } $req = [ "jsonrpc" => '2.0', "method" => sprintf("%s::%s::%s", $version, $class, $method), 'params' => $param, 'id' => '', 'ext' => $ext, ]; $data = json_encode($req) . RPC_EOL; fwrite($fp, $data); $result = ''; while (!feof($fp)) { $tmp = stream_socket_recvfrom($fp, 1024); if ($pos = strpos($tmp, RPC_EOL)) { $result .= substr($tmp, 0, $pos); break; } else { $result .= $tmp; } } fclose($fp); return json_decode($result, true); } $ret = request('tcp://172.18.0.6:18307', \App\Rpc\Lib\UserInterface::class, 'getList', [1, 2], "1.2"); var_dump($ret);
11.需要格外注意是框架外調用的ip地址并非官方文檔例子里的127.0.0.1,大家改為自己的實際ip即可。不然會連接報錯。
到此,關于“Swoft 2.0.6怎么實現Rpc服務客戶端以及非Swoft框架外部調用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。