<七>调用服务路由改成由客户端传入
上一节中,我们在服务端的执行方法中定死了反射的路由,如下图。
但是实际上这个路由应该由客户端传过来,参数应该放到参数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、运行结果,如下图,已经成功了。