private string BuildRpcInfo() { string info = ""; foreach (var kv in rpcProcessor.UrlPath2Method) { string urlPath = kv.Key; var m = kv.Value; if (m.DocEnabled == false) { continue; } string returnType = m.Method.ReturnType.ToString(); var args = ""; ParameterInfo[] pinfos = m.Method.GetParameters(); for (int i = 0; i < pinfos.Length; i++) { ParameterInfo pinfo = pinfos[i]; args += pinfo.ToString(); if (i < pinfos.Length - 1) { args += ", "; } } var link = PathKit.Join(rpcProcessor.UrlPrefix, urlPath); info += string.Format(RpcMethodTemplate, link, returnType, m.Method.Name, args); } return(string.Format(RpcInfoTemplate, rpcProcessor.UrlPrefix, RpcStyleTemplate, info)); }
public void Mount(string urlPrefix, object service, bool docEnabled = true) { List <Type> types = new List <Type>(); types.Add(service.GetType()); foreach (Type type in service.GetType().GetInterfaces()) { types.Add(type); } foreach (Type type in types) { foreach (MethodInfo info in type.GetMethods()) { if (info.DeclaringType != type || !info.IsPublic) { continue; } string urlPath = PathKit.Join(urlPrefix, info.Name); bool exclude = false; string httpMethod = null; foreach (Attribute attr in Attribute.GetCustomAttributes(info)) { if (attr.GetType() == typeof(RequestMapping)) { RequestMapping r = (RequestMapping)attr; if (r.Path != null) { urlPath = PathKit.Join(urlPrefix, r.Path); } if (r.Exclude) { exclude = true; } if (r.Method != null) { httpMethod = r.Method; } break; } } if (exclude) { continue; } ParameterInfo[] paramInfo = info.GetParameters(); Type[] paramTypes = new Type[paramInfo.Length]; for (int i = 0; i < paramTypes.Length; i++) { paramTypes[i] = paramInfo[i].ParameterType; } MethodInstance instance = new MethodInstance(info, service); instance.HttpMethod = httpMethod; instance.DocEnabled = docEnabled; UrlPath2Method[urlPath] = instance; } } }
public async Task <T> InvokeAsync <T>(string url, object[] args, int timeoutMillis = 10000) { Message msg = new Message(); msg.Url = PathKit.Join(UrlPrefix, url); msg.Body = args; return(await InvokeAsync <T>(msg, timeoutMillis)); }
public void MountDoc() { if (!DocEnabled) { return; } string urlPath = PathKit.Join(DocUrlPrefix, "/"); if (UrlPath2Method.ContainsKey(urlPath)) { return; } this.Mount(DocUrlPrefix, new RpcInfo(this), false); }
public List <UrlEntry> UrlEntryList(string mq) { List <UrlEntry> res = new List <UrlEntry>(); foreach (var kv in UrlPath2Method) { string urlPath = kv.Key; var e = new UrlEntry { Url = PathKit.Join(UrlPrefix, urlPath), Mq = mq }; res.Add(e); } return(res); }
public T CreateProxy <T>(string urlPrefix) { urlPrefix = PathKit.Join(this.UrlPrefix, urlPrefix); return(new RpcProxy <T>(this, urlPrefix).Create()); }
public override IMessage Invoke(IMessage msg) { var methodCall = (IMethodCallMessage)msg; var method = (MethodInfo)methodCall.MethodBase; if (method.DeclaringType.FullName.Equals("System.IDisposable")) { return(new ReturnMessage(null, null, 0, methodCall.LogicalCallContext, methodCall)); } if (method.DeclaringType.Name.Equals("Object")) { var result = method.Invoke(this, methodCall.Args); return(new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall)); } try { string methodName = methodCall.MethodName; object[] args = methodCall.Args; Message req = new Message(); req.Url = PathKit.Join(this.urlPrefix, methodName); req.Body = args; Type returnType = method.ReturnType; //Simple methods if (!typeof(Task).IsAssignableFrom(returnType)) { dynamic res = Request(returnType, req); if (res != null && res is Exception) { return(new ReturnMessage(res as Exception, methodCall)); } return(new ReturnMessage(res, null, 0, methodCall.LogicalCallContext, methodCall)); } //Task returned method Type realType = typeof(void); if (returnType.GenericTypeArguments.Length >= 1) { realType = returnType.GenericTypeArguments[0]; } Task task = null; if (realType == typeof(void)) { task = Task.Run(() => { Request(realType, req); }); } else { MethodInfo invokeMethod = this.GetType().GetRuntimeMethod("Request", new Type[] { typeof(Type), typeof(Message) }); var calledExp = Expression.Call( Expression.Constant(this), invokeMethod, Expression.Constant(realType), Expression.Constant(req) ); var castedExp = Expression.Convert(calledExp, realType); var d = Expression.Lambda(castedExp).Compile(); task = (Task)Activator.CreateInstance(returnType, d); task.Start(); } return(new ReturnMessage(task, null, 0, methodCall.LogicalCallContext, methodCall)); } catch (Exception e) { if (e is TargetInvocationException && e.InnerException != null) { return(new ReturnMessage(e.InnerException, msg as IMethodCallMessage)); } return(new ReturnMessage(e, msg as IMethodCallMessage)); } }
public void Start() { if (Mq == null) { throw new MissingFieldException("missing mq field"); } if (Channel == null) { Channel = Mq; } processor.MountDoc(); MqClient client = new MqClient(MqServerAddress); if (AuthEnabled) { client.AuthEnabled = AuthEnabled; client.ApiKey = ApiKey; client.SecretKey = SecretKey; } client.OnOpen += async(cli) => { Message msg = new Message(); msg.Headers[Protocol.CMD] = Protocol.CREATE; msg.Headers[Protocol.MQ] = Mq; msg.Headers[Protocol.MQ_TYPE] = MqType; msg.Headers[Protocol.CHANNEL] = Channel; var res = await client.InvokeAsync(msg); logger.Info(JsonKit.SerializeObject(res)); msg = new Message(); msg.Headers[Protocol.CMD] = Protocol.SUB; msg.Headers[Protocol.MQ] = Mq; msg.Headers[Protocol.CHANNEL] = Channel; res = await client.InvokeAsync(msg); logger.Info(JsonKit.SerializeObject(res)); msg = new Message(); msg.Headers[Protocol.CMD] = Protocol.BIND; msg.Headers[Protocol.MQ] = Mq; msg.Body = processor.UrlEntryList(Mq); res = await client.InvokeAsync(msg); logger.Info(JsonKit.SerializeObject(res)); }; client.AddMqHandler(Mq, Channel, async(request) => { string prefix = processor.UrlPrefix; string url = request.Url; if (url != null && url.StartsWith(prefix)) { url = url.Substring(prefix.Length); request.Url = PathKit.Join(url); } string id = (string)request.Headers[Protocol.ID]; string source = (string)request.Headers[Protocol.SOURCE]; Message response = new Message(); try { await processor.ProcessAsync(request, response); } catch (Exception e) { while (e.InnerException != null) { e = e.InnerException; } response.Status = 500; response.Headers["content-type"] = "text/plain; charset=utf8;"; response.Body = e.Message; } response.Headers[Protocol.CMD] = Protocol.ROUTE; response.Headers[Protocol.ID] = id; response.Headers[Protocol.TARGET] = source; await client.SendAsync(response); }); client.ConnectAsync().Wait(); }