GRPC-マイクロサービス用のJavascript/HTML guiを構築したいと考えています。ブラウザ側ではgRPCがサポートされていないため、webソケットを使用してnode.jsサーバーに接続し、grpcを介してターゲットサービスを呼び出すことを考えました。これを行うためのエレガントなソリューションを見つけるのに苦労しています。特に、gRPCストリームを使用してマイクロサービス間でイベントをプッシュするためです。フロントエンドとnode.jsサーバー間で通信するためだけに、2番目のRPCシステムが必要なようです。これは、多くのオーバーヘッドと、維持する必要がある追加のコードのようです。
誰かがこのようなことをした経験がありますか、これをどのように解決できるか考えていますか?
編集: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サーバーのスタンドアロンプロキシまたはラッパーが必要です。プロキシ/ラッパーは、応答を変更して、応答本文にトレーラをパッケージ化し、ブラウザで読み込めるようにします。
開示:私はプロジェクトのメンテナーです。
残念ながら、まだ良い答えはありません。
ブラウザからストリーミングRPCをサポートするには、ブラウザがHTTP2トレーラーを完全にサポートしている必要がありますが、この回答の執筆時点ではサポートされていません。
トピックに関する議論については この問題 をご覧ください。
そうでなければ、はい、WebSocketsとgRPCの間に完全な翻訳システムが必要になります。 grpc-gateway からインスピレーションを得ることは、そのようなプロジェクトの始まりかもしれませんが、それはまだ非常に長いショットです。
公式のgrpc-web(ベータ)実装が3/23/2018にリリースされました。あなたはそれを見つけることができます
次の指示はREADMEからのものです。
service EchoService {
rpc Echo(EchoRequest) returns (EchoResponse);
rpc ServerStreamingEcho(ServerStreamingEchoRequest)
returns (stream ServerStreamingEchoResponse);
}
var echoService = new proto.grpc.gateway.testing.EchoServiceClient(
'http://localhost:8080');
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ストリーミングを示していますが、 このコメント は、この例が実際にはまだ機能しないことを明確にします。
うまくいけば、これはすぐに変更されます。 :)
https://github.com/grpc/ のgrpcの人々は現在、js 実装 を構築しています。
再現は https://github.com/grpc/grpc-web (404->)にあります。これは現在(2016-12-20)早期アクセスであるため、必要です アクセスの要求 。
https://github.com/tmc/grpc-websocket-proxy それはあなたのニーズを満たすかもしれません。これは、Webソケット上のjsonをgrpc(grpc-gatewayの上のレイヤー)に変換します。
OPがブラウザのサポートを求めたので、WebSocketを介した双方向ソリューションについて多くの回答が指摘されていなかったことがわかります。
WebSocketを介した双方向RPCを取得するために、gRPCの代わりにJSON-RPCを使用できます。これは、WebRTC(ブラウザーからブラウザー)を含む、より多くをサポートします。
このタイプのシリアライゼーションが本当に必要な場合は、gRPCをサポートするように変更できると思います。
ただし、ブラウザータブからブラウザータブの場合、リクエストオブジェクトはシリアル化されず、ネイティブに転送されます。これはNodeJSクラスターまたはスレッドワーカーでも同じであり、パフォーマンスが大幅に向上します。
また、gRPC形式でシリアル化する代わりに、「ポインタ」をSharedArrayBufferに転送できます。
V8でのJSONシリアル化と逆シリアル化も無敵です。
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 を参照してください。
GRPC over webを使用した現在のソリューションを見ると、これを書いている時点で利用可能なもの(および私が見つけたもの)は次のとおりです。
また、会社用に書いた独自のソリューションを恥知らずにプラグインしたいと思います。これは、実稼働環境で、単項およびサーバーストリーミングコールのみを含むgRPCサービスへのリクエストをプロキシするために使用されています。
コードのあらゆるインチがテストで覆われています。 Expressミドルウェアであるため、gRPCセットアップに追加の変更を加える必要はありません。 HTTP認証をExpressに委任することもできます(たとえば、Passportを使用)。