├── chat.proto ├── chat ├── chat.go └── chat.pb.go ├── client.go ├── go.mod ├── go.sum └── server.go /chat.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package chat; 3 | 4 | message Message { 5 | string body = 1; 6 | } 7 | 8 | service ChatService { 9 | rpc SayHello(Message) returns (Message) {} 10 | } -------------------------------------------------------------------------------- /chat/chat.go: -------------------------------------------------------------------------------- 1 | package chat 2 | 3 | import ( 4 | "log" 5 | 6 | "golang.org/x/net/context" 7 | ) 8 | 9 | type Server struct { 10 | } 11 | 12 | func (s *Server) SayHello(ctx context.Context, message *Message) (*Message, error) { 13 | log.Printf("Received message body from client: %s", message.Body) 14 | return &Message{Body: "Hello From the Server!"}, nil 15 | } 16 | -------------------------------------------------------------------------------- /chat/chat.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: chat.proto 3 | 4 | package chat 5 | 6 | import proto "github.com/golang/protobuf/proto" 7 | import fmt "fmt" 8 | import math "math" 9 | 10 | import ( 11 | context "golang.org/x/net/context" 12 | grpc "google.golang.org/grpc" 13 | ) 14 | 15 | // Reference imports to suppress errors if they are not otherwise used. 16 | var _ = proto.Marshal 17 | var _ = fmt.Errorf 18 | var _ = math.Inf 19 | 20 | // This is a compile-time assertion to ensure that this generated file 21 | // is compatible with the proto package it is being compiled against. 22 | // A compilation error at this line likely means your copy of the 23 | // proto package needs to be updated. 24 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 25 | 26 | type Message struct { 27 | Body string `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` 28 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 29 | XXX_unrecognized []byte `json:"-"` 30 | XXX_sizecache int32 `json:"-"` 31 | } 32 | 33 | func (m *Message) Reset() { *m = Message{} } 34 | func (m *Message) String() string { return proto.CompactTextString(m) } 35 | func (*Message) ProtoMessage() {} 36 | func (*Message) Descriptor() ([]byte, []int) { 37 | return fileDescriptor_chat_91f479c7d1a62b93, []int{0} 38 | } 39 | func (m *Message) XXX_Unmarshal(b []byte) error { 40 | return xxx_messageInfo_Message.Unmarshal(m, b) 41 | } 42 | func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 43 | return xxx_messageInfo_Message.Marshal(b, m, deterministic) 44 | } 45 | func (dst *Message) XXX_Merge(src proto.Message) { 46 | xxx_messageInfo_Message.Merge(dst, src) 47 | } 48 | func (m *Message) XXX_Size() int { 49 | return xxx_messageInfo_Message.Size(m) 50 | } 51 | func (m *Message) XXX_DiscardUnknown() { 52 | xxx_messageInfo_Message.DiscardUnknown(m) 53 | } 54 | 55 | var xxx_messageInfo_Message proto.InternalMessageInfo 56 | 57 | func (m *Message) GetBody() string { 58 | if m != nil { 59 | return m.Body 60 | } 61 | return "" 62 | } 63 | 64 | func init() { 65 | proto.RegisterType((*Message)(nil), "chat.Message") 66 | } 67 | 68 | // Reference imports to suppress errors if they are not otherwise used. 69 | var _ context.Context 70 | var _ grpc.ClientConn 71 | 72 | // This is a compile-time assertion to ensure that this generated file 73 | // is compatible with the grpc package it is being compiled against. 74 | const _ = grpc.SupportPackageIsVersion4 75 | 76 | // ChatServiceClient is the client API for ChatService service. 77 | // 78 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. 79 | type ChatServiceClient interface { 80 | SayHello(ctx context.Context, in *Message, opts ...grpc.CallOption) (*Message, error) 81 | } 82 | 83 | type chatServiceClient struct { 84 | cc *grpc.ClientConn 85 | } 86 | 87 | func NewChatServiceClient(cc *grpc.ClientConn) ChatServiceClient { 88 | return &chatServiceClient{cc} 89 | } 90 | 91 | func (c *chatServiceClient) SayHello(ctx context.Context, in *Message, opts ...grpc.CallOption) (*Message, error) { 92 | out := new(Message) 93 | err := c.cc.Invoke(ctx, "/chat.ChatService/SayHello", in, out, opts...) 94 | if err != nil { 95 | return nil, err 96 | } 97 | return out, nil 98 | } 99 | 100 | // ChatServiceServer is the server API for ChatService service. 101 | type ChatServiceServer interface { 102 | SayHello(context.Context, *Message) (*Message, error) 103 | } 104 | 105 | func RegisterChatServiceServer(s *grpc.Server, srv ChatServiceServer) { 106 | s.RegisterService(&_ChatService_serviceDesc, srv) 107 | } 108 | 109 | func _ChatService_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 110 | in := new(Message) 111 | if err := dec(in); err != nil { 112 | return nil, err 113 | } 114 | if interceptor == nil { 115 | return srv.(ChatServiceServer).SayHello(ctx, in) 116 | } 117 | info := &grpc.UnaryServerInfo{ 118 | Server: srv, 119 | FullMethod: "/chat.ChatService/SayHello", 120 | } 121 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 122 | return srv.(ChatServiceServer).SayHello(ctx, req.(*Message)) 123 | } 124 | return interceptor(ctx, in, info, handler) 125 | } 126 | 127 | var _ChatService_serviceDesc = grpc.ServiceDesc{ 128 | ServiceName: "chat.ChatService", 129 | HandlerType: (*ChatServiceServer)(nil), 130 | Methods: []grpc.MethodDesc{ 131 | { 132 | MethodName: "SayHello", 133 | Handler: _ChatService_SayHello_Handler, 134 | }, 135 | }, 136 | Streams: []grpc.StreamDesc{}, 137 | Metadata: "chat.proto", 138 | } 139 | 140 | func init() { proto.RegisterFile("chat.proto", fileDescriptor_chat_91f479c7d1a62b93) } 141 | 142 | var fileDescriptor_chat_91f479c7d1a62b93 = []byte{ 143 | // 112 bytes of a gzipped FileDescriptorProto 144 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4a, 0xce, 0x48, 0x2c, 145 | 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x01, 0xb1, 0x95, 0x64, 0xb9, 0xd8, 0x7d, 0x53, 146 | 0x8b, 0x8b, 0x13, 0xd3, 0x53, 0x85, 0x84, 0xb8, 0x58, 0x92, 0xf2, 0x53, 0x2a, 0x25, 0x18, 0x15, 147 | 0x18, 0x35, 0x38, 0x83, 0xc0, 0x6c, 0x23, 0x4b, 0x2e, 0x6e, 0xe7, 0x8c, 0xc4, 0x92, 0xe0, 0xd4, 148 | 0xa2, 0xb2, 0xcc, 0xe4, 0x54, 0x21, 0x2d, 0x2e, 0x8e, 0xe0, 0xc4, 0x4a, 0x8f, 0xd4, 0x9c, 0x9c, 149 | 0x7c, 0x21, 0x5e, 0x3d, 0xb0, 0x61, 0x50, 0xdd, 0x52, 0xa8, 0x5c, 0x25, 0x86, 0x24, 0x36, 0xb0, 150 | 0x35, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x7c, 0xe7, 0x3e, 0x74, 0x00, 0x00, 0x00, 151 | } 152 | -------------------------------------------------------------------------------- /client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "golang.org/x/net/context" 7 | "google.golang.org/grpc" 8 | 9 | "github.com/tutorialedge/go-grpc-tutorial/chat" 10 | ) 11 | 12 | func main() { 13 | var conn *grpc.ClientConn 14 | conn, err := grpc.Dial(":9000", grpc.WithInsecure()) 15 | if err != nil { 16 | log.Fatalf("could not connect: %s", err) 17 | } 18 | defer conn.Close() 19 | 20 | c := chat.NewChatServiceClient(conn) 21 | 22 | message := chat.Message{ 23 | Body: "Hello from the client!", 24 | } 25 | 26 | response, err := c.SayHello(context.Background(), &message) 27 | if err != nil { 28 | log.Fatalf("Error when calling SayHello: %s", err) 29 | } 30 | 31 | log.Printf("Response from Server: %s", response.Body) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tutorialedge/go-grpc-tutorial 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/golang/protobuf v1.3.3 7 | golang.org/x/net v0.0.0-20190311183353-d8887717615a 8 | google.golang.org/grpc v1.29.1 9 | ) 10 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 4 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 5 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 6 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 7 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 8 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 9 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 10 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 11 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 12 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 13 | github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= 14 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 15 | github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= 16 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 17 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 18 | github.com/tutorialedge/go v0.0.0-20200426143337-94a947fd7aa4 h1:5EYSz9UAxLGzBCf54jCkUWJxryUulw+wT8XByuAYDlQ= 19 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 20 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 21 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 22 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 23 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 24 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 25 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 26 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 27 | golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= 28 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 29 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 30 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 31 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 32 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 33 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 34 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= 35 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 36 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 37 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 38 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 39 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 40 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 41 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 42 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 43 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 44 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 45 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= 46 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 47 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 48 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 49 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 50 | google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= 51 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 52 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 53 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 54 | -------------------------------------------------------------------------------- /server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net" 6 | 7 | "github.com/tutorialedge/go-grpc-tutorial/chat" 8 | "google.golang.org/grpc" 9 | ) 10 | 11 | func main() { 12 | lis, err := net.Listen("tcp", ":9000") 13 | if err != nil { 14 | log.Fatalf("Failed to listen on port 9000: %v", err) 15 | } 16 | 17 | s := chat.Server{} 18 | 19 | grpcServer := grpc.NewServer() 20 | 21 | chat.RegisterChatServiceServer(grpcServer, &s) 22 | 23 | if err := grpcServer.Serve(lis); err != nil { 24 | log.Fatalf("Failed to serve gRPC server over port 9000: %v", err) 25 | } 26 | 27 | } 28 | --------------------------------------------------------------------------------