在上一篇我們已經有定義.proto的描述檔,並且已生成對應.pb.go檔,所以接下來需以描述檔為基礎,來實現服務端的具體功能。
type ServerService struct{}
var UserData sync.Map
func main() {
lis, err := net.Listen("tcp", ":8081")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterMyprotoServiceServer(s, &ServerService{})
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatal("grpc.Serve Error: ", err)
return
}
}
解說一下上面程式
由於在描述檔有定義三個接口(AddUser、LoginUser、UsersList),所以需在Server端實現對應的function。
// rpc AddUser(UserRequest) returns (UserResponse){}
func (s *ServerService) AddUser(ctx context.Context, in *pb.UserRequest) (*pb.UserResponse, error) {
var result string = "error"
_, ok := UserData.Load(in.UserName)
if !ok {
UserData.Store(in.UserName, in.UserPwd)
result = "ok"
}
return &pb.UserResponse{
Result: result,
}, nil
}
// rpc LoginUser(UserRequest) returns (UserResponse){}
func (s *ServerService) LoginUser(ctx context.Context, in *pb.UserRequest) (*pb.UserResponse, error) {
var result string = "error"
pwd, ok := UserData.Load(in.UserName)
if ok {
if in.UserPwd == pwd {
result = "ok"
}
}
return &pb.UserResponse{
Result: result,
}, nil
}
// rpc UsersList(UsersListRequest) returns (UsersListResponse){}
func (s *ServerService) UsersList(ctx context.Context, in *pb.UsersListRequest) (*pb.UsersListResponse, error) {
var users []string
f := func(k, v interface{}) bool {
var name string
name = k.(string)
fmt.Println(k, v)
users = append(users, name)
return true
}
UserData.Range(f)
return &pb.UsersListResponse{
Result: "ok",
UserName: users,
}, nil
}
以上就完成gRPC Server實作。