web-dev-qa-db-ja.com

gRPC定義のAPIをWebブラウザーに取り込む方法

GRPC-マイクロサービス用のJavascript/HTML guiを構築したいと考えています。ブラウザ側ではgRPCがサポートされていないため、webソケットを使用してnode.jsサーバーに接続し、grpcを介してターゲットサービスを呼び出すことを考えました。これを行うためのエレガントなソリューションを見つけるのに苦労しています。特に、gRPCストリームを使用してマイクロサービス間でイベントをプッシュするためです。フロントエンドとnode.jsサーバー間で通信するためだけに、2番目のRPCシステムが必要なようです。これは、多くのオーバーヘッドと、維持する必要がある追加のコードのようです。

誰かがこのようなことをした経験がありますか、これをどのように解決できるか考えていますか?

67
Oliver

編集:2018年10月23日以降、 gRPC-WebプロジェクトはGA であり、これは問題を解決するための最も公式で標準化された方法かもしれません。 (すでに2018年になったとしても...;))

GA-Blogから: "gRPC-Webは、gRPCと同様に、プロトコルを使用してクライアント(Web)サービスとバックエンドgRPCサービス間のサービス「契約」を定義できます。バッファ。クライアントは自動生成できます。[...] "

最近、gRPC-Web( https://github.com/improbable-eng/grpc-web )を作成しました。これは、提案されたgRPC-Webプロトコルに従うブラウザークライアントおよびサーバーラッパーです。そのレポの例は、良い出発点を提供するはずです。

Golangを使用している場合は、gRPCサーバーのスタンドアロンプ​​ロキシまたはラッパーが必要です。プロキシ/ラッパーは、応答を変更して、応答本文にトレーラをパッケージ化し、ブラウザで読み込めるようにします。

開示:私はプロジェクトのメンテナーです。

31
Marcus

残念ながら、まだ良い答えはありません。

ブラウザからストリーミングRPCをサポートするには、ブラウザがHTTP2トレーラーを完全にサポートしている必要がありますが、この回答の執筆時点ではサポートされていません。

トピックに関する議論については この問題 をご覧ください。

そうでなければ、はい、WebSocketsとgRPCの間に完全な翻訳システムが必要になります。 grpc-gateway からインスピレーションを得ることは、そのようなプロジェクトの始まりかもしれませんが、それはまだ非常に長いショットです。

16
Nicolas Noble

公式のgrpc-web(ベータ)実装が3/23/2018にリリースされました。あなたはそれを見つけることができます

https://github.com/grpc/grpc-web

次の指示はREADMEからのものです。

GRPCサービスを定義します。

service EchoService {
  rpc Echo(EchoRequest) returns (EchoResponse);

  rpc ServerStreamingEcho(ServerStreamingEchoRequest)
      returns (stream ServerStreamingEchoResponse);
}

必要な言語でサーバーを構築します。

JSクライアントを作成して、ブラウザーから呼び出しを行います。

var echoService = new proto.grpc.gateway.testing.EchoServiceClient(
  'http://localhost:8080');

単項RPC呼び出しを行う

var unaryRequest = new proto.grpc.gateway.testing.EchoRequest();
unaryRequest.setMessage(msg);
echoService.echo(unaryRequest, {},
  function(err, response) {
    console.log(response.getMessage());
  });

サーバーからブラウザーへのストリームがサポートされています。

var stream = echoService.serverStreamingEcho(streamRequest, {});
stream.on('data', function(response) {
  console.log(response.getMessage());
});

双方向ストリームはサポートされていません:

これは進行中の作業であり、 grpc-webロードマップ にあります。 protobufの例 bidiストリーミングを示していますが、 このコメント は、この例が実際にはまだ機能しないことを明確にします。

うまくいけば、これはすぐに変更されます。 :)

10
Cody A. Ray

https://github.com/grpc/ のgrpcの人々は現在、js 実装 を構築しています。

再現は https://github.com/grpc/grpc-web (404->)にあります。これは現在(2016-12-20)早期アクセスであるため、必要です アクセスの要求

