<七>调用服务路由改成由客户端传入

上一节中,我们在服务端的执行方法中定死了反射的路由,如下图。

但是实际上这个路由应该由客户端传过来,参数应该放到参数r里面去。

上一节我们把GrpcRequest的参数类型定死了string,为了支持多参数,那么我们改一下,把参数类型改成一个字典。

 1、修改proto文件的GrpcRequest参数改成字典以支持多参数

message GrpcRequest{
     map<string,string> requestMsg=1;
 } 

2、修改一下GetInvokeMethod 方法的代码,base命名空间下新增一个类 ServicesRoute 保存固定字段

 public class ServicesRoute
    {
        public  const string NAMESPACE = "NameSpace";
        public  const string CLASSNAME = "ClassName";
        public  const string METHODNAME = "MethodName";
    }
    public class BuildServices
    {
        /// <summary>
        /// 执行服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="r"></param>
        /// <returns></returns>
        public static T GetInvokeMethod<T>(GrpcRequest r)
        {
            try
            {
                if (r.RequestMsg == null || r.RequestMsg.Count <= 0)
                {
                    throw (new Exception("参数无效!"));
                }
                string nameSpace = "", className = "", methodName = "";
                List<Type> paratypes = new List<Type>();
                List<string> param = new List<string>();
                foreach (string key in r.RequestMsg.Keys)
                {
                    switch (key)
                    {
                        case ServicesRoute.NAMESPACE:
                            nameSpace = r.RequestMsg[key];//"AidenGRPC.Module";
                            break;
                        case ServicesRoute.CLASSNAME:
                            className = r.RequestMsg[key];// "SayHelleServer";
                            break;
                        case ServicesRoute.METHODNAME:
                            methodName = r.RequestMsg[key];//"AidenGRPC.Module";
                            break;
                        default:  paratypes.Add(r.RequestMsg[key].GetType());
                                  param.Add(r.RequestMsg[key]);
                            break;
                    }                               
                }
                if (string.IsNullOrEmpty(nameSpace) || string.IsNullOrEmpty(className) || string.IsNullOrEmpty(methodName))
                {
                    throw (new Exception("参数无效!"));
                }//命名空间.类名,程序集               
                object instance = Assembly.Load(nameSpace).CreateInstance(nameSpace + "." + className);
                Type type = instance.GetType();
                //根据类型创建实例
                object obj = Activator.CreateInstance(type, true);
                //加载方法参数类型及方法
                MethodInfo method = null;
                if (paratypes.Count >= 1)
                {
                    method = type.GetMethod(methodName, paratypes.ToArray()); //加载有参方法
                    return (T)method.Invoke(obj, param.ToArray());
                }
                else
                {
                    method = type.GetMethod(methodName);
                    return (T)method.Invoke(obj,null);
                }
                //类型转换并返回
                
            }
            catch (Exception ex)
            {
                //发生异常时,返回类型的默认值。
                return default(T);
            }
        }
    }

3、新增一个Invoke公共方法来处理服务的调用

public  class Request
    {
        public string Ip { get; set; }
        public int Port { get; set; }
        public string ChannelRoute { get; set; }
        public Request(string ip, int port)
        {
            Ip = ip;
            Port = port;
            ChannelRoute = $"{ip}:{port}";
        }
        public GrpcResponse Invork(Dictionary<string,string> requestMsg)
        {
            Channel channel = new Channel(ChannelRoute, ChannelCredentials.Insecure);
            var client = new AidenGRPC.RPCBase.TestServer.TestServerClient(channel);
            GrpcRequest re = new GrpcRequest();
            re.RequestMsg.Add(requestMsg);
            GrpcResponse rp = client.Invoke(re);
            return rp;
        }
    }

4、修改一下客户端的main函数

 static void Main(string[] args)
        {
            Dictionary<string, string> requestMsg = new Dictionary<string, string>();
            requestMsg.Add(ServicesRoute.NameSpace.ToString(), "AidenGRPC.Module");
            requestMsg.Add(ServicesRoute.ClassName.ToString(), "SayHelleServer");
            requestMsg.Add(ServicesRoute.MethodName.ToString(), "SayHello");
            requestMsg.Add("name","Aiden");
            GrpcResponse rp =new Request("127.0.0.1", 30052).Invoke(requestMsg);
            Console.WriteLine(rp.ResponseMsg);
            Console.WriteLine("Press any key to exit client...");
            Console.ReadKey();        
        }

5、运行结果,如下图,已经成功了。

 

 

 

 


posted @ 2021-04-02 01:30  许轩霖  阅读(64)  评论(0编辑  收藏  举报