1. 客户端参数存在repeated 参数注意点
proto
syntax = "proto3";
option go_package=".;proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
message HelloRequest{
string name =1;
repeated int32 id = 2;
}
message HelloReply{
string message = 1;
}
客户端服务端
Go 客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
)
func main() {
conn,err:=grpc.Dial("127.0.0.1:8080",grpc.WithInsecure())
if err!=nil {
fmt.Println("net.Dial err"+err.Error())
}
c := proto.NewGreeterClient(conn)
hello_res :=&proto.HelloRequest{
Name: "hello name 2 ",
}
hello_res.Id = []int32{1,2,3,4,5}
//r,err := c.SayHello(context.Background(),&proto.HelloRequest{Name:"hello name",Id: []int32{1,2,3}})
r,err := c.SayHello(context.Background(),hello_res)
if err!=nil{
panic(err)
}
fmt.Println(r.Message)
// 输出 name is hello name 2 id is [1 2 3 4 5]
defer conn.Close()
}
Go 服务端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
"net"
)
type Server struct {
}
func (this *Server) SayHello(ctx context.Context,res *proto.HelloRequest)(resp *proto.HelloReply,err error){
return &proto.HelloReply{
Message: fmt.Sprintf("name is %s id is %v",res.Name,res.Id),
},nil
}
func main() {
g:=grpc.NewServer()
s := Server{}
proto.RegisterGreeterServer(g,&s)
lis, err := net.Listen("tcp", fmt.Sprintf(":8080"))
if err != nil {
panic("failed to listen: "+err.Error())
}
g.Serve(lis)
}
Python 客户端
需要注意的是如果参数中存在数组类型,那么参数赋值形式要么直接赋值,要么使用内置的append 或者extend方法
from grpc_demo.proto import helloworld_pb2_grpc,helloworld_pb2
import grpc
if __name__ == '__main__':
with grpc.insecure_channel("localhost:50051") as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
hello_request = helloworld_pb2.HelloRequest()
hello_request.name = "你好name"
hello_request.id.extend([1,2])
# or hello_request.id.append(1)
# hello_request.id = [1,2,3] 这种形式是错误的
# resp = stub.SayHello(helloworld_pb2.HelloRequest(name="你好name",id=[1,2,3]))
resp = stub.SayHello(hello_request)
print(resp.message)
Python 服务端
from grpc_demo.proto import helloworld_pb2, helloworld_pb2_grpc
import grpc
from concurrent import futures
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message=f" name: {request.name} id = {request.id}")
if __name__ == '__main__':
# 实例化server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 注册逻辑到server
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
# 启动
server.add_insecure_port('127.0.0.1:50051')
server.start()
server.wait_for_termination()
2. option go_package 作用
如 option go_package=”./common/proto/v1;v1”; 表示将文件生成在当前proto文件下的/common/proto/v1中 且包名为 v1(对go有效),有利于包管理
3. proto文件引入其他proto文件
Python 版本
base.proto
syntax = "proto3";
message Empty {
string name=1;
}
message Pong {
string name=1;
}
helloworld.proto
syntax = "proto3";
option go_package="./;proto";
import "base.proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
rpc Ping(Empty) returns(Pong){}
}
message HelloRequest{
string name =1;
repeated int32 id=2;
}
message HelloReply{
string message = 1;
}
客户端
from grpc_demo.proto import helloworld_pb2_grpc,helloworld_pb2
import grpc
if __name__ == '__main__':
with grpc.insecure_channel("localhost:50051") as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
resp = stub.SayHello(helloworld_pb2.HelloRequest(name="你好name",id=[1,2,3]))
resp1 = stub.Ping(helloworld_pb2_grpc.base__pb2.Empty(name="name11"))
print(resp.message)
print(resp1,"-----")
# 输出
# name: 你好name id = [1, 2, 3]
name: " name is name11"
-----
服务端
from grpc_demo.proto import helloworld_pb2, helloworld_pb2_grpc
from concurrent import futures
import grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message=f" name: {request.name} id = {request.id}")
def Ping(self, request, context):
return helloworld_pb2.base__pb2.Pong(name=f" name is {request.name}")
if __name__ == '__main__':
# 实例化server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 注册逻辑到server
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
# 启动
server.add_insecure_port('127.0.0.1:50051')
server.start()
server.wait_for_termination()
Go 版本
base.proto
syntax = "proto3";
message Empty {
string name=1;
}
message Pong {
string name=1;
}
helloworld.proto
syntax = "proto3";
option go_package=".;proto";
import "base.proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
rpc Ping(Empty) returns(Pong){}
}
message HelloRequest{
string name =1;
repeated int32 id = 2;
}
message HelloReply{
string message = 1;
}
客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
)
func main() {
conn,err:=grpc.Dial("127.0.0.1:8080",grpc.WithInsecure())
if err!=nil {
fmt.Println("net.Dial err"+err.Error())
}
c := proto.NewGreeterClient(conn)
r,err := c.SayHello(context.Background(),&proto.HelloRequest{Name:"hello name",Id: []int32{1,2,3}})
r1,_ := c.Ping(context.Background(),&proto.Empty{Name: "empty name"})
if err!=nil{
panic(err)
}
fmt.Println(r.Message)
fmt.Println(r1)
// 输出
// name is hello name id is [1 2 3]
name:"pong name is empty name"
defer conn.Close()
}
服务端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
"net"
)
type Server struct {
}
func (this *Server) SayHello(ctx context.Context,res *proto.HelloRequest)(resp *proto.HelloReply,err error){
return &proto.HelloReply{
Message: fmt.Sprintf("name is %s id is %v",res.Name,res.Id),
},nil
}
func (this *Server) Ping(ctx context.Context,res *proto.Empty)(resp *proto.Pong,err error){
return &proto.Pong{
Name: fmt.Sprintf("pong name is %s",res.Name),
},nil
}
func main() {
g:=grpc.NewServer()
s := Server{}
proto.RegisterGreeterServer(g,&s)
lis, err := net.Listen("tcp", fmt.Sprintf(":8080"))
if err != nil {
panic("failed to listen: "+err.Error())
}
g.Serve(lis)
}
4. message 嵌套
直接嵌套在message里面
proto
syntax = "proto3";
option go_package=".;proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
message HelloRequest{
string name =1;
repeated int32 id=2;
}
message HelloReply{
string message = 1;
message Result {
string code=1;
string msg=2;
}
repeated Result data =2;
}
Python
客户端
from proto import helloworld_pb2_grpc,helloworld_pb2
import grpc
if __name__ == '__main__':
with grpc.insecure_channel("127.0.0.1:50051") as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
resp = stub.SayHello(helloworld_pb2.HelloRequest(name="你好name",id=[1,2,3]))
print(resp.message)
print("----------------")
for i in resp.data:
print(i.code,"++",i.msg)
输出
name: 你好name id = [1, 2, 3]
————————
111 ++ success
000 ++ fail
服务端
from proto import helloworld_pb2, helloworld_pb2_grpc
from concurrent import futures
import grpc
a = helloworld_pb2.HelloReply.Result()
a.code = "111"
a.msg = "success"
b = helloworld_pb2.HelloReply.Result()
b.code = "000"
b.msg = "fail"
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message=f" name: {request.name} id = {request.id}",
data=[a,b])
if __name__ == '__main__':
# 实例化server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 注册逻辑到server
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
# 启动
server.add_insecure_port('127.0.0.1:50051')
server.start()
server.wait_for_termination()
Go
客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
)
func main() {
conn,err:=grpc.Dial("127.0.0.1:8080",grpc.WithInsecure())
if err!=nil {
fmt.Println("net.Dial err"+err.Error())
}
c := proto.NewGreeterClient(conn)
r,err := c.SayHello(context.Background(),&proto.HelloRequest{Name:"hello name",Id: []int32{1,2,3}})
if err!=nil{
panic(err)
}
fmt.Println(r.Message)
fmt.Println(r.Data)
// 输出
name is hello name
[code:"11" msg:"success" code:"00" msg:"fail"]
defer conn.Close()
}
服务端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
"net"
)
type Server struct {
}
func (this *Server) SayHello(ctx context.Context,res *proto.HelloRequest)(resp *proto.HelloReply,err error){
rs:=[]*proto.HelloReply_Result{
&proto.HelloReply_Result{Code: "11",Msg: "success"},
&proto.HelloReply_Result{Code: "00",Msg: "fail"},
}
return &proto.HelloReply{
Message: fmt.Sprintf("name is %s",res.Name),
Data: rs,
},nil
}
func main() {
g:=grpc.NewServer()
s := Server{}
proto.RegisterGreeterServer(g,&s)
lis, err := net.Listen("tcp", fmt.Sprintf(":8080"))
if err != nil {
panic("failed to listen: "+err.Error())
}
g.Serve(lis)
}
数据类型在message之外
proto
syntax = "proto3";
option go_package = ".;proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
message HelloRequest{
string name = 1;
repeated int32 id = 2;
}
message Result {
string code = 1;
string msg = 2;
}
message HelloReply{
string message = 1;
repeated Result data = 2;
}
Python
客户端
from proto import helloworld_pb2_grpc,helloworld_pb2
import grpc
if __name__ == '__main__':
with grpc.insecure_channel("127.0.0.1:50051") as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
resp = stub.SayHello(helloworld_pb2.HelloRequest(name="你好name",id=[1,2,3]))
print(resp.message)
print("----------------")
for i in resp.data:
print(i.code,"++",i.msg)
服务端
from proto import helloworld_pb2, helloworld_pb2_grpc
from concurrent import futures
import grpc
a = helloworld_pb2.Result()
a.code = "111"
a.msg = "success"
b = helloworld_pb2.Result()
b.code = "000"
b.msg = "fail"
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message=f" name: {request.name} id = {request.id}",
data=[a,b])
if __name__ == '__main__':
# 实例化server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 注册逻辑到server
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
# 启动
server.add_insecure_port('127.0.0.1:50051')
server.start()
server.wait_for_termination()
Go
客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
)
func main() {
conn,err:=grpc.Dial("127.0.0.1:8080",grpc.WithInsecure())
if err!=nil {
fmt.Println("net.Dial err"+err.Error())
}
c := proto.NewGreeterClient(conn)
r,err := c.SayHello(context.Background(),&proto.HelloRequest{Name:"hello name",Id: []int32{1,2,3}})
if err!=nil{
panic(err)
}
fmt.Println(r.Message)
fmt.Println(r.Data)
defer conn.Close()
}
服务端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
"net"
)
type Server struct {
}
func (this *Server) SayHello(ctx context.Context,res *proto.HelloRequest)(resp *proto.HelloReply,err error){
rs:=[]*proto.Result{
&proto.Result{Code: "11",Msg: "success"},
&proto.Result{Code: "00",Msg: "fail"},
}
return &proto.HelloReply{
Message: fmt.Sprintf("name is %s",res.Name),
Data: rs,
},nil
}
func main() {
g:=grpc.NewServer()
s := Server{}
proto.RegisterGreeterServer(g,&s)
lis, err := net.Listen("tcp", fmt.Sprintf(":8080"))
if err != nil {
panic("failed to listen: "+err.Error())
}
g.Serve(lis)
}
5. enum 枚举类型
proto
syntax = "proto3";
option go_package = ".;proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
enum Gender {
Male = 0;
Female = 1;
}
message HelloRequest{
string name = 1;
repeated int32 id = 2;
Gender sex = 3;
}
message Result {
string code = 1;
string msg = 2;
}
message HelloReply{
string message = 1;
repeated Result data = 2;
}
Python
客户端
from proto import helloworld_pb2_grpc,helloworld_pb2
import grpc
if __name__ == '__main__':
with grpc.insecure_channel("127.0.0.1:50051") as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
resp = stub.SayHello(helloworld_pb2.HelloRequest(name="你好name",id=[1,2,3],
sex=helloworld_pb2.Male))
print(resp.message)
print("----------------")
for i in resp.data:
print(i.code,"++",i.msg)
服务端
from proto import helloworld_pb2, helloworld_pb2_grpc
from concurrent import futures
import grpc
a = helloworld_pb2.Result()
a.code = "111"
a.msg = "success"
b = helloworld_pb2.Result()
b.code = "000"
b.msg = "fail"
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
print(request.sex)
return helloworld_pb2.HelloReply(message=f" name: {request.name} id = {request.id}",
data=[a,b])
if __name__ == '__main__':
# 实例化server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 注册逻辑到server
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
# 启动
server.add_insecure_port('127.0.0.1:50051')
server.start()
server.wait_for_termination()
Go
客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
)
func main() {
conn,err:=grpc.Dial("127.0.0.1:8080",grpc.WithInsecure())
if err!=nil {
fmt.Println("net.Dial err"+err.Error())
}
c := proto.NewGreeterClient(conn)
r,err := c.SayHello(context.Background(),
&proto.HelloRequest{Name:"hello name",
Id: []int32{1,2,3},Sex: proto.Gender_Female})
if err!=nil{
panic(err)
}
fmt.Println(r.Message)
fmt.Println(r.Data)
defer conn.Close()
}
服务端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
"net"
)
type Server struct {
}
func (this *Server) SayHello(ctx context.Context,res *proto.HelloRequest)(resp *proto.HelloReply,err error){
rs:=[]*proto.Result{
&proto.Result{Code: "11",Msg: "success"},
&proto.Result{Code: "00",Msg: "fail"},
}
fmt.Println(fmt.Sprintf("Gender is %v",res.Sex))
return &proto.HelloReply{
Message: fmt.Sprintf("name is %s",res.Name),
Data: rs,
},nil
}
func main() {
g:=grpc.NewServer()
s := Server{}
proto.RegisterGreeterServer(g,&s)
lis, err := net.Listen("tcp", fmt.Sprintf(":8080"))
if err != nil {
panic("failed to listen: "+err.Error())
}
g.Serve(lis)
}
6 . map 类型
proto
syntax = "proto3";
option go_package = ".;proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
message HelloRequest{
string name = 1;
repeated int32 id = 2;
map<string,string> mp = 3;
}
message Result {
string code = 1;
string msg = 2;
}
message HelloReply{
string message = 1;
repeated Result data = 2;
}
Python
客户端
服务端
Go
客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc_demo/proto"
)
func main() {
conn,err:=grpc.Dial("127.0.0.1:8080",grpc.WithInsecure())
if err!=nil {
fmt.Println("net.Dial err"+err.Error())
}
c := proto.NewGreeterClient(conn)
r,err := c.SayHello(context.Background(),
&proto.HelloRequest{Name:"hello name",
Id: []int32{1,2,3},
Mp:map[string]string{"name":"zhangsan",
"age":"14"}})
if err!=nil{
panic(err)
}
fmt.Println(r.Message)
fmt.Println(r.Data)
defer conn.Close()
}
服务端
雷同
输出即可
Mp is map[age:14 name:zhangsan]
7. grpc metadata信息
proto
syntax = "proto3";
option go_package = ".;proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
message HelloRequest{
string name = 1;
}
message HelloReply{
string message = 1;
}
Python
客户端
from proto import helloworld_pb2_grpc,helloworld_pb2
import grpc
if __name__ == '__main__':
with grpc.insecure_channel("127.0.0.1:50051") as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
resp = stub.SayHello.with_call(
helloworld_pb2.HelloRequest(name='myname'),
metadata=(
('name', 'zhangsan'),
('password', '123456')
)
)
print(resp[0].message)
服务端
from proto import helloworld_pb2, helloworld_pb2_grpc
from concurrent import futures
import grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
for key, value in context.invocation_metadata():
print('Received initial metadata: key=%s value=%s' % (key, value))
return helloworld_pb2.HelloReply(message=f" name: {request.name}")
if __name__ == '__main__':
# 实例化server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 注册逻辑到server
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
# 启动
server.add_insecure_port('127.0.0.1:50051')
server.start()
server.wait_for_termination()
输出
Received initial metadata: key=name value=zhangsan
Received initial metadata: key=password value=123456
Received initial metadata: key=user-agent value=grpc-python/1.33.2 grpc-c/13.0.0 (windows; chttp2)
Go
客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"grpc_demo/proto"
)
func main() {
md := metadata.New(map[string]string{"key1": "val1", "key2": "val2"})
// md
//md := metadata.Pairs(
// "key1", "val1",
// "key1", "val1-2",
// "key2", "val2",
//)
ctx := metadata.NewOutgoingContext(context.Background(), md)
conn,err:=grpc.Dial("127.0.0.1:8080",grpc.WithInsecure())
if err!=nil {
fmt.Println("net.Dial err"+err.Error())
}
c := proto.NewGreeterClient(conn)
r,err := c.SayHello(ctx,
&proto.HelloRequest{Name:"hello name"})
if err!=nil{
panic(err)
}
fmt.Println(r.Message)
defer conn.Close()
}
服务端
输出
map[:authority:[127.0.0.1:8080] content-type:[application/grpc] key1:[val1] key2:[val2] user-agent:[grpc-go/1.33.2]] true
8 grpc拦截器
proto
syntax = "proto3";
option go_package = ".;proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
message HelloRequest{
string name = 1;
}
message HelloReply{
string message = 1;
}
Python
客户端
from proto import helloworld_pb2_grpc,helloworld_pb2
import grpc
class DefaultInterceptor(grpc.UnaryUnaryClientInterceptor):
def intercept_unary_unary(self, continuation, client_call_details, request):
from datetime import datetime
start = datetime.now()
res = continuation(client_call_details,request)
print((datetime.now()-start).microseconds/1000)
return res
if __name__ == '__main__':
defaultintercept = DefaultInterceptor()
with grpc.insecure_channel("127.0.0.1:50051") as channel:
intecept = grpc.intercept_channel(channel,defaultintercept)
stub = helloworld_pb2_grpc.GreeterStub(intecept)
resp = stub.SayHello.with_call(
helloworld_pb2.HelloRequest(name='myname'),
metadata=(
('name', 'zhangsan'),
('password', '123456')
)
)
print(resp[0].message)
服务端
from proto import helloworld_pb2, helloworld_pb2_grpc
from concurrent import futures
import grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
for key, value in context.invocation_metadata():
print('Received initial metadata: key=%s value=%s' % (key, value))
return helloworld_pb2.HelloReply(message=f" name: {request.name}")
class LogInterceptor(grpc.ServerInterceptor):
def intercept_service(self, continuation, handler_call_details):
print("请求结束")
resp = continuation(handler_call_details)
print("请求结束")
return resp
if __name__ == '__main__':
interceptor = LogInterceptor()
# 实例化server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10),interceptors=[interceptor])
# 注册逻辑到server
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
# 启动
server.add_insecure_port('127.0.0.1:50051')
server.start()
server.wait_for_termination()
Go
客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"grpc_demo/proto"
"time"
)
func main() {
intercaptor:=func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error{
start:=time.Now()
err:=invoker(ctx,method,req,reply,cc,opts...)
fmt.Printf("耗时%s\n",time.Since(start))
fmt.Println(err)
return err
}
opt:=grpc.WithUnaryInterceptor(intercaptor)
md := metadata.New(map[string]string{"key1": "val1", "key2": "val2",})
ctx := metadata.NewOutgoingContext(context.Background(), md)
conn,err:=grpc.Dial("127.0.0.1:8080",grpc.WithInsecure(),opt)
if err!=nil {
fmt.Println("net.Dial err"+err.Error())
}
c := proto.NewGreeterClient(conn)
r,err := c.SayHello(ctx,
&proto.HelloRequest{Name:"hello name"})
if err!=nil{
panic(err)
}
fmt.Println(r.Message)
defer conn.Close()
}
服务端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"grpc_demo/proto"
"net"
)
type Server struct {
}
func (this *Server) SayHello(ctx context.Context,res *proto.HelloRequest)(resp *proto.HelloReply,err error){
// 接收metadata信息
md, ok := metadata.FromIncomingContext(ctx)
fmt.Println(md,ok)
return &proto.HelloReply{
Message: fmt.Sprintf("name is %s",res.Name),
},nil
}
func main() {
intercaptor:= func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error){
fmt.Println("接收到请求 ")
res,err:= handler(ctx,req)
fmt.Println("请求结束")
return res,err
}
opt:=grpc.UnaryInterceptor(intercaptor)
g:=grpc.NewServer(opt)
s := Server{}
proto.RegisterGreeterServer(g,&s)
lis, err := net.Listen("tcp", fmt.Sprintf(":8080"))
if err != nil {
panic("failed to listen: "+err.Error())
}
g.Serve(lis)
}
9 grpc-gateway
proto
syntax = "proto3";
option go_package=".;proto";
import "google/api/annotations.proto";
service DemoService {
rpc Echo(StringMessage) returns (StringMessage) {
option (google.api.http) = {
post: "/v1/example/echo"
body: "*"
};
}
rpc GetMessage(Empty) returns (GETMessage) {
option (google.api.http) = {
get: "/v1/example/echo"
};
}
}
message StringMessage{
string name=1;
}
message Empty {
}
message GETMessage{
repeated string names=1;
}
分别生成 pd.go 和gw.go文件
github.com/grpc-ecosystem/grpc-gateway/tree/master/third_party/googleapis
protoc -I/usr/local/include -I.
-I$GOPATH/src -I$GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway/v2@v2.0.1/third_party/googleapis --go_out=plugins=grpc:. *.proto
protoc -I/usr/local/include -I. -I$GOPATH/src -I$GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway/v2@v2.0.1/third_party/googleapis --grpc-gateway_out=logtostderr=true:. *.proto
server
package main
import (
"context"
"fmt"
"go_demo/grpc_demo/proto"
"log"
"net"
// pb "grpc_demo/proto"
"google.golang.org/grpc"
)
const (
port = "0.0.0.0:8080"
)
type server struct {
proto.UnimplementedDemoServiceServer
}
func (s *server) Echo(ctx context.Context, req *proto.StringMessage) (*proto.StringMessage, error) {
fmt.Println("请求进来了......")
return &proto.StringMessage{Name: "123456789"}, nil
}
func (s *server) GetMessage(ctx context.Context, req *proto.Empty) (*proto.GETMessage, error) {
return &proto.GETMessage{Names: []string{"1", "2", "4", "5"}}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v\n", err)
}
s := grpc.NewServer()
proto.RegisterDemoServiceServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
client
package main
import (
"context"
"go_demo/grpc_demo/proto"
"log"
"time"
"google.golang.org/grpc"
)
const (
addr = "9.135.90.120:58080"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
conn, err := grpc.DialContext(ctx, addr, grpc.WithBlock(), grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v\n", err)
}
defer conn.Close()
c := proto.NewDemoServiceClient(conn)
log.Printf("echo request: wang\n")
r, err := c.Echo(ctx, &proto.StringMessage{Name: "iiiiii"})
if err != nil {
log.Fatalf("could not echo: %v\n", err)
}
log.Printf("Echo reply: %s\n", r.GetName())
}
httpclient
package main
import (
"context"
"flag"
"go_demo/grpc_demo/proto"
"net/http"
"github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
)
var (
GrpcServerEndpoint = flag.String("grpc-server-endpoint", "9.135.90.120:58080", "gRPC server demoserver")
)
func run() error {
ctx := context.Background()
ctx1, cancel := context.WithCancel(ctx)
defer cancel()
mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithInsecure()}
err := proto.RegisterDemoServiceHandlerFromEndpoint(ctx1, mux, *GrpcServerEndpoint, opts)
if err != nil {
return err
}
return http.ListenAndServe("9.135.90.120:8081", mux)
}
func main() {
flag.Parse()
defer glog.Flush()
if err := run(); err != nil {
glog.Fatal(err)
}
}
10 grpc异常处理
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/status"
)
func main() {
st, ok := status.FromError(err)
if ok {
fmt.Println(st.Code(), "-----")
fmt.Println(st.Message(), "+++++++")
}
}