$brewinstallprotobufprotoc-gen-goprotoc-gen-go-grpc$exportGO111MODULE=off# 有的包必须要装到$GOPATH/src下$cd$GOPATH/src$gitclonehttps://github.com/golang/text.git./golang.org/x/text$gitclonehttps://github.com/golang/net.git./golang.org/x/net$gitclonehttps://github.com/grpc/grpc-go./google.golang.org/grpc$gitclonehttps://github.com/google/go-genproto.git./google.golang.org/genproto$gitclonehttps://github.com/protocolbuffers/protobuf-go.git./google.golang.org/protobuf$gitclonehttps://github.com/golang/protobuf.git./github.com/golang/protobuf$gitclonehttps://github.com/googleapis/googleapis./googleapis# 这个包直接放src目录下$exportGO111MODULE=on# 开启 go mod 才能安装指定版本# $ go install github.com/golang/protobuf/[email protected] # 这个代码生成的包不装太新的
// server is used to implement helloworld.SimpleServer.
type server struct{}
// SayHello implements helloworld.SimpleServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Printf("Received: %v", in.Name)
return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer(grpc.UnaryInterceptor(UnaryServerInterceptor))
pb.RegisterSimpleServiceServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
func (s *Server) register(sd *ServiceDesc, ss interface{}) {
...
srv := &service{
server: ss,
md: make(map[string]*MethodDesc),
sd: make(map[string]*StreamDesc),
mdata: sd.Metadata,
}
for i := range sd.Methods {
d := &sd.Methods[i]
srv.md[d.MethodName] = d
}
for i := range sd.Streams {
d := &sd.Streams[i]
srv.sd[d.StreamName] = d
}
s.m[sd.ServiceName] = srv
}
func (s *Server) Serve(lis net.Listener) error {
...
var tempDelay time.Duration // how long to sleep on accept failure
for {
rawConn, err := lis.Accept()
if err != nil {
if ne, ok := err.(interface {
Temporary() bool
}); ok && ne.Temporary() {
if tempDelay == 0 {
tempDelay = 5 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
s.mu.Lock()
s.printf("Accept error: %v; retrying in %v", err, tempDelay)
s.mu.Unlock()
timer := time.NewTimer(tempDelay)
select {
case <-timer.C:
case <-s.quit:
timer.Stop()
return nil
}
continue
}
...
return err
}
tempDelay = 0
// Start a new goroutine to deal with rawConn so we don't stall this Accept
// loop goroutine.
//
// Make sure we account for the goroutine so GracefulStop doesn't nil out
// s.conns before this conn can be added.
s.serveWG.Add(1)
go func() {
s.handleRawConn(rawConn)
s.serveWG.Done()
}()
}
}
func main() {
// Set up a connection to the server.
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewSimpleServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "world"})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("call response message: %s", r.Message)
}
func (c *simpleServiceClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
out := new(HelloReply)
err := c.cc.Invoke(ctx, "/grpc_demo.SimpleService/SayHello", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
$ cd $GOPATH/src/github.com/zhhnzw # 需要在$GOPATH/src下操作,安装到$GOPATH/bin
$ mkdir tool
$ cd tool
$ go mod init tool
$ go mod tidy
$ go install \
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
google.golang.org/protobuf/cmd/protoc-gen-go \
google.golang.org/grpc/cmd/protoc-gen-go-grpc