0.背景
在实际项目当中,我采用的是 Abp 框架,但是 Abp 框架官方并没有针对 Grpc 进行模块封装。基于此我结合 Abp 与 MagicOnion 封装了一个 Abp.Grpc 模块,它包括服务端和调用端两部分的包。通过这两个包,你可以很方便地在 Abp 框架当中集成 Grpc 实现服务内部通讯。
但是在实际使用当中会出现一个问题,当 A 服务调用 B 服务的时候,A 服务当前登录用户为 admin,调用 B 服务的 IAbpSession
的值仍然为空,这个时候当 B 服务内部实现使用了 IAbpSession
时会出现问题。
这是因为通过 Grpc 接口调用时,并没有传递诸如 Token 之类的东西,而在 B 服务内部的 IAbpSession
本身附加的数据是从 HttpContext
里面获取的,所以 B 服务当前是没有用户状态的。
1.解决
所幸 IAbpSession
提供了一个 Use
方法,通过这个方法我们可以临时地改变 IAbpSession
内部的值,当 。定义如下:
IDisposable Use(int? tenantId, long? userId);
使用方法如下:
2.Grpc 接口改造
这里 Abp.Grpc 库使用的是 MagicOnion 库实现 Grpc 接口的,底层序列化使用的是 MessagePack,速度也不比 Protocol Buffer 差。
2.1 服务定义
服务定义接口时,必须附加一个 GrpcSession
参数,这个参数用于调用方传递其 IAbpSession
值所使用。例如我有一个接口方法如下,用于返回服务方接收到的用户 Id 值。
2.2 服务提供方
服务提供方在实现 ITestGrpcService
的时候,需要在代码起始点就开始使用 using
语句包裹代码。
2.3 服务调用方
服务调用方则直接在调用 Grpc 接口的时候,传递给接口当前服务的 Session 状态。
2.4 最后的效果
当客户端调用 GRPC 接口时,会将自身的 Session 状态通过 GrpcSession 传递到服务端,这样服务端就能够共享客户端的绘画状态。
3.Abp.Grpc 项目地址
Abp.Grpc 库地址:https://github.com/GameBelial/Abp.Grpc
4.实现的 DEMO 地址
服务端:https://github.com/GameBelial/Abp.Grpc.Server.Demo
客户端:https://github.com/GameBelial/Abp.Grpc.Client.Demo
原文地址:https://www.cnblogs.com/myzony/p/9454612.html
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com