如何将gRPC定义的API引入网络浏览器


76

我们想为我们的gRPC-microservices构建一个Javascript / HTML gui。由于浏览器端不支持gRPC,因此我们考虑使用Web套接字连接到node.js服务器,该服务器通过grpc调用目标服务。我们很难找到一个完美的解决方案来做到这一点。特别是,由于我们使用gRPC流在微服务之间推送事件。似乎我们需要第二个RPC系统,仅用于在前端和node.js服务器之间进行通信。这似乎有很多开销,必须维护其他代码。

有没有人有做过这样的事情的经验或有解决办法的想法?


查看Wildcard API,这是一个小工具,可让您轻松在前端和Node.js服务器之间创建RPC API。就像gRPC一样,但是更简单,更容易使用。披露:我是作者。
brillout

Answers:


38

编辑:自2018年10月23日起,gRPC-Web项目为GA,这可能是解决问题的最官方/标准化方式。(即使现在已经是2018年了...;)

在GA博客中:“与gRPC一样,gRPC-Web允许您使用协议缓冲区在客户端(网络)和后端gRPC服务之间定义服务“合同”。然后可以自动生成客户端。[...]

我们最近构建了gRPC-Web(https://github.com/improbable-eng/grpc-web)-一种遵循建议的gRPC-Web协议的浏览器客户端和服务器包装。该回购中的示例应提供一个很好的起点。

如果您使用的是Golang,则它需要gRPC服务器的独立代理或包装器。代理/包装器修改响应以将预告片打包在响应主体中,以便浏览器可以读取它们。

披露:我是该项目的维护者。


4
杀手级功能是现在可以为任何原型文件创建HTML操场页面,类似于对swagger所做的操作。这样,可以通过浏览器轻松测试任何gRPC服务。
Setheron

1
@Marcus,您说它遵循“建议的gRPC-Web协议”。官方github.com/grpc/grpc-web实现使用的协议(最近已公开)是否使用相同的协议,因此这些实现是否兼容?还是您指的是您自己建议的协议?
Matthijs Kooijman,

@Setheron您能给我链接到此concreate killer功能的示例或说明吗?我还找不到它:(我有gRPC-Web应用程序(node.js),带有二进制(base64)消息和Envoy Proxy,如官方文档一样,我想使用像招摇工具一样的工具来测试我的应用程序
razon

这个项目也可以与wordpress(php)连接吗?
Raju yourPepe '19

16

不幸的是,您还没有任何好的答案。

要从浏览器支持流式RPC,完全需要浏览器支持HTTP2预告片,而在撰写此答案时,还不支持。

有关主题的讨论,请参见此问题

否则,是的,您将需要WebSockets和gRPC之间的完整翻译系统。也许从grpc-gateway获得灵感可能是这个项目的开始,但这仍然是一个漫长的过程。


感谢您的回答!我已经阅读了有关HTTP预告片的问题。甚至有人做了一个补丁,以便可以在没有流功能的浏览器中使用grpc。grpc-gateway项目是一个有用的提示。我们现在可能正在使用dnode做网关...
Oliver

1
是的,如果您忘记了流式传输,那么完全有可能使用浏览器提供grpc。
Nicolas Noble

@NicolasNoble-太好了。有没有来自浏览器的非流gRPC调用示例?
AlikElzin-kilaka '16

还不是很不幸。我从理论上讲。但是变化应该很小。
Nicolas Noble

1
我们正在收集有志于早期试用计划的人的名字在这里。随时在其中添加您的名字,我们将很快分享。
Nicolas Noble

10

正式的grpc-web(beta)实现于2018年3月23日发布。你可以在找到它

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

以下说明摘自自述文件:

定义您的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路线图上。虽然有一个示例协议显示bidi流,但此注释清楚表明该示例尚未真正起作用。

希望这会很快改变。:)


1
您确定支持双向流吗?您的双向示例似乎仅显示服务器流,而您的服务器流示例仅显示一元请求而没有任何流。自述文件还仅提及服务器流,这使我怀疑不支持客户端或双向流。你能澄清一下吗?
Matthijs Kooijman,

2
@MatthijsKooijman他们的回声示例显示了客户端和全双工流:github.com/grpc/grpc-web/blob/master/net/grpc/gateway/examples/...
科迪A.雷

1
该示例似乎仅供将来参考,实际上不受支持。另请参见github.com/grpc/grpc-web/issues/24#issuecomment-303285538,其中明确说明了有关示例的内容。
Matthijs Kooijman

1
@MatthijsKooijman看起来您是对的。我已经更新了答案以反映这一点(并包括指向路线图和评论的链接)。谢谢!
Cody A. Ray

1
现在,您从答案中删除了流服务器示例(您以前将其错误地标记为双向流)。
Matthijs Kooijman



2

GRPC Bus WebSocket代理通过在WebSocket连接上代理所有GRPC调用来实现此目的,从而为您提供与浏览器中的Node GRPC API非常相似的功能。与GRPC-Gateway不同,它既可以处理流请求,可以处理流响应,也可以处理非流调用。

同时有服务器和客户端组件。该GRPC总线的WebSocket代理服务器可以与码头工人做运行docker run gabrielgrant/grpc-bus-websocket-proxy

在浏览器端,你需要安装GRPC总线的WebSocket代理客户端npm install grpc-bus-websocket-client

然后使用以下命令创建一个新的GBC对象: new GBC(<grpc-bus-websocket-proxy address>, <protofile-url>, <service map>)

例如:

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

客户端库希望能够.proto通过AJAX请求下载文件。该service-map代理服务器所看到提供在原文件中定义的不同服务的URL。

有关更多详细信息,请参见GRPC Bus WebSocket代理客户端自述文件。


2

我看到很多答案都没有指出WebSocket上的双向解决方案,因为OP要求浏览器支持。

您可以使用JSON-RPC而不是gRPC来通过WebSocket获得双向RPC,它支持更多功能,包括WebRTC(浏览器到浏览器)。

我想如果您确实需要这种类型的序列化,可以对其进行修改以支持gRPC。

但是,对于浏览器选项卡到浏览器选项卡,请求对象不会被序列化,而是本地传输,与NodeJS集群或线程工作程序相同,这提供了更高的性能。

另外,您可以将“指针”传输到SharedArrayBuffer,而不是通过gRPC格式进行序列化。

V8中的JSON序列化和反序列化也是无与伦比的。

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


0

查看使用gRPC over web的当前解决方案,以下是编写本文时(以及我发现的)可用的内容:

我还想无耻地插入我为公司编写的自己的解决方案,并将其用于生产中以将请求代理到gRPC服务,该服务仅包含一元和服务器流调用:

测试覆盖每一英寸的代码。它是Express中间件,因此不需要对gRPC设置进行任何其他修改。您也可以将HTTP身份验证委派给Express(例如,使用Passport)。


嘿! grpc-express看起来很酷,尤其是。适用于不需要客户端流的使用Express的用户。我很好奇,您还要对gRPC-bus-websocket-proxy-server进行哪些其他测试?它是grpc-bus的相当薄的包装层/传输层(已经过很好的单元测试),所以我认为复制这些层并没有任何意义,“演示”实际上是验收测试。无论如何,我们都在Pachyderm中积极使用它,只是不需要最近更新,因为它主要是Just Works :)
Gabriel Grant
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.