PHP中使用grpc服務(wù)的教程詳解
grpc是通過(guò)定義服務(wù)端和客戶端的代碼來(lái)實(shí)現(xiàn)的通信的。
但是要實(shí)現(xiàn)通信,還是要將其方法包裝為一個(gè)http請(qǐng)求,除非你把grpc的服務(wù)端代碼放在本地的端口上。
grpc是面對(duì)微服務(wù)框架而風(fēng)生水起的,上次我用python編寫了一個(gè)圖神經(jīng)網(wǎng)絡(luò)處理的微服務(wù),使用grpc放在我的服務(wù)器本地端口上。
現(xiàn)在我希望我的一個(gè)php項(xiàng)目也可以調(diào)用該服務(wù),現(xiàn)在來(lái)試一試吧~
流程
- php的服務(wù)器安裝protoc
- php的服務(wù)器安裝grpc
- 編寫服務(wù)端代碼
- 編寫客戶端代碼
由于服務(wù)端(python)的代碼已經(jīng)編寫或者說(shuō)已經(jīng)部署,就不做敘述了。
安裝代碼請(qǐng)根據(jù)自己的php版本和grpc版本酌情自定義。本人使用的php8.0,grpc1.62.0,protobuf4.62.0
安裝protoc解釋器
和windows開(kāi)發(fā)一樣,使用grpc服務(wù)均需要使用protoc解釋器,去官方github下的release下載linux版本:
解壓到/usr/bin/目錄下
如果你使用寶塔,你也可以直接先在本地電腦上解壓,把解壓后的bin文件夾里的protoc文件上傳到/usr/bin/中就好了。
終端中輸入protoc,有返回即為成功
安裝grpc
無(wú)論你服務(wù)器是否安裝pecl,可以直接通過(guò)http請(qǐng)求安裝php相關(guān)包,但是必須安裝了php(廢話)
# 下載解壓 grpc cd ~ wget http://pecl.php.net/get/grpc-1.62.0.tgz tar xvf grpc-1.62.0.tgz cd grpc-1.62.0 # 生成配置并編譯安裝(編譯安裝時(shí)間很長(zhǎng),我大概安裝了一小時(shí)左右) /www/server/php/72/bin/phpize ./configure --with-php-config=/www/server/php/72/bin/php-config make && make install
之后要配置php的拓展
# 配置PHP擴(kuò)展 cd grpc-1.62.0 echo "extension = grpc.so" >> /www/server/php/80/etc/php.ini cd protobuf-4.62.0 # 如果沒(méi)有路徑請(qǐng)仿照grpc安裝的方式手動(dòng)安裝安裝一下,我個(gè)人覺(jué)得可能并不需要 echo "extension = protobuf.so" >> /www/server/php/80/etc/php.ini
最后重啟一下php和nginx服務(wù)就大功告成了
編譯protoc文件
具體的protoc文件的定義詳細(xì)見(jiàn)之前的博客
需要安裝protoc和grpc_php_plugin
使用如下代碼生成:
protoc --php_out ./ you-file.proto #需要安裝protoc解釋器,生成protoc的php定義文件在當(dāng)前目錄(./)
protoc --grpc_out ./ you-file.proto #需要grpc_php_plugin插件安裝,生成grpc文件在當(dāng)前目錄
第一行生成你的proto數(shù)據(jù)定義文件,我生成了GCNResult.php,Node.php,Edge.php,GraphData.php,同時(shí)還會(huì)生成一個(gè)GPBMetaData文件夾。
第二行生成php的grpc文件:GCNServiceClient.php
注意,如果你沒(méi)有生成grpc文件的插件(安裝grpc出現(xiàn)問(wèn)題),可以直接下載該插件然后通過(guò)如下代碼生成xxxClient.php文件
protoc --grpc_out ./ --plugin=protoc-gen-grpc=/your-path-to-plugin/grpc_php_plugin you-filename.proto
編寫php請(qǐng)求的代碼(客戶端代碼)
編寫文件前置注意事項(xiàng):
注意:如果你使用寶塔,需要把php設(shè)置里的禁用函數(shù)putenv和proc_open給刪除,不然composer安裝無(wú)法進(jìn)行。
需要編寫composer.json文件,因?yàn)槭褂昧薲irname(__FILE__).'/vendor/autoload.php'該自動(dòng)導(dǎo)入功能。json文件內(nèi)容示例:
{ "require": { "grpc/grpc": "*", "google/protobuf": "*" }, "autoload": { "psr-4": { "GPBMetadata\\": "protoc/GPBMetadata/", "protoc\\": "protoc/" } } }
編寫后在服務(wù)器該文件目錄下啟動(dòng)終端輸入composer install即可,會(huì)生成vendor文件夾
現(xiàn)在我將編寫一個(gè)最簡(jiǎn)單的php文件來(lái)調(diào)用這個(gè)服務(wù)。
<?php require dirname(__FILE__).'/vendor/autoload.php'; // 引入 gRPC PHP 擴(kuò)展的自動(dòng)加載文件 require 'protoc/GraphData.php'; // 引入包含 protoc文件夾下的grpc生成文件 require 'protoc/Node.php'; require 'protoc/Edge.php'; require 'protoc/GCNResult.php'; require 'protoc/GCNServiceClient.php'; // 進(jìn)行g(shù)rpc請(qǐng)求,獲取gcn處理后的數(shù)據(jù),返回json字符串 function GCN_request() { $client = new GCNServiceClient('localhost:9999', [ 'credentials' => \Grpc\ChannelCredentials::createInsecure(), ]); // 創(chuàng)建一個(gè)實(shí)例的圖數(shù)據(jù) $G_example = new GraphData(); $G_example->setNodes([ (new Node())->setId("node1")->setFeatures([0.1, 0.2, 0.3]), (new Node())->setId("node2")->setFeatures([0.4, 0.5, 0.6]), ]); $G_example->setEdges([ (new Edge())->setSourceId("node1")->setTargetId("node2"), ]); // 發(fā)送請(qǐng)求并接收響應(yīng) list($response, $status) = $client->ProcessGraph($G_example)->wait(); if ($status->code !== Grpc\STATUS_OK) { // gRPC 請(qǐng)求出錯(cuò) throw new Exception('Error calling grpc server -> ProcessGraph: ' . $status->details); exit(1); } // 因?yàn)槲业姆祷亟Y(jié)果是個(gè)map數(shù)據(jù)類型,php中沒(méi)有該類型,需要做一個(gè)遍歷取值,如果是string類型可以直接取。 $NodeScores = []; foreach ($response->getNodeScores() as $key => $value) { $NodeScores[$key] = $value; } return json_encode($NodeScores); }
該函數(shù)返回一個(gè)json數(shù)據(jù),想要修改可以使用json_decode()
, 至此,大功告成!
到此這篇關(guān)于PHP中使用grpc服務(wù)的教程詳解的文章就介紹到這了,更多相關(guān)PHP使用grpc服務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一個(gè)簡(jiǎn)單php擴(kuò)展介紹與開(kāi)發(fā)教程
這個(gè)擴(kuò)展早就寫好了,只是一直沒(méi)有時(shí)間寫在blog上面,今天抽點(diǎn)時(shí)間,將它記錄下來(lái),以后備用。2010-08-08深入理解PHP原理之錯(cuò)誤抑制與內(nèi)嵌HTML分析
PHP支持內(nèi)嵌HTML的, 那么對(duì)于PHP文件中, PHP標(biāo)簽外的HTML會(huì)怎么處理呢? 它和直接輸出HTML有什么區(qū)別么?2011-05-05深入理解PHP之?dāng)?shù)組(遍歷順序) Laruence原創(chuàng)
經(jīng)常會(huì)有人問(wèn)我, PHP的數(shù)組, 如果用foreach來(lái)訪問(wèn), 遍歷的順序是固定的么? 以什么順序遍歷呢?下面看Laruence整理的2012-06-06php mysql操作mysql_connect連接數(shù)據(jù)庫(kù)實(shí)例詳解
php操作數(shù)據(jù)庫(kù)首先必須連接到指定的數(shù)據(jù)庫(kù),連接數(shù)據(jù)庫(kù)可以使用PHP mysql_connect函數(shù),本文章向大家介紹mysql_connect函數(shù)的使用方法和實(shí)例,需要的朋友可以參考一下2016-12-12php在linux下檢測(cè)mysql同步狀態(tài)的方法
這篇文章主要介紹了php在linux下檢測(cè)mysql同步狀態(tài)的方法,是Linux下使用php檢測(cè)mysql同步狀態(tài)的實(shí)用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01PHP中spl_autoload_register()和__autoload()區(qū)別分析
這篇文章主要介紹了spl_autoload_register()和__autoload()區(qū)別,需要的朋友可以參考下2014-05-05PHP字符串長(zhǎng)度計(jì)算 - strlen()函數(shù)使用介紹
在PHP中,函數(shù)strlen()返回字符串的長(zhǎng)度,strlen()函數(shù)返回字符串所占的字節(jié)長(zhǎng)度,一個(gè)英文字母、數(shù)字、各種符號(hào)均占一個(gè)字節(jié),它們的長(zhǎng)度均為12013-10-10php將數(shù)據(jù)庫(kù)導(dǎo)出成excel的方法
有時(shí)寫程序時(shí)后臺(tái)要求把大量數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù)中,比如考試成績(jī)、電話簿等一般都是存放在excel中的數(shù)據(jù),這時(shí)我們可把excel導(dǎo)出成csv文件,然后通過(guò)以下程序即可批量導(dǎo)入數(shù)據(jù)到數(shù)據(jù)庫(kù)中2010-05-05