之前我們如果使用 protobuf : https://blog.csdn.net/daily886/article/details/98594066
現在我們使用protobuf作爲數據流,搭建grpc服務器和客戶端
目錄結構如下:
項目根目錄是 grpc
grpc的目錄結構
├── protobuf # proto文件統一存放目錄
│ ├── helloworld.proto # proto文件
├── server.go # grpc服務器端
├── client.go # grpc客戶端
下面,我們根據目錄結構,從上往下建立文件夾和文件
建立文件夾和文件 grpc/protobuf/helloworld.proto ,helloworld.proto 內容如下:
syntax = "proto3";
option objc_class_prefix = "HLW";
package helloworld;
// 定義一個greeter服務器,其中api 爲sayhello
// 形式參數: hellorequest
// 返回參數: helloreply
service Greeter{
// 發送一個問候
rpc SayHello(HelloRequest) returns (HelloReply) {}
/*
rpc 接口的類型分爲以下四種: A 爲接收參數, B 爲返回參數
1. rpc GetFeature(Point) returns (Feature) {} 普通調用:A-B
2. rpc ListFeatures(Rectangle) returns (stream Feature) {} 單向流:A - B(流)
3. rpc RecordRoute(stream Point) returns (RouteSummary) {} 單向流:A(流) - B
4. rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} 雙向流:A(流) - B(流)
*/
}
// 請求參數-根據自己需求定義
message HelloRequest{
string name = 1;
}
// 返回參數-根據自己需求定義
message HelloReply{
string message = 1;
}
//最後運行命令: protoc --go_out=plugins=grpc:. helloworld.proto
//即可生成 pb 文件
建立文件 grpc/server.go ,server.go 內容如下:
package main
import (
"google.golang.org/grpc"
"fmt"
"context"
"net"
pb "grpc/protobuf"
)
//服務器端口
const port = ":6664"
//定義struct 來實現我們自定義的 helloworld.proto 對應的服務
type myServer struct {
}
func (m *myServer) SayHello(ctx context.Context,in *pb.HelloRequest) (*pb.HelloReply,error){
return &pb.HelloReply{Message:"請求server端成功!"}, nil
}
/*
首先我們必須實現我們自定義的 rpc 服務,例如: rpc SayHello() -在此我們可以實現自己的邏輯
創建監聽listener
創建grpc 服務
將我們的服務註冊到grpc 的server 中
啓動grpc 服務,將我們自定義的監聽信息傳遞給grpc 服務器
*/
func main(){
//創建server 端監聽端口
list,err := net.Listen("tcp",port)
if err != nil{
fmt.Println(err)
}
//創建grpc 的server
server := grpc.NewServer()
//註冊我們自定義的helloworld 服務
pb.RegisterGreeterServer(server,&myServer{})
//啓動grpc 服務
fmt.Println("grpc 服務啓動...")
server.Serve(list)
}
建立文件 grpc/client.go ,client.go 內容如下:
package main
import (
"google.golang.org/grpc"
"fmt"
"context"
pb "grpc/protobuf"
)
//與服務器對應的端口
const address = "127.0.0.1:6664"
/*
創建grpc 連接器
創建grpc 客戶端,並將連接器賦值給客戶端
向grpc 服務器發起請求
獲取grpc 服務器返回的結果
*/
func main() {
//創建一個grpc 連接器
conn,err := grpc.Dial(address,grpc.WithInsecure())
if err != nil{
fmt.Println(err)
}
//當請求完畢後記得關閉連接,否則大量連接會佔用資源
defer conn.Close()
//創建grpc 客戶端
c := pb.NewGreeterClient(conn)
name := "我是客戶端,正在請求服務器!!"
//客戶端向grpc 服務器發起請求
result,err := c.SayHello(context.Background(),&pb.HelloRequest{Name:name})
fmt.Println(name)
if err != nil{
fmt.Println("請求失敗!!")
return
}
//獲取服務器返回的結果
fmt.Println(result.Message)
}
切換到grpc/protobuf目錄中,編譯 .proto
文件,生成 Go 語言文件
[root@izj6c4jirdug8kh3uo6rdez grpc]# cd protobuf
[root@izj6c4jirdug8kh3uo6rdez protobuf]# protoc --go_out=plugins=grpc:. helloworld.proto
[root@izj6c4jirdug8kh3uo6rdez protobuf]# ll
total 12
-rw-r--r-- 1 root root 7112 Aug 30 15:29 helloworld.pb.go
-rw-r--r-- 1 root root 941 Aug 30 15:20 helloworld.proto
切換到grpc目錄中, 初始化包,並把google.golang.org/grpc包替換爲github.com/grpc/grpc-go@latest
[root@izj6c4jirdug8kh3uo6rdez grpc]# go mod init grpc
go: creating new go.mod: module grpc
[root@izj6c4jirdug8kh3uo6rdez grpc]# go mod edit -replace=google.golang.org/grpc=github.com/grpc/grpc-go@latest
[root@izj6c4jirdug8kh3uo6rdez grpc]# cat go.mod
module grpc
go 1.12
replace google.golang.org/grpc => github.com/grpc/grpc-go v1.23.0
require (
github.com/golang/protobuf v1.3.2
google.golang.org/grpc v0.0.0-00010101000000-000000000000
)
啓動grpc服務器
[root@izj6c4jirdug8kh3uo6rdez grpc]# go run server.go
grpc 服務啓動...
啓動客戶端
[root@izj6c4jirdug8kh3uo6rdez grpc]# go run client.go
我是客戶端,正在請求服務器!!
請求server端成功!
參考:https://www.cnblogs.com/hcy-fly/p/8819111.html
參考:https://github.com/grpc/grpc-go