# Basic GRPC Setup ## Requirements * protoc * protoc-gen-go ``` go install google.golang.org/protobuf/cmd/protoc-gen-go@latest ``` * protoc-gen-go-grpc ``` go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest ``` * Get lib folder or collect it from protoc/include Folder structure - lib - server - main.go - proto - proto.proto - client - main.go - Makefile ## Writing protofile (proto/proto.proto) ``` syntax = "proto3"; package proto; message Request { } message Response { string message = 1; } service Service { rpc Ping(Request) returns (Response); } ``` ## Writing Makefile ``` protogen-service: protoc -I./lib -I. \ --go_out=plugins=grpc:. \ ./proto/proto.proto ``` if we run ```make protogen-service``` there should be a new generated file inside **proto** directory named ```proto.pb.go``` ## Writing Server (server/main.go) ``` package main import ( "context" "net" "github.com/haquenafeem/msbasic/proto" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) type server struct{} func main() { listener, err := net.Listen("tcp", ":4042") // listens at this port if err != nil { panic(err) } srv := grpc.NewServer() // new grpc server proto.RegisterServiceServer(srv, &server{}) // registering server reflection.Register(srv) // reflecting if e := srv.Serve(listener); e != nil { // serving panic(e) } } // implementing Ping function from proto (Service Interface in generated file) func (s *server) Ping(ctx context.Context, request *proto.Request) (*proto.Response, error) { return &proto.Response{Message: "Ping from server"}, nil } ``` ## Writing Client (client/main.go) ``` package main import ( "context" "fmt" "github.com/haquenafeem/msbasic/proto" "google.golang.org/grpc" ) func main() { // dials to get connection conn, err := grpc.Dial("localhost:4042", grpc.WithInsecure()) if err != nil { panic(err) } // gets new service client from connection client := proto.NewServiceClient(conn) // requests for the method to call req := &proto.Request{} // calls the method using client response, err := client.Ping(context.Background(), req) if err != nil { panic(err) } // prints response fmt.Println(response.Message) } ``` ## Running * Open a terminal -> run ```go run server/main.go``` * Open another terminal -> run ```go run client/main.go``` -> you should see ```Ping from server``` in the console.