如何在单端口同时提供gRPC与gRPC-web服务?
问题:gRPC服务端如何处理gRPC-web连接?
我开发了一个多平台应用,采用gRPC实现前后端通信,架构如下:
backend transport various clients [ gRPC(Server) ] -- gRPC -- [ flutter app + bloc + gRPC ] [ gRPC + Postgres backend ] [ gRPC-web(HttpServer?) ] -- gRPCw -- [ flutter web + bloc + gRPC-web ]
所有连接均通过同一端口建立,目前应用运行正常,可调用已定义服务并与数据库交互,后端也能单独捕获HTTP连接数据,传输环节无问题。
我的问题是:如何在服务端处理gRPC-web连接?我已编写以下代码,能捕获到HTTP连接,但不知道如何将请求传入现有gRPC服务中:
final webServer = await HttpServer.bind( '0.0.0.0', rpcPort, shared: true, ); print('gRPC-web port ${webServer.port}'); await for (HttpRequest request in webServer) { print(request); }
补充:我的gRPC服务端代码如下,希望能找到类似的gRPC-web实现方式:
final server = Server.create( services: [ SiteMethodsService(databaseCore), CategoryMethodsService(databaseCore) ], interceptors: [], codecRegistry: CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]), );
解决方案
你可以复用已创建的gRPC Server实例,通过其serveHttp()方法获取gRPC-web请求处理器,直接将HttpServer捕获的请求交给该处理器处理,无需重新注册服务。修改后的代码如下:
// 保留原有的gRPC服务端初始化代码 final server = Server.create( services: [ SiteMethodsService(databaseCore), CategoryMethodsService(databaseCore) ], interceptors: [], codecRegistry: CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]), ); // 获取gRPC-web请求处理器,该处理器会将HTTP请求转换为gRPC调用 final grpcWebRequestHandler = server.serveHttp(); // 绑定HttpServer并将所有请求转发给处理器 final webServer = await HttpServer.bind('0.0.0.0', rpcPort, shared: true); print('gRPC-web 端口 ${webServer.port}'); // 处理所有HTTP请求,自动适配gRPC-web协议 await webServer.forEach(grpcWebRequestHandler);
说明
server.serveHttp()返回一个void Function(HttpRequest)类型的函数,专门用于处理符合gRPC-web规范的HTTP请求- 该处理器会自动解析HTTP请求中的gRPC-web数据,调用你已注册的
SiteMethodsService和CategoryMethodsService中的方法 - 无需修改现有服务的实现逻辑,完全复用原有gRPC服务代码
内容的提问来源于stack exchange,提问作者geoai777
相关产品推荐
相关产品推荐