7
RickyA

https://github.com/tmc/grpc-websocket-proxy それはあなたのニーズを満たすかもしれません。これは、Webソケット上のjsonをgrpc(grpc-gatewayの上のレイヤー)に変換します。

6
tmc

OPがブラウザのサポートを求めたので、WebSocketを介した双方向ソリューションについて多くの回答が指摘されていなかったことがわかります。

WebSocketを介した双方向RPCを取得するために、gRPCの代わりにJSON-RPCを使用できます。これは、WebRTC(ブラウザーからブラウザー)を含む、より多くをサポートします。

このタイプのシリアライゼーションが本当に必要な場合は、gRPCをサポートするように変更できると思います。

ただし、ブラウザータブからブラウザータブの場合、リクエストオブジェクトはシリアル化されず、ネイティブに転送されます。これはNodeJSクラスターまたはスレッドワーカーでも同じであり、パフォーマンスが大幅に向上します。

また、gRPC形式でシリアル化する代わりに、「ポインタ」をSharedArrayBufferに転送できます。

V8でのJSONシリアル化と逆シリアル化も無敵です。

https://github.com/bigstepinc/jsonrpc-bidirectional

1

GRPC Bus WebSocketプロキシは、WebSocket接続を介してすべてのGRPC呼び出しをプロキシすることでこれを正確に行い、ブラウザーのNode GRPC APIと非常によく似たものを提供します。 GRPC-Gatewayとは異なり、ストリーミング要求とストリーミング応答の両方、および非ストリーミング呼び出しで機能します。

サーバーとクライアントの両方のコンポーネントがあります。 GRPC Bus WebSocketプロキシサーバー は、docker run gabrielgrant/grpc-bus-websocket-proxyを実行することでDockerで実行できます。

ブラウザ側では、 GRPC Bus WebSocket Proxy client with npm install grpc-bus-websocket-clientをインストールする必要があります。

次に、new GBC(<grpc-bus-websocket-proxy address>, <protofile-url>, <service map>)を使用して新しいGBCオブジェクトを作成します

例えば:

var GBC = require("grpc-bus-websocket-client");

new GBC("ws://localhost:8080/", 'helloworld.proto', {helloworld: {Greeter: 'localhost:50051'}})
  .connect()
  .then(function(gbc) {
    gbc.services.helloworld.Greeter.sayHello({name: 'Gabriel'}, function(err, res){
      console.log(res);
    });  // --> Hello Gabriel
  });

クライアントライブラリは、AJAX要求で.protoファイルをダウンロードできることを想定しています。 service-mapは、プロキシサーバーから見たprotoファイルで定義されているさまざまなサービスのURLを提供します。

詳細については、 GRPC Bus WebSocketプロキシクライアントのREADME を参照してください。

1
Gabriel Grant

GRPC over webを使用した現在のソリューションを見ると、これを書いている時点で利用可能なもの(および私が見つけたもの)は次のとおりです。

  • gRPC-web :クライアントにTypeScriptが必要
  • gRPC-web-proxy :Goが必要
  • gRPC-gateway :.protoの変更と装飾が必要
  • gRPC-bus-websocket-proxy-server : このドキュメントを書いている時点では、テストが不足しており、放棄されているようです (編集:元の著者によるコメントを見てください!)
  • gRPC-dynamic-gateway :単純なgRPCサービスと認証のやり過ぎは少し厄介です
  • gRPC-bus :トランスポートに何かが必要です

また、会社用に書いた独自のソリューションを恥知らずにプラグインしたいと思います。これは、実稼働環境で、単項およびサーバーストリーミングコールのみを含むgRPCサービスへのリクエストをプロキシするために使用されています。

コードのあらゆるインチがテストで覆われています。 Expressミドルウェアであるため、gRPCセットアップに追加の変更を加える必要はありません。 HTTP認証をExpressに委任することもできます(たとえば、Passportを使用)。

0
Sepehr