So bringen Sie eine gRPC-definierte API in den Webbrowser

76

Wir wollen 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. Zumal wir gRPC-Streams verwenden, um Ereignisse zwischen unseren Mikrodiensten zu übertragen. Es scheint, dass wir ein zweites RPC-System benötigen, um zwischen dem Front-End und dem node.js-Server zu kommunizieren. Dies scheint viel Aufwand und zusätzlichen Code zu sein, der gepflegt werden muss.

Hat jemand Erfahrung damit oder hat eine Idee, wie dies gelöst werden könnte?

Oliver
quelle
Schauen Sie sich die Wildcard-API an , ein kleines Tool, mit dem Sie auf einfache Weise eine RPC-API zwischen Ihrem Frontend und Ihrem Node.js-Server erstellen können. Es ist wie gRPC, aber viel einfacher und benutzerfreundlicher. Offenlegung: Ich bin der Autor.
Brillout

Antworten:

38

Bearbeiten: Seit dem 23. Oktober 2008 ist das gRPC-Web-Projekt GA , was möglicherweise die offiziellste / standardisierteste Methode zur Lösung Ihres Problems ist. (Auch wenn es jetzt schon 2018 ist ...;))

Aus dem GA-Blog: "Mit gRPC-Web können Sie genau wie mit gRPC den Dienstvertrag zwischen Client- (Web-) und Back-End-gRPC-Diensten mithilfe von 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.

Für die Verwendung von Golang ist entweder ein eigenständiger Proxy oder ein Wrapper für Ihren gRPC-Server erforderlich. Der Proxy / Wrapper ändert die Antwort, um die Trailer in den Antworttext zu packen, damit sie vom Browser gelesen werden können.

Offenlegung: Ich bin ein Betreuer des Projekts.

Marcus
quelle
4
Killer-Feature wäre jetzt die Möglichkeit, eine HTML-Spielplatzseite für jede Protodatei zu erstellen, die der für Swagger ähnelt. Auf diese Weise kann jeder gRPC-Dienst einfach über den Browser getestet werden.
Setheron
1
@Marcus, Sie sagen, es folgt dem "Vorgeschlagenen gRPC-Web-Protokoll". Ist das das gleiche Protokoll, das von der offiziellen Implementierung von github.com/grpc/grpc-web (die kürzlich veröffentlicht wurde) verwendet wird, und wären diese Implementierungen daher kompatibel? Oder beziehen Sie sich auf Ihr eigenes vorgeschlagenes Protokoll?
Matthijs Kooijman
@Setheron, kannst du mir einen Link zu einem Beispiel oder einer Beschreibung dieser Concreate Killer-Funktion geben? Ich kann es noch nicht finden :( Ich habe eine gRPC-Webanwendung (node.js) mit binären (base64) Nachrichten und Envoy Proxy wie in offiziellen Dokumenten, und ich möchte ein prahlerisches Tool zum Testen meiner App haben
razon
Kann dieses Projekt auch mit WordPress (PHP) verbunden werden?
Raju yourPepe
16

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

Um Streaming-RPCs vom Browser vollständig zu unterstützen, müssen HTTP2-Trailer von den Browsern unterstützt werden, und zum Zeitpunkt des Schreibens dieser Antwort sind dies nicht der Fall.

In dieser Ausgabe finden Sie die Diskussion zum Thema.

Andernfalls benötigen Sie ein vollständiges Übersetzungssystem zwischen WebSockets und gRPC. Vielleicht könnte die Inspiration von grpc-gateway der Beginn eines solchen Projekts sein, aber das ist noch ein sehr langer Weg.

Nicolas Noble
quelle
Danke für deine Antwort! Ich habe bereits über das Problem mit den http-Trailern gelesen. Es gibt sogar einen Patch, den jemand gemacht hat, damit es möglich ist, grpc im Browser ohne die Streaming-Funktion zu verwenden. Das grpc-gateway-Projekt ist ein nützlicher Hinweis. Wir machen jetzt wahrscheinlich ein Gateway mit dnode ...
Oliver
1
Ja, wenn Sie das Streaming vergessen haben, ist grpc vom Browser aus völlig möglich.
Nicolas Noble
@NicolasNoble - das ist großartig. Gibt es ein Beispiel für einen nicht-Streaming-gRPC-Aufruf von einem Browser?
AlikElzin-Kilaka
Leider noch nicht. Ich habe theoretisch gesprochen. Die Änderungen sollten jedoch minimal sein.
Nicolas Noble
1
Wir sammeln hier Namen von Personen, die an einem Early-Access-Programm interessiert sind . Fühlen Sie sich frei, Ihren Namen dort hinzuzufügen und wir werden teilen, was wir bald haben.
Nicolas Noble
10

Eine offizielle Implementierung von grpc-web (Beta) wurde am 23.03.2008 veröffentlicht. Sie finden es unter

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

Die folgenden Anweisungen stammen aus der README-Datei:

Definieren Sie Ihren gRPC-Service:

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

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

Erstellen Sie den Server in einer beliebigen Sprache.

Erstellen Sie Ihren JS-Client, um Anrufe über den Browser zu tätigen:

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

Machen Sie einen unären RPC-Anruf

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 laufende Arbeit und an der grpc-web-Roadmap . Während es ein Beispielprotobuf gibt, das Bidi-Streaming zeigt, macht dieser Kommentar deutlich, dass dieses Beispiel noch nicht funktioniert.

Hoffentlich ändert sich das bald. :) :)

