• 游戏编程系列[1]--游戏编程中RPC协议的使用[2]--Aop PostSharp篇


      上一篇我们使用了一个通用JSON协议约定来进行达到远程调用的目的。
    但是从实现上,我们需要不断的在所有的方法上添加拦截,并且判断拦截,然后执行,这就达到了一个比较繁琐的目的。

       之前我们尝试过使用代码生成器,直接生成。


    构造基类,TestClassA
    然后使用代码生成器,构造第二个类,TestClassAProxy。
    所有需要的方法,我们都采用虚函数,然后重载,直接调用Base.Func();
    这样也就完成了任务,这个方法的好处,代码生成简单,但是需要替换使用类别。
    相对来说实现成本还比较低,对下面说的方法没什么信心的同学,可以采用这种实现方式。

    然后我们说到到了本篇的主角,AOP利器 PostSharp
    (额,商业软件,但是45天免费试用,我不会告诉你删了注册表后可以无限免费试用)

    来看例子:

       [Serializable]
         //[DebuggerNonUserCode]
         public sealed class ProxyAttribute : OnMethodBoundaryAspect
        {
    
    
            //[DebuggerNonUserCode]
            public override void OnException(MethodExecutionArgs args)
            {
                base.OnException(args);
                WindNet.RemoteCall.Instance.DoError(args.Exception);
                args.FlowBehavior = FlowBehavior.Continue;
                //不抛出
    
            }
    
            //[DebuggerNonUserCode]
            public override void OnSuccess(MethodExecutionArgs args)
            {
                base.OnSuccess(args);
                WindNet.RemoteCall.Instance.DoCallBack(args.ReturnValue, __cid);
            }
    
    
            private WindNet.RPC.RequestObj __cid;
    
    
            //[DebuggerNonUserCode]
            public override void OnEntry(MethodExecutionArgs args)
            {
                var callback = args.Arguments.Last();
             
                var methodName =args.Method.DeclaringType.Name + "." +  args.Method.Name;
                var outargs = new List<object>();
                for (int i = 0; i < args.Arguments.Count - 1; i++)
                {
                    outargs.Add(args.Arguments[i]);
                }
                __cid = WindNet.RemoteCall.Instance.DoCall(callback as Delegate, args.Instance as IOpItem, methodName, outargs.ToArray());
    
                if (WindNet.RemoteCall.Instance.IsLocal || __cid.isLocal)
                {
                    //继续执行
                }
                else
                {
                    args.FlowBehavior = FlowBehavior.Return;
                }
        
            }
        }
    

      然后我们在之前的方法上添加:

    	  public class LocalTest
            {
                /// <summary>
                /// 添加一个消息
                /// </summary>
                [Proxy]
                public static void AddMessage(string topic, string messageBody)
                {
                    //这里什么都不干
                }
            }
    

      生成后反编译

    public class LocalTest
    {
    	public static void AddMessage(string topic, string messageBody)
    	{
    		MethodExecutionArgs methodExecutionArgs = new MethodExecutionArgs(null, new Arguments<string, string>
    		{
    			Arg0 = topic,
    			Arg1 = messageBody
    		});
    		MethodExecutionArgs arg_25_0 = methodExecutionArgs;
    		MethodBase  = <>z__a_3._2;
    		arg_25_0.Method = ;
    		<>z__a_3.a2.OnEntry(methodExecutionArgs);
    		if (methodExecutionArgs.FlowBehavior != FlowBehavior.Return)
    		{
    			try
    			{
    				<>z__a_3.a2.OnSuccess(methodExecutionArgs);
    			}
    			catch (Exception exception)
    			{
    				methodExecutionArgs.Exception = exception;
    				<>z__a_3.a2.OnException(methodExecutionArgs);
    				switch (methodExecutionArgs.FlowBehavior)
    				{
    				case FlowBehavior.Default:
    				case FlowBehavior.RethrowException:
    					IL_81:
    					throw;
    				case FlowBehavior.Continue:
    					methodExecutionArgs.Exception = null;
    					return;
    				case FlowBehavior.Return:
    					methodExecutionArgs.Exception = null;
    					return;
    				case FlowBehavior.ThrowException:
    					throw methodExecutionArgs.Exception;
    				}
    				goto IL_81;
    			}
    		}
    	}
    }
    

      

    帮我们正确的填写了缺失的部分。

    优点:
    简便,自动化,并且不需要去修改成代理类。
    商业版,稳定性良好。
    在VS中集成

    缺点:
    商业化,如果上线保险点还是去买一个。
    Unity中,调试有点Bug,Pdb貌似有bug,兼容性问题。
    如果不想用DLL,需要一些特殊手法才能在Unity中使用。

    PS:不喜欢用商业产品,推荐用Fody,也有实现,回头有可能会切换到那个版本去。

  • 相关阅读:
    NHibernate之映射文件配置说明(转载3)
    NHibernate之映射文件配置说明(转载2)
    NHibernate之映射文件配置说明(转载1)
    NHibernate+NUnit (VS2012+SQL Server2008) (转)
    ASP.NET MVC全局观
    使用Razor来进行页面布局
    视图引擎输出字符串
    @Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction
    Html.Action和Html.RederAction来创建子视图
    从客户端检测到有潜在危险的Request.Form值
  • 原文地址:https://www.cnblogs.com/icesun963/p/6251786.html
Copyright © 2020-2023  润新知