アウトライン
一般gRPC RPCフレームワーク構築された迎撃機能として。サーバ側とクライアント側インターセプタインターセプタ、同様の使用を含みます。主な役割は、RPC呼び出しの前または後に追加の処理を実行することです。
クライアントの観点からは、前の要求は、開始インターセプトやリクエストのパラメータを変更することができ、応答パラメータは、サーバーを変更することができます。
例
以下に、実施の特定の機能を記述するために簡単な例を記述します。例えば、他の言語gRPCライブラリも同様の機能を持っている必要があり、言語に移動し、特定のドキュメントを参照してください。
簡単な例では、それはエラーの処理を簡素化します。そして唯一のコードの一部を示し、完全なプロジェクトGitHubのリポジトリを参照してくださいpnnh /スジ-行きます
インターフェイスの説明
syntax = "proto3";
package suji;
service Suji {
rpc Say(SayRequest) returns (SayReply) {}
}
message SayRequest {
string msg = 1;
}
message SayReply {
string msg = 1;
}
初期の実装
サーバーのmainメソッド
func main() {
lis, err := net.Listen("tcp", "0.0.0.0:1301")
if err != nil {
log.Fatalln("监听出错", err)
return
}
grpcServer := grpc.NewServer()
suji.RegisterSujiServer(grpcServer, &server.SujiServer{})
if err = grpcServer.Serve(lis); err != nil {
log.Fatalln("服务停止", err)
}
}
クライアントの主な方法
func main() {
addr := "127.0.0.1:1301"
c := client.LinkSujiServer(addr)
rep := client.Say(c, msg)
log.Println("收到:", rep.Msg)
}
ここでgRPC LinkSujiServerサーバへ法により接続され、インタフェース発言権を呼び出し、プリントサーバは、値を返します。
LinkSujiServerは、以下の
func LinkSujiServer(target string) suji.SujiClient {
conn, err := grpc.DialContext(context.Background(), target, grpc.WithInsecure())
if err != nil {
log.Fatalln("链接至服务出错", err, target)
}
return suji.NewSujiClient(conn)
}
次のようにインターフェース・クライアントが呼び出すと言います:
func Say(client suji.SujiClient, msg string) *suji.SayReply {
request := &suji.SayRequest{Msg: msg}
reply, err := client.Say(context.Background(), request)
if err != nil {
log.Fatalln("调用出错", err)
}
return reply
}
それは呼び出し元に返されるよう、以下の内容を達成するために、Interfaceサーバーが受信されると言います。
func (s *SujiServer) Say(ctx context.Context, req *suji.SayRequest) (*suji.SayReply, error) {
log.Println("收到:", req.Msg)
reply := &suji.SayReply{Msg: req.Msg}
return reply, nil
}
このコードを実行すると、以下の結果であった印刷します
クライアント:
2019/08/15 18:19:59 发送: 你好
2019/08/15 18:19:59 收到: 你好
サーバー:
2019/08/15 18:19:59 收到: 你好
2019/08/15 18:19:59 回复: 你好
インターセプタを達成
我々は非常にシンプルなインターフェース呼び出しを持っていた、そして今、私たちはこの会話に新しいポイントを追加するgRPCクライアントインターセプタを渡します。
私たちは、サーバから返されたコンテンツも出改ざん、その後、傍受し、サーバーにクライアントから送信されたコンテンツを改ざんするインターセプタます。このすべては、発信者と受信者が知らない、インターセプタで静かに行われます。
インターセプタメソッドを定義します
func callInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn,
invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
if reqParam, ok := req.(*suji.SayRequest); ok {
newMsg := strings.Replace(reqParam.Msg, "喜欢", "讨厌", 1)
req = &suji.SayRequest{Msg: newMsg}
}
err := invoker(ctx, method, req, reply, cc, opts...)
if err != nil {
log.Println("接口调用出错", method, err)
return err
}
if replyParam, ok := reply.(*suji.SayReply); ok {
newMsg := strings.Replace(replyParam.Msg, "讨厌", "喜欢", 1)
replyParam.Msg = newMsg
}
return nil
}
この方法は、インターセプタのオプションを追加し、サーバーへの接続方法を変更するために、ここで、後述します:
func LinkSujiServer(target string) suji.SujiClient {
conn, err := grpc.DialContext(context.Background(), target, grpc.WithInsecure(),
grpc.WithUnaryInterceptor(callInterceptor))
if err != nil {
log.Fatalln("链接至服务出错", err, target)
}
return suji.NewSujiClient(conn)
}
新しいことに注意してくださいgrpc.WithUnaryInterceptor(callInterceptor)この行。
それは私たちの定義されたcallInterceptor gRPCランタイムのためのいくつかの有用なパラメータに渡されます。前記方法は、REQ、それぞれ応答要求インターフェースおよび出力パラメータに対応する、コール・インタフェース・パスです。呼び出しの引数は、このメソッドを呼び出した場合、RPC要求がサーバーに送信されることはありません、オリジナルのRPC要求を実行するための方法です。
ここでは、我々、およびパラメータは、要求と応答タイプを改ざんすることによって決定されます。一方、より多くの興味深い例は、メイン機能コードの簡単な変更を行うためです。
クライアントの主な方法
func main() {
addr := "127.0.0.1:1301"
c := client.LinkSujiServer(addr)
msg := "我喜欢你"
log.Println("发送:", msg)
rep := client.Say(c, msg)
log.Println("收到:", rep.Msg)
if strings.Contains(rep.Msg, "喜欢") {
log.Println("内心:", "好开心啊")
}
}
サーバーメソッドを言います
func (s *SujiServer) Say(ctx context.Context, req *suji.SayRequest) (*suji.SayReply, error) {
log.Println("收到:", req.Msg)
reply := &suji.SayReply{}
if strings.Contains(req.Msg, "讨厌") {
reply.Msg = "我也讨厌你"
}
log.Println("回复:", reply.Msg)
log.Println("内心:", "沙雕")
return reply, nil
}
その下の低出力の感情の内側を見てください:
クライアントの出力:
2019/08/15 19:07:14 发送: 我喜欢你
2019/08/15 19:07:14 收到: 我也喜欢你
2019/08/15 19:07:14 内心: 好开心啊
サーバーの出力:
2019/08/15 19:07:14 收到: 我讨厌你
2019/08/15 19:07:14 回复: 我也讨厌你
2019/08/15 19:07:14 内心: 沙雕
遂に
1元gRPCインターセプタに加えて、フローインターセプタを設定する方法は、grpc.WithStreamInterceptor法を介して確立された接続を提供して提供します。一価フローインターセプタインターセプタ機能が実質的に同じであると、特定のアプリケーションは、ライブラリ関連文書又はソースコードを参照することができます。