Cody A. Ray
quelle
1
Sind Sie sicher, dass bidirektionale Streams unterstützt werden? Ihr bidirektionales Beispiel scheint nur Server-Streaming anzuzeigen, während Ihr Server-Streaming-Beispiel nur eine unäre Anforderung ohne Streaming anzeigt. Die README-Datei erwähnt auch nur Server-Streaming, was mich vermuten lässt, dass Client- oder bidirektionales Streaming nicht unterstützt wird. Könnten Sie das klarstellen?
Matthijs Kooijman
2
@MatthijsKooijman Ihr Echo-Beispiel zeigt sowohl Client- als auch Vollduplex-Streaming: github.com/grpc/grpc-web/blob/master/net/grpc/gateway/examples/…
Cody A. Ray
1
Es scheint, dass dieses Beispiel nur als zukünftige Referenz dient und nicht wirklich unterstützt wird. Siehe auch github.com/grpc/grpc-web/issues/24#issuecomment-303285538, in dem dies explizit für das Beispiel angegeben ist.
Matthijs Kooijman
1
@MatthijsKooijman sieht aus wie Sie Recht haben. Ich habe meine Antwort aktualisiert, um dies widerzuspiegeln (und einen Link zur Roadmap und zum Kommentar eingefügt). Vielen Dank!
Cody A. Ray
1
Jetzt haben Sie das Streaming-Server-Beispiel aus Ihrer Antwort entfernt (die Sie zuvor als bidirektionales Streaming falsch bezeichnet hatten).
Matthijs Kooijman
2

GRPC Bus WebSocket Proxy führt genau dies durch, indem alle GRPC-Aufrufe über eine WebSocket-Verbindung übertragen werden, um etwas zu erhalten, das der Node GRPC-API im Browser sehr ähnlich sieht. Im Gegensatz zu GRPC-Gateway funktioniert es sowohl mit Streaming-Anforderungen und Streaming-Antworten als auch mit Nicht-Streaming-Anrufen.

Es gibt sowohl eine Server- als auch eine Client-Komponente. Der GRPC Bus WebSocket Proxy-Server kann mit Docker ausgeführt werdendocker run gabrielgrant/grpc-bus-websocket-proxy

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

und erstellen Sie dann 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 die .protoDatei mit einer AJAX-Anforderung heruntergeladen werden kann. Hier finden Sie service-mapdie URLs der verschiedenen Dienste, die in Ihrer Protodatei definiert sind und vom Proxyserver angezeigt werden.

Weitere Informationen finden Sie in der README-Datei des GRPC Bus WebSocket Proxy-Clients

Gabriel Grant
quelle
2

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

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

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

Für Browser-Tab zu Browser-Tab werden Anforderungsobjekte jedoch nicht serialisiert und nativ übertragen. Dies gilt auch für NodeJS-Cluster- oder Thread-Worker, die wesentlich mehr Leistung bieten.

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

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

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

Tiberiu-Ionuț Stan
quelle
0

Wenn Sie sich die aktuellen Lösungen mit gRPC über das Internet ansehen, sehen Sie hier, was zum Zeitpunkt des Schreibens verfügbar war (und was ich gefunden habe):

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

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

Sepehr
quelle
Hallo! grpc-express sieht cool aus, insb. für diejenigen, die Express verwenden und kein Client-Streaming benötigen. Ich bin gespannt, welche zusätzlichen Tests Sie für den gRPC-Bus-Websocket-Proxy-Server wünschen. Es ist eine ziemlich dünne Wrapper / Transport-Schicht für grpc-bus (die ziemlich gut auf Einheiten getestet ist), daher halte ich es nicht für sinnvoll, diese zu duplizieren, und die "Demo" ist effektiv der Abnahmetest. Auf jeden Fall verwenden wir es aktiv in Pachyderm , es musste nur in letzter Zeit nicht viel aktualisiert werden, da es meistens nur funktioniert :)
Gabriel Grant