javascript - google - Cómo llevar una API definida por gRPC al navegador web
google maps api javascript (8)
Queremos construir una gui Javascript / HTML para nuestros microservicios gRPC. Como gRPC no es compatible en el lado del navegador, pensamos en usar sockets web para conectarse a un servidor node.js, que llama al servicio de destino a través de grpc. Luchamos por encontrar una solución elegante para hacer esto. Especialmente, ya que usamos flujos de gRPC para impulsar eventos entre nuestros microservicios. Parece que necesitamos un segundo sistema RPC, solo para comunicarnos entre el servidor front-end y el servidor node.js. Esto parece ser una gran cantidad de sobrecarga y código adicional que debe mantenerse.
¿Alguien tiene experiencia haciendo algo como esto o tiene una idea de cómo se podría resolver esto?
Desafortunadamente, todavía no hay una buena respuesta para ti.
La compatibilidad con la transmisión de RPC desde el navegador requiere que los exploradores HTTP2 sean compatibles con los navegadores, y en el momento de escribir esta respuesta, no lo son.
Vea este tema para la discusión sobre el tema.
De lo contrario, sí, necesitaría un sistema de traducción completo entre WebSockets y gRPC. Quizás obtener inspiración de grpc-gateway podría ser el comienzo de un proyecto de este tipo, pero aún así es una grpc-gateway .
El 3/23/2018 se lanzó una implementación oficial de grpc-web (beta). Puedes encontrarlo en
Las siguientes instrucciones se han tomado del archivo README:
Defina su servicio gRPC:
service EchoService {
rpc Echo(EchoRequest) returns (EchoResponse);
rpc ServerStreamingEcho(ServerStreamingEchoRequest)
returns (stream ServerStreamingEchoResponse);
}
Cree el servidor en el idioma que desee.
Cree su cliente JS para hacer llamadas desde el navegador:
var echoService = new proto.grpc.gateway.testing.EchoServiceClient(
''http://localhost:8080'');
Hacer una llamada unaria RPC
var unaryRequest = new proto.grpc.gateway.testing.EchoRequest();
unaryRequest.setMessage(msg);
echoService.echo(unaryRequest, {},
function(err, response) {
console.log(response.getMessage());
});
Se admiten transmisiones desde el servidor al navegador:
var stream = echoService.serverStreamingEcho(streamRequest, {});
stream.on(''data'', function(response) {
console.log(response.getMessage());
});
NO se admiten transmisiones bidireccionales:
Este es un trabajo en progreso y en la hoja de ruta de grpc-web . Si bien hay un ejemplo de protobuf que muestra la transmisión bidi, este comentario deja en claro que este ejemplo aún no funciona.
Esperemos que esto cambie pronto. :)
El Proxy WebSocket de GRPC Bus hace exactamente esto al enviar todas las llamadas GRPC a través de una conexión WebSocket para proporcionarle algo que se parece mucho a la API Node GRPC en el navegador. A diferencia de GRPC-Gateway, funciona tanto con solicitudes de transmisión como con respuestas de transmisión, así como con llamadas sin transmisión.
Hay un servidor y un componente de cliente.
El
servidor GRPC Bus WebSocket Proxy
se puede ejecutar con Docker haciendo que Docker
docker run gabrielgrant/grpc-bus-websocket-proxy
En el lado del navegador, necesitará instalar el
cliente GRPC Bus WebSocket Proxy
con
npm install grpc-bus-websocket-client
y luego cree un nuevo objeto GBC con:
new GBC(<grpc-bus-websocket-proxy address>, <protofile-url>, <service map>)
Por ejemplo:
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
});
La biblioteca del cliente espera poder descargar el archivo
.proto
con una solicitud AJAX.
El
service-map
proporciona las URL de los diferentes servicios definidos en su archivo proto tal como lo ve el servidor proxy.
Para obtener más detalles, consulte el archivo README del cliente proxy GRPC Bus WebSocket
La gente de grpc en https://github.com/grpc/ está construyendo una implementation js.
La reproducción se encuentra en github.com/grpc/grpc-web (da 404 ->) que está actualmente (2016-12-20) en acceso temprano, por lo que debe solicitar acceso .
Mirando las soluciones actuales con gRPC en la web, aquí está lo que está disponible al momento de escribir esto (y lo que encontré):
- https://github.com/improbable-eng/grpc-web : requiere TypeScript para el cliente
- gRPC-web-proxy : requiere Ir
- gRPC-gateway : requiere modificaciones y decoraciones .proto
-
gRPC-bus-websocket-proxy-server
:
al escribir este documento le faltan pruebas y parece abandonado(editar: ¡mire los comentarios del autor original!) - gRPC-dynamic-gateway : un poco exagerado para los servicios simples de gRPC y la autenticación es incómoda
- gRPC-bus : requiere algo para el transporte
También quiero conectar descaradamente mi propia solución que escribí para mi empresa y que se está utilizando en producción para enviar solicitudes de proxy a un servicio gRPC que solo incluye llamadas de transmisión unitarias y de servidor:
Cada centímetro del código está cubierto por pruebas. Es un middleware Express, por lo que no necesita modificaciones adicionales en su configuración de gRPC. También puede delegar la autenticación HTTP a Express (por ejemplo, con Passport).
Veo que muchas respuestas no apuntaban a una solución bidireccional a través de WebSocket, ya que el OP solicitó soporte para el navegador.
Puede usar JSON-RPC en lugar de gRPC, para obtener un RPC bidireccional sobre WebSocket , que admite mucho más, incluido WebRTC (navegador a navegador).
Supongo que podría modificarse para admitir gRPC si realmente necesita este tipo de serialización.
Sin embargo, para la pestaña del navegador a la pestaña del navegador, los objetos de solicitud no se serializan y se transfieren de forma nativa, y lo mismo ocurre con el clúster NodeJS o los trabajadores de subprocesos, que ofrece mucho más rendimiento.
Además, puede transferir "punteros" a SharedArrayBuffer, en lugar de serializar a través del formato gRPC.
La serialización y deserialización de JSON en V8 también es inmejorable.
https://github.com/tmc/grpc-websocket-proxy parece que puede satisfacer sus necesidades. Esto traduce json sobre sockets web a grpc (capa en la parte superior de grpc-gateway).
Editar: desde el 23 de octubre de 2018, el proyecto gRPC-Web es GA , que podría ser la forma más oficial / estandarizada de resolver su problema. (Incluso si ya es 2018 ahora ...;))
Desde el blog de GA: "gRPC-Web, al igual que gRPC, le permite definir el" contrato "de servicio entre el cliente (web) y los servicios de back-end gRPC utilizando Protocol Buffers. El cliente puede generarse automáticamente. [...]"
Recientemente creamos gRPC-Web ( https://github.com/improbable-eng/grpc-web ), un cliente de navegador y un contenedor de servidor que sigue el protocolo propuesto de gRPC-Web. El ejemplo en ese repositorio debería proporcionar un buen punto de partida.
Requiere un proxy independiente o un contenedor para su servidor gRPC si está usando Golang. El proxy / contenedor modifica la respuesta para empaquetar los trailers en el cuerpo de la respuesta para que el navegador pueda leerlos.
Divulgación: soy el mantenedor del proyecto.