ASP.NET Core 3.0 gRPC攔截器的使用
一. 前言
前面兩篇文章給大家介紹了使用gRPC的入門(mén)以及雙向流的使用,今天介紹的是gRPC中的攔截器。攔截器就像MVC的過(guò)濾器或者是ASP.NET Core middleware 一樣,具有面向切面的思想,可以在調(diào)用服務(wù)的時(shí)候進(jìn)行一些統(tǒng)一處理, 很適合在這里處理驗(yàn)證、日志等流程。本片文章就以記錄日志為例來(lái)進(jìn)行講解。
二. Interceptor 類(lèi)介紹
Interceptor類(lèi)是gRPC服務(wù)攔截器的基類(lèi),是一個(gè)抽象類(lèi),它定了幾個(gè)虛方法,分別如下:
public virtual TResponse BlockingUnaryCall<TRequest, TResponse>(); public virtual AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(); public virtual AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(); public virtual AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(); public virtual AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(); public virtual Task<TResponse> UnaryServerHandler<TRequest, TResponse>(); public virtual Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>(); public virtual Task ServerStreamingServerHandler<TRequest, TResponse>(); public virtual Task DuplexStreamingServerHandler<TRequest, TResponse>();
各個(gè)方法作用如下:
| 方法名稱(chēng) | 作用 |
|---|---|
| BlockingUnaryCall | 攔截阻塞調(diào)用 |
| AsyncUnaryCall | 攔截異步調(diào)用 |
| AsyncServerStreamingCall | 攔截異步服務(wù)端流調(diào)用 |
| AsyncClientStreamingCall | 攔截異步客戶端流調(diào)用 |
| AsyncDuplexStreamingCall | 攔截異步雙向流調(diào)用 |
| UnaryServerHandler | 用于攔截和傳入普通調(diào)用服務(wù)器端處理程序 |
| ClientStreamingServerHandler | 用于攔截客戶端流調(diào)用的服務(wù)器端處理程序 |
| ServerStreamingServerHandler | 用于攔截服務(wù)端流調(diào)用的服務(wù)器端處理程序 |
| DuplexStreamingServerHandler | 用于攔截雙向流調(diào)用的服務(wù)器端處理程序 |
在實(shí)際使用中,可以根據(jù)自己的需要來(lái)使用對(duì)應(yīng)的攔截方法。
三. 客戶端攔截器
基于前面兩篇文章使用的Demo。
在客戶端項(xiàng)目新建一個(gè)類(lèi),命名為 ClientLoggerInterceptor,繼承攔截器基類(lèi) Interceptor。
我們?cè)谇懊媸褂玫腄emo,定義了擼貓服務(wù),其中 SuckingCatAsync方法為異步調(diào)用,所以我們重寫(xiě)攔截器的 AsyncUnaryCall方法
public class ClientLoggerInterceptor:Interceptor
{
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
LogCall(context.Method);
return continuation(request, context);
}
private void LogCall<TRequest, TResponse>(Method<TRequest, TResponse> method)
where TRequest : class
where TResponse : class
{
var initialColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Starting call. Type: {method.Type}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}");
Console.ForegroundColor = initialColor;
}
}
注冊(cè)攔截器:
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var invoker = channel.Intercept(new ClientLoggerInterceptor());
var catClient = new LuCat.LuCatClient(invoker);
var catReply = await catClient.SuckingCatAsync(new Empty());
Console.WriteLine("調(diào)用擼貓服務(wù):"+ catReply.Message);
然后運(yùn)行:

可以看到成功的在客戶端攔截到了調(diào)用,并記錄了調(diào)用信息。
四. 服務(wù)端攔截器
在服務(wù)端項(xiàng)目新建一個(gè)類(lèi),命名為 ServerLoggerInterceptor,繼承攔截器基類(lèi) Interceptor。
我們?cè)诜?wù)端需要實(shí)現(xiàn)的方法是 UnaryServerHandler
public class ServerLoggerInterceptor: Interceptor
{
private readonly ILogger<ServerLoggerInterceptor> _logger;
public ServerLoggerInterceptor(ILogger<ServerLoggerInterceptor> logger)
{
_logger = logger;
}
public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
LogCall<TRequest, TResponse>(MethodType.Unary, context);
return continuation(request, context);
}
private void LogCall<TRequest, TResponse>(MethodType methodType, ServerCallContext context)
where TRequest : class
where TResponse : class
{
_logger.LogWarning($"Starting call. Type: {methodType}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}");
}
}
注冊(cè)攔截器:
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc(options =>
{
options.Interceptors.Add<ServerLoggerInterceptor>();
});
}
運(yùn)行:

可以看到服務(wù)端成功攔截到了,客戶端的調(diào)用。
五. 參考資料
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 使用grpcui測(cè)試ASP.NET core的gRPC服務(wù)
- .NET?Core(.NET6)中g(shù)RPC使用實(shí)踐
- .Net?Core微服務(wù)rpc框架GRPC通信實(shí)際運(yùn)用
- .Net?Core微服務(wù)rpc框架GRPC通信基礎(chǔ)
- 在?ASP.NET?Core?中為?gRPC?服務(wù)添加全局異常處理
- 如何在.NET Core中為gRPC服務(wù)設(shè)計(jì)消息文件(Proto)
- .Net Core中使用Grpc的方法
- ASP.NET Core 3.0使用gRPC的具體方法
- 圖析ASP.NET Core引入gRPC服務(wù)模板
- ASP.NET Core中Grpc通信的簡(jiǎn)單用法
相關(guān)文章
動(dòng)態(tài)加載Js代碼到Head標(biāo)簽中的腳本
我遇到了這樣的問(wèn)題,請(qǐng)教google,結(jié)果大多數(shù)只是介紹那個(gè)注冊(cè)js的幾個(gè)函數(shù),而這幾個(gè)函數(shù)插入的js都在body里面,幸而在老外那里看到了這個(gè)代碼,其實(shí)比較簡(jiǎn)單,但夠有用2009-01-01
關(guān)于.NET6?Minimal?API的使用方式詳解
本文我們主要是介紹了ASP.NET?Core?6?Minimal?API的常用的使用方式,在.NET6中也是默認(rèn)的項(xiàng)目方式,整體來(lái)說(shuō)卻是非常的簡(jiǎn)單、簡(jiǎn)潔、強(qiáng)大、靈活,不得不說(shuō)Minimal?API卻是在很多場(chǎng)景都非常適用的2021-12-12
Asp.net利用一般處理程序?qū)崿F(xiàn)文件下載功能
這篇文章主要介紹了Asp.net利用一般處理程序?qū)崿F(xiàn)文件下載功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-07-07
asp.net(c#)實(shí)現(xiàn)從sqlserver存取二進(jìn)制圖片的代碼
有一個(gè)員工表Employee,需要保存員工照片(Photo)到數(shù)據(jù)庫(kù)(sql server)上。員工照片對(duì)應(yīng)的字段是varbinary(max),也就是要存成二進(jìn)制文件類(lèi)型(這和以前討巧地存圖片文件路徑就不相同了),默認(rèn)可以為空。2011-09-09
.Net基于MVC4 Web Api輸出Json格式實(shí)例
這篇文章主要介紹了.Net基于MVC4 Web Api輸出Json格式的實(shí)現(xiàn)方法,實(shí)例講述了Global中json的操作與XML的處理等技巧,需要的朋友可以參考下2014-10-10
.NET6打包部署到Windows?Service的全過(guò)程
net用了這么久,雖然多數(shù)都是部署在centos系統(tǒng),但也有部署在windows上的情況,下面這篇文章主要給大家介紹了關(guān)于.NET6打包部署到Windows?Service的相關(guān)資料,需要的朋友可以參考下2022-10-10
asp.net core 多文件分塊同時(shí)上傳的組件
分享一個(gè)可多個(gè)文件同時(shí)上傳、斷點(diǎn)續(xù)傳,并實(shí)時(shí)反饋上傳進(jìn)度的 Asp.Net core 組件,本文通過(guò)實(shí)例代碼對(duì)asp.net core 多文件分塊同時(shí)上傳的組件知識(shí)介紹的非常詳細(xì),感興趣的朋友一起看看吧2023-12-12
ASP.NET Core按用戶等級(jí)授權(quán)的方法
這篇文章主要介紹了ASP.NET Core按用戶等級(jí)授權(quán),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01

