我有一個放著很多測試程式的資料夾,每次要用新的套件或測試邏輯的時候, 為了要排除其他影響因素, 我會開一個最精簡的main.go來測試, 這樣可以先掌握好主要的項目, 然後再移到開發框架裡面使用。
昨天定好了grpc spec, 今天就示範寫一個最簡短的gRPC server的樣子。
首先, 開好main.go之後把spec import進來 coconut "[spec路徑]/coconut/pb"
package main
import (
"context"
"fmt"
"net"
"os"
"os/signal"
"syscall"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
coconut "[spec路徑]/coconut/pb"
)
在func main
註冊 grpc server, 要先指定服務的port, net.Listen("tcp", ":8800")
帶入port時要用:
+port
的方式帶入
func main() {
var (
err error
shutdownObserver = make(chan os.Signal, 1)
)
sv := &server{}
// 監聽指定port,服務會在該port執行
apiListener, err := net.Listen("tcp", ":8800")
if err != nil {
panic(err)
}
gs := grpc.NewServer(grpc.MaxRecvMsgSize(1024 * 1024 * 8))
coconut.RegisterCoconutServer(gs, sv)
// 在 gRPC 伺服器上註冊反射服務。
reflection.Register(gs)
go func(gs *grpc.Server, c chan<- os.Signal) {
err := gs.Serve(apiListener)
if err != nil {
shutdownObserver <- syscall.SIGINT
}
}(gs, shutdownObserver)
/** 監聽信號
SIGHUP 終端控制進程結束(終端連接斷開)
SIGINT 用戶發送INTR字符(Ctrl+C)觸發
SIGQUIT 用戶發送QUIT字符(Ctrl+/)觸發
SIGTERM 結束程序(可以被捕獲、阻塞或忽略)
**/
signal.Notify(shutdownObserver, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
//阻塞直到有信號傳入
s := <-shutdownObserver
fmt.Println(`Receive signal:`, s)
// 優雅停止GRPC服務
gs.GracefulStop()
}
grpc server如果只有註冊服務是沒有辦法go build
成功的, 它需要先把gRPC各個接口依照spec開好
func (s *server) Ping(ctx context.Context, in *coconut.PingRequest) (r *coconut.Pong, err error) {
r = &coconut.Pong{
Pong: "Pong",
}
return r, err
}
func (s *server) UpdatePoints(ctx context.Context, in *coconut.PointsRequest) (r *coconut.RetPoints, err error) {
r = &coconut.RetPoints{}
return
}
func (s *server) GetPoints(ctx context.Context, in *coconut.GetPointsRequest) (r *coconut.RetPoints, err error) {
r = &coconut.RetPoints{}
return
}
接著執行 go build
之後, 啟動 ./coconut
就可以透過 grpcurl
打到server
-> % grpcurl -plaintext -d '{}' localhost:8800 coconut.Coconut/Ping
{
"pong": "Pong"
}
這是最簡短的grpc server, 有時候我要使用的grpc服務還沒實作的時候我也會這樣做一個簡單的mock程式, protobuf的好處是有spec就可以自己mock, 這樣不僅可以同步開發, 也可以在測試時排除外部服務的影響。
實際上開發的專案檔案結構會複雜得多, 檔案結構的部分就明天分享囉。