如何在Dart中实现服务端gRPC拦截器
Dart服务端gRPC拦截器开发实现方案
1. 自定义拦截器类实现Interceptor接口
Dart gRPC 服务端拦截器的核心是实现grpc包提供的Interceptor抽象类,重写其call方法即可完成自定义拦截逻辑:
import 'package:grpc/grpc.dart'; class CustomServerInterceptor implements Interceptor { @override FutureOr<Response> call( ServiceCall call, ServiceMethod method, FutureOr<Response> Function(ServiceCall call, ServiceMethod method) handler, ) async { // 【请求前置拦截逻辑】请求到达业务方法前执行,可做身份校验、参数校验、日志打印等操作 final authHeader = call.clientMetadata?['authorization']?.firstOrNull; if (authHeader == null || !_verifyToken(authHeader)) { // 校验不通过直接抛出GrpcError,终止请求流转,错误会直接返回给客户端 throw GrpcError.unauthenticated('缺少有效访问凭证'); } // 放行请求,调用后续拦截器或业务方法 final response = await handler(call, method); // 【响应后置拦截逻辑】业务方法执行完成后执行,可做统一响应头追加、耗时统计、异常统一封装等操作 call.headers['x-service-version'] = '2.1.3'; return response; } // 自定义token校验逻辑,替换为自身业务实现即可 bool _verifyToken(String authStr) { return authStr.startsWith('Bearer ') && authStr.split(' ').last.length == 32; } }
2. 服务启动时注册拦截器
创建gRPC服务实例时,将自定义拦截器传入interceptors参数完成注册即可生效:
Future<void> startGrpcServer() async { final server = Server( // 填入你自身实现的所有gRPC服务实例列表 [UserServiceImpl(), OrderServiceImpl()], // 注册拦截器,支持传入多个,按数组顺序执行 interceptors: [CustomServerInterceptor(), LogInterceptor()], // 可选配置:设置支持的压缩编码等 codecRegistry: CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]), ); // 启动服务,监听指定端口 await server.serve(address: '0.0.0.0', port: 50052); print('gRPC服务已启动,监听端口:${server.port}'); }
3. 注意事项
- 多个拦截器的执行逻辑为:按注册顺序执行所有拦截器的前置逻辑,业务方法执行完成后,按注册逆序执行所有拦截器的后置逻辑
- 若需要在拦截器和业务方法之间传递自定义参数,可以往
call.clientMetadata中追加自定义字段,业务方法中通过传入的ServiceCall对象读取对应值即可 - 流式请求(客户端流、服务端流、双向流)的拦截逻辑和普通一元请求完全一致,无需额外适配,gRPC包会自动处理流的全生命周期
- 拦截器中仅抛出
GrpcError类型的异常会被gRPC框架正确处理,其他类型异常会被包装为GrpcError.internal返回给客户端
内容的提问来源于stack exchange,提问作者Daniel Armas
相关产品推荐
相关产品推荐

