gRPC是可以在任何環境中執行的現代開源高效能RPC框架。它可以通過可插拔的支援來有效地連線資料中心內和跨資料中心的服務,以實現負載平衡,跟蹤,執行狀況檢查和身份驗證。它也適用於分散式計算的最後一英里,以將裝置,移動應用程式和瀏覽器連線到後端服務。
安裝protocol buffer 編譯器
mac:
brew install protobuf
其他系統可以嘗試編譯安裝
安裝gprc
go get -u google.golang.org/grpc
安裝protoc-gen-go外掛
go get -u github.com/golang/protobuf/protoc-gen-go
使用
新建hello目錄,進入後執行:
protoc --proto_path hello/ --go_out=plugins=grpc:hello hello.proto
會看到hello目錄下生成了hello.pb.go檔案。
當然,其中的 hello.proto
是預先自定義在hello資料夾下的,如:
syntax = "proto3"; //語法宣告
package hello; //包名
// 定義服務
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 請求資料格式
message HelloRequest {
string name = 1;
}
// 響應資料格式
message HelloReply {
string message = 1;
}
server
新建server目錄,
golang例子程式碼來自:https://github.com/grpc/grpc-go/tree/maste...
// main.go
package main
import (
"context"
"log"
"net"
"google.golang.org/grpc"
pb "local.com/sai/game/grpc/hello"
)
const (
port = ":50051"
)
// server is used to implement helloworld.GreeterServer.
type server struct {
pb.UnimplementedGreeterServer
}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Printf("Received: %v", in.GetName())
return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
client
go client
// client.go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/grpc"
pb "local.com/sai/game/grpc/hello"
)
const (
address = "127.0.0.1:50051"
defaultName = "13sai"
)
func main() {
// Set up a connection to the server.
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)
// Contact the server and print out its response.
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetMessage())
}`
php client
擴充套件安裝
下載安裝合適版本的擴充套件即可,記得別忘記在php.ini中加入:
extension=grpc.so
extension=protobuf.so
自動生成程式碼
protoc --php_out=client hello/hello.proto
會看到client目錄下生成了GPBMetadata和Hello兩個目錄。
如果你對grpc相對叫熟練,可以直接進行程式碼編寫:
<?php
require __DIR__ . '/vendor/autoload.php';
class Client extends \Grpc\BaseStub{
public function __construct($hostname, $opts, $channel = null) {
parent::__construct($hostname, $opts, $channel);
}
/**
* rpc SayHello(HelloRequest) returns (HelloReply) {}
* 方法名儘量和 (gprc 定義 Greeter 服務)的方法一樣
* 用於請求和響應該服務
*/
public function SayHello(\Hello\HelloRequest $argument){
// (/hello.Greeter/SayHello) 是請求服務端那個服務和方法,基本和 proto 檔案定義一樣
return $this->_simpleRequest('/hello.Greeter/SayHello',
$argument,
['\Hello\HelloReply', 'decode']
);
}
}
//用於連線 服務端
$client = new \Client('127.0.0.1:50051', [
'credentials' => Grpc\ChannelCredentials::createInsecure()
]);
//例項化 TestRequest 請求類
$request = new \Hello\HelloRequest();
$request->setName("fairy");
//呼叫遠端服務
$get = $client->SayHello($request)->wait();
//返回陣列
//$reply 是 TestReply 物件
//$status 是陣列
list($reply, $status) = $get;
echo $reply->getMessage().PHP_EOL;
// print_r($client->SayHello($request));
當然,也可以使用grpc_php_plugin外掛生成。
grpc_php_plugin外掛
git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
cd grpc
#這一步很慢,暫未找到什麼好方法
git submodule update --init
make grpc_php_plugin
新建php-client,再來自動生成:
protoc -I=./hello hello.proto --php_out=./php-client/ --grpc_out=php-client/ --plugin=protoc-gen-grpc=/Users/wangzetao/www/grpc1/bins/opt/grpc_php_plugin
會發現比上面自動生成多了一個GreeterClient.php
<?php
// client.php
require __DIR__ . '/vendor/autoload.php';
//用於連線 服務端
$client = new \Hello\GreeterClient('127.0.0.1:50051', [
'credentials' => Grpc\ChannelCredentials::createInsecure()
]);
//例項化 TestRequest 請求類
$request = new \Hello\HelloRequest();
$request->setName("world");
//呼叫遠端服務
$get = $client->SayHello($request)->wait();
//返回陣列
//$status 是陣列
list($reply, $status) = $get;
echo $reply->getMessage().PHP_EOL;
// print_r($client->SayHello($request));
執行測試
go run grpc/server/main.go
go run grpc/client/main.go
go run grpc/client/client.php
go run grpc/client/php-client.php
grpc初體驗完成了,本次只是小小的使用了一下子,後續感興趣的話可以深入學習一下。文中如有錯誤,歡迎指出交流。