zoukankan      html  css  js  c++  java
  • <七>调用服务路由改成由客户端传入

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

    但是实际上这个路由应该由客户端传过来,参数应该放到参数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、运行结果,如下图,已经成功了。

    
    
  • 相关阅读:
    202002知识点
    爬取思想流程
    测试
    运维
    设计模式重温
    ?March2020疑问点
    最方便简洁的设置Sublime编辑预览MarkDown
    rime中州韵输入法安装及配置
    Deepin更新Sublime并取消更新提示
    关于在线教学软件一些发现和思考
  • 原文地址:https://www.cnblogs.com/choii/p/14604608.html
Copyright © 2011-2022 走看看