使用するのは簡単gRPC-インターセプター

アウトライン

一般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法を介して確立された接続を提供して提供します。一価フローインターセプタインターセプタ機能が実質的に同じであると、特定のアプリケーションは、ライブラリ関連文書又はソースコードを参照することができます。

おすすめ

転載: www.cnblogs.com/coloc/p/11360071.html