我们想为我们的gRPC-microservices构建一个Javascript / HTML gui。由于浏览器端不支持gRPC,因此我们考虑使用Web套接字连接到node.js服务器,该服务器通过grpc调用目标服务。我们很难找到一个完美的解决方案来做到这一点。特别是,由于我们使用gRPC流在微服务之间推送事件。似乎我们需要第二个RPC系统,仅用于在前端和node.js服务器之间进行通信。这似乎有很多开销,必须维护其他代码。
有没有人有做过这样的事情的经验或有解决办法的想法?
我们想为我们的gRPC-microservices构建一个Javascript / HTML gui。由于浏览器端不支持gRPC,因此我们考虑使用Web套接字连接到node.js服务器,该服务器通过grpc调用目标服务。我们很难找到一个完美的解决方案来做到这一点。特别是,由于我们使用gRPC流在微服务之间推送事件。似乎我们需要第二个RPC系统,仅用于在前端和node.js服务器之间进行通信。这似乎有很多开销,必须维护其他代码。
有没有人有做过这样的事情的经验或有解决办法的想法?
Answers:
编辑:自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服务器的独立代理或包装器。代理/包装器修改响应以将预告片打包在响应主体中,以便浏览器可以读取它们。
披露:我是该项目的维护者。
不幸的是,您还没有任何好的答案。
要从浏览器支持流式RPC,完全需要浏览器支持HTTP2预告片,而在撰写此答案时,还不支持。
否则,是的,您将需要WebSockets和gRPC之间的完整翻译系统。也许从grpc-gateway获得灵感可能是这个项目的开始,但这仍然是一个漫长的过程。
正式的grpc-web(beta)实现于2018年3月23日发布。你可以在找到它
以下说明摘自自述文件:
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路线图上。虽然有一个示例协议显示bidi流,但此注释清楚表明该示例尚未真正起作用。
希望这会很快改变。:)
https://github.com/grpc/上的grpc人目前正在构建js实现。
该repro位于https://github.com/grpc/grpc-web(gives 404->),当前(2016年12月20日)处于早期访问状态,因此您需要请求访问权限。
https://github.com/tmc/grpc-websocket-proxy听起来可能满足您的需求。这会将JSON通过Web套接字转换为grpc(在grpc-gateway顶部的层)。
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代理客户端自述文件。
我看到很多答案都没有指出WebSocket上的双向解决方案,因为OP要求浏览器支持。
您可以使用JSON-RPC而不是gRPC来通过WebSocket获得双向RPC,它支持更多功能,包括WebRTC(浏览器到浏览器)。
我想如果您确实需要这种类型的序列化,可以对其进行修改以支持gRPC。
但是,对于浏览器选项卡到浏览器选项卡,请求对象不会被序列化,而是本地传输,与NodeJS集群或线程工作程序相同,这提供了更高的性能。
另外,您可以将“指针”传输到SharedArrayBuffer,而不是通过gRPC格式进行序列化。
V8中的JSON序列化和反序列化也是无与伦比的。
查看使用gRPC over web的当前解决方案,以下是编写本文时(以及我发现的)可用的内容:
我还想无耻地插入我为公司编写的自己的解决方案,并将其用于生产中以将请求代理到gRPC服务,该服务仅包含一元和服务器流调用:
测试覆盖每一英寸的代码。它是Express中间件,因此不需要对gRPC设置进行任何其他修改。您也可以将HTTP身份验证委派给Express(例如,使用Passport)。