跳到主要内容
版本:2.1

Rpc服务AOP

定义

命名空间:TouchSocket.Rpc
程序集:TouchSocket.Rpc.dll

一、说明

Rpc服务在被调用时,会触发一系列的Rpc筛选器AOPIRpcActionFilter特性(Attribute),进行相关AOP操作。所以可以利用该特性做很多有关Rpc的AOP操作。

二、支持的特性方法

方法名触发时机功能
ExecutingAsync在执行Rpc之前当invokeResult的InvokeStatus不为InvokeStatus.Ready。则不会执行Rpc。同时,当InvokeStatus为Success。会直接返回结果
ExecutExceptionAsync执行Rpc遇见异常如果修改invokeResult的InvokeStatus,或Result。则会影响Rpc最终结果
ExecutedAsync成功执行Rpc后如果修改invokeResult的InvokeStatus,或Result。则会影响Rpc最终结果

三、使用

3.1 定义RpcActionFilterAttribute特性

public class MyRpcActionFilterAttribute : RpcActionFilterAttribute
{
public override Task<InvokeResult> ExecutingAsync(ICallContext callContext, object[] parameters, InvokeResult invokeResult)
{
//invokeResult = new InvokeResult()
//{
// Status = InvokeStatus.UnEnable,
// Message = "不允许执行",
// Result = default
//};
if (callContext.Caller is ITcpSessionClient client)
{
client.Logger.Info($"即将执行Rpc-{callContext.RpcMethod.Name}");
}
return Task.FromResult(invokeResult);
}

public override Task<InvokeResult> ExecutedAsync(ICallContext callContext, object[] parameters, InvokeResult invokeResult)
{
if (callContext.Caller is ITcpSessionClient client)
{
client.Logger.Info($"执行RPC-{callContext.RpcMethod.Name}完成,状态={invokeResult.Status}");
}
return Task.FromResult(invokeResult);
}

public override Task<InvokeResult> ExecutExceptionAsync(ICallContext callContext, object[] parameters, InvokeResult invokeResult, Exception exception)
{
if (callContext.Caller is ITcpSessionClient client)
{
client.Logger.Info($"执行RPC-{callContext.RpcMethod.Name}异常,信息={invokeResult.Message}");
}
return Task.FromResult(invokeResult);
}
}
提示

使用RpcActionFilterAttribute特性,不仅可以实现日志记录,还可以实现访问权限限制、全局异常捕捉等。

3.2 使用

RpcActionFilterAttribute 特性可以应用到任何方法上,也可以应用到类上。

[MyRpcActionFilter]
class MyRpcServer : RpcServer
{
private readonly ILog m_logger;

public MyRpcServer(ILog logger)
{
this.m_logger = logger;
}

/// <summary>
/// 将两个数相加
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
[DmtpRpc(true)]//使用函数名直接调用
[Description("将两个数相加")]//其作用是生成代理时,作为注释。
[MyRpcActionFilter]
public int Add(int a, int b)
{
this.m_logger.Info("调用Add");
var sum = a + b;
return sum;
}
}

3.3 规则

  1. 标签添加在方法注册接口注册服务上均会生效。
  2. 标签生效顺序为接口方法(如果有)服务方法注册接口(如果有)、服务
  3. 同一类型的标签仅生效一次。
  4. 继承的特性,可以通过MutexAccessTypes属性来标识以哪个类型作为同一特性标识。

第1、2条规则,以下代码为例,执行顺序依次为MyRpcActionFilter1MyRpcActionFilter3MyRpcActionFilter2MyRpcActionFilter4

[MyRpcActionFilter2]
interface IMyRpcServer : IRpcServer
{
[MyRpcActionFilter1]
int Add(int a, int b);
}

[MyRpcActionFilter4]
class MyRpcServer :RpcServer, IMyRpcServer
{
[MyRpcActionFilter3]
public int Add(int a, int b)
{
return a + b;
}
}

第3条规则,以下代码为例,只会将MyRpcActionFilter执行一次。

[MyRpcActionFilter]
interface IMyRpcServer : IRpcServer
{
[MyRpcActionFilter]
int Add(int a, int b);
}

[MyRpcActionFilter]
class MyRpcServer :RpcServer, IMyRpcServer
{
[MyRpcActionFilter]
public int Add(int a, int b)
{
return a + b;
}
}

第4条规则,以下代码为例。在MyBaseAttribute中指定MutexAccessTypesMyBaseAttribute,则MyAttributeMy2Attribute都继承MyBaseAttribute时,即为互斥,在生效时会按照优先等级有且只有一个生效。

interface IInterface
{
[My]
[My2]
void Test();
}

class MyBaseAttribute:RpcActionFilterAttribute
{
public override Type[] MutexAccessTypes => new Type[] {typeof(MyBaseAttribute) };
}

class MyAttribute: MyBaseAttribute
{

}

class My2Attribute : MyBaseAttribute
{

}