it-swarm.com.de

Wie bringt man eine gRPC-definierte API in den Webbrowser?

Wir möchten eine Javascript/HTML-GUI für unsere gRPC-Microservices erstellen. Da gRPC auf der Browserseite nicht unterstützt wird, haben wir uns überlegt, Web-Sockets zu verwenden, um eine Verbindung zu einem node.js-Server herzustellen, der den Zieldienst über grpc aufruft. Wir bemühen uns, eine elegante Lösung dafür zu finden. Insbesondere, da wir gRPC-Streams verwenden, um Ereignisse zwischen unseren Mikrodiensten zu übertragen. Es scheint, dass wir ein zweites RPC-System benötigen, nur um zwischen dem Frontend und dem node.js-Server zu kommunizieren. Dies scheint viel Aufwand und zusätzlichen Code zu sein, der gepflegt werden muss.

Hat jemand Erfahrung mit so etwas oder hat eine Idee, wie man das lösen könnte?

56
Oliver

Edit: Seit dem 23. Oktober 2008 ist das gRPC-Web-Projekt GA . Dies könnte der offiziellste/standardisierteste Weg sein, um Ihr Problem zu lösen. (Auch wenn es jetzt schon 2018 ist ...;))

Aus dem GA-Blog: "Mit gRPC-Web können Sie, genau wie gRPC, den Dienst" Vertrag "zwischen Client- (Web-) und Back-End-gRPC-Diensten mit Protokollpuffern definieren. Der Client kann dann automatisch generiert werden. ...] "

Wir haben kürzlich gRPC-Web ( https://github.com/improbable-eng/grpc-web ) erstellt - einen Browser-Client und -Server-Wrapper, der dem vorgeschlagenen gRPC-Web-Protokoll folgt. Das Beispiel in diesem Repo sollte einen guten Ausgangspunkt bieten.

Wenn Sie Golang verwenden, ist entweder ein eigenständiger Proxy oder ein Wrapper für Ihren gRPC-Server erforderlich. Der Proxy/Wrapper ändert die Antwort, um die Trailer im Antworttext zu verpacken, damit sie vom Browser gelesen werden können.

Offenlegung: Ich bin ein Projektbetreuer.

24
Marcus

Leider gibt es noch keine gute Antwort für Sie.

Die vollständige Unterstützung des Streaming von RPCs aus dem Browser erfordert, dass HTTP2-Trailer von den Browsern unterstützt werden. Zum Zeitpunkt des Schreibens dieser Antwort ist dies nicht der Fall.

Siehe diese Ausgabe für die Diskussion zum Thema.

Ansonsten, ja, Sie benötigen ein vollständiges Übersetzungssystem zwischen WebSockets und gRPC. Vielleicht wird die Inspiration von grpc-gateway der Beginn eines solchen Projekts sein, aber das ist immer noch eine sehr lange Sicht.

15
Nicolas Noble

Eine offizielle Implementierung von Grpc-Web (Beta) wurde am 23.03.2014 veröffentlicht. Sie finden es bei

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

Die folgenden Anweisungen stammen aus der Readme-Datei:

Definieren Sie Ihren gRPC-Dienst:

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

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

Erstellen Sie den Server in der gewünschten Sprache.

Erstellen Sie Ihren JS-Client, um Anrufe vom Browser aus zu tätigen:

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

Machen Sie einen unären RPC-Aufruf

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

Streams vom Server zum Browser werden unterstützt:

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

Bidirektionale Streams werden NICHT unterstützt:

Dies ist eine Arbeit in Arbeit und auf der grpc-web roadmap . Während es ein example protobuf gibt, das Bidi-Streaming zeigt, macht dieser Kommentar klar, dass dieses Beispiel noch nicht funktioniert.

Hoffentlich wird sich das bald ändern. :)

9
Cody A. Ray

Die grpc-Leute bei https://github.com/grpc/ bauen derzeit ein js Implementierung .

Die Reproduktion ist bei https://github.com/grpc/grpc-web (ergibt 404 ->), die sich derzeit (2016-12-20) im frühen Zugriff befindet, so dass Sie anfordern) müssen Zugriff .

