Пример #1
0
        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));
        }
Пример #2
0
        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;
                }
            }
        }
Пример #3
0
        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));
        }
Пример #4
0
        public void MountDoc()
        {
            if (!DocEnabled)
            {
                return;
            }
            string urlPath = PathKit.Join(DocUrlPrefix, "/");

            if (UrlPath2Method.ContainsKey(urlPath))
            {
                return;
            }

            this.Mount(DocUrlPrefix, new RpcInfo(this), false);
        }
Пример #5
0
        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);
        }
Пример #6
0
 public T CreateProxy <T>(string urlPrefix)
 {
     urlPrefix = PathKit.Join(this.UrlPrefix, urlPrefix);
     return(new RpcProxy <T>(this, urlPrefix).Create());
 }
Пример #7
0
        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));
            }
        }
Пример #8
0
        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();
        }