0

Looking at the helloworld example from grpc-go, how can I add a StopGrpcServer() function to stop gRPC server?

I'm trying to make a shared C library file of gRPC server which can be used to start and stop the gRPC server by invoking the functions via ffi.

In my tests I am able to start the gRPC server with StartGrpcServer() but I'm feeling lost how to implement StopGrpcServer().

package main

import C

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "google.golang.org/grpc/examples/helloworld/helloworld"
)

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
}

//export StopGrpcServer
func (s *server) StopGrpcServer() {
    s.Stop()
}

//export StartGrpcServer
func StartGrpcServer() {
    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)
    }
}

func main() {}

Would really appreciate some help on it.

Thanks, Satinder

satinder
  • 173
  • 3
  • 16
  • 3
    You need to call [Stop()](https://godoc.org/google.golang.org/grpc#Server.Stop) on the `grpc.Server` created by `grpc.NewServer()`, not your custom `server` struct. – Marc Jul 08 '20 at 16:19
  • Thanks for the hint @Marc. I'm able to solve the problem by declaring `*grpc.Server` variable as global variable. Posted my code in answers. – satinder Jul 08 '20 at 17:23

1 Answers1

3

Thanks for the hint @Marc. I am able to solve the problem by declaring *grpc.Server variable globally outside StartGrpcServer(), and then using it in StopGrpcServer().

Here's the working code:

package main

import C

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "google.golang.org/grpc/examples/helloworld/helloworld"
)

var srv *grpc.Server

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
}

//export StopGrpcServer
func StopGrpcServer() {
    srv.Stop()
}

//export StartGrpcServer
func StartGrpcServer() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    srv = grpc.NewServer()
    pb.RegisterGreeterServer(srv, &server{})
    if err := srv.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

func main() {}


// Compile with command:
// go build -o greeter.so -buildmode=c-shared server.go
satinder
  • 173
  • 3
  • 16