7
RickyA

https://github.com/tmc/grpc-websocket-proxy klingt so, als könnte es Ihren Bedürfnissen entsprechen. Dies übersetzt Json über Web-Sockets in Grpc (Layer auf dem Grpc-Gateway).

6
tmc

GRPC-Bus WebSocket-Proxy tut genau dies, indem er alle GRPC-Aufrufe über eine WebSocket-Verbindung weiterleitet, um Ihnen etwas zu vermitteln, das der Node-GRPC-API im Browser sehr ähnlich sieht. Im Gegensatz zu GRPC-Gateway werden sowohl Streaming-Anforderungen und Streaming-Antworten als auch nicht-Streaming-Anrufe verwendet. 

Es gibt eine Server- und eine Client-Komponente ..__ Der GRPC Bus WebSocket-Proxyserver kann mit Docker ausgeführt werden, indem docker run gabrielgrant/grpc-bus-websocket-proxy ausgeführt wird.

Auf der Browserseite müssen Sie den GRPC Bus WebSocket Proxy-Client mit npm install grpc-bus-websocket-client installieren.

und erstellen Sie ein neues GBC-Objekt mit: new GBC(<grpc-bus-websocket-proxy address>, <protofile-url>, <service map>)

Zum Beispiel:

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
  });

Die Clientbibliothek erwartet, dass sie die .proto-Datei mit der Anforderung AJAX herunterladen kann. service-map enthält die URLs der verschiedenen Dienste, die in Ihrer Proto-Datei definiert sind, wie vom Proxy-Server angezeigt.

Weitere Informationen finden Sie im GRPC Bus WebSocket Proxy-Client README

1
Gabriel Grant

Ich sehe, dass viele Antworten nicht auf eine bidirektionale Lösung über WebSocket hinwiesen, da das OP die Browserunterstützung anforderte.

Sie können JSON-RPC anstelle von gRPC verwenden, um einen bidirektionalen RPC über WebSocket zu erhalten, der sehr viel mehr unterstützt, einschließlich WebRTC (Browser-Browser).

Ich denke, es könnte geändert werden, um gRPC zu unterstützen, wenn Sie diese Art der Serialisierung wirklich benötigen.

Anforderungsobjekte werden jedoch von Browser-Registerkarte zu Browser-Registerkarte nicht serialisiert und nativ übertragen. Dies gilt auch für NodeJS-Cluster oder -Thread-Worker, was erheblich mehr Leistung bietet.

Sie können auch "Zeiger" an SharedArrayBuffer übertragen, anstatt das gRPC-Format zu serialisieren.

Die JSON-Serialisierung und Deserialisierung in V8 ist ebenfalls unschlagbar.

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

0

Wenn Sie sich die aktuellen Lösungen mit gRPC über das Web anschauen, finden Sie Folgendes zum Zeitpunkt des Schreibens (und was ich gefunden habe):

  • gRPC-web : erfordert TypeScript für den Client
  • gRPC-Web-Proxy : erfordert Go
  • gRPC-gateway : erfordert .proto-Änderungen und Dekorationen
  • gRPC-Bus-Websocket-Proxy-Serverzum Zeitpunkt der Abfassung dieses Dokuments mangelt es an Tests und scheint aufgegeben zu sein (edit: schau dir die Kommentare des ursprünglichen Autors an!)
  • gRPC-Dynamic-Gateway : Ein bisschen Overkill für einfache gRPC-Dienste und Authentifizierung ist umständlich
  • gRPC-Bus : erfordert etwas für den Transport

Ich möchte auch meine eigene Lösung schamlos anschließen, die ich für mein Unternehmen geschrieben habe. Sie wird in der Produktion verwendet, um Anfragen an einen gRPC-Dienst zu senden, der nur unäre und Server-Streaming-Aufrufe enthält:

Jeder Zoll des Codes wird durch Tests abgedeckt. Da es sich um eine Express-Middleware handelt, sind keine weiteren Änderungen an Ihrem gRPC-Setup erforderlich. Sie können die HTTP-Authentifizierung auch an Express delegieren (z. B. mit Passport).

0
Sepehr