Пример #1
0
        /// <summary>准备上下文</summary>
        /// <param name="session"></param>
        /// <param name="action"></param>
        /// <param name="args"></param>
        /// <param name="api"></param>
        /// <returns></returns>
        protected virtual ControllerContext Prepare(IApiSession session, String action, Packet args, ApiAction api)
        {
            //var enc = Host.Encoder;
            var enc = session["Encoder"] as IEncoder ?? Host.Encoder;

            // 当前上下文
            var ctx = ControllerContext.Current;

            if (ctx == null)
            {
                ctx = new ControllerContext();
                ControllerContext.Current = ctx;
            }
            ctx.Action     = api;
            ctx.ActionName = action;
            ctx.Session    = session;
            ctx.Request    = args;

            // 如果服务只有一个二进制参数,则走快速通道
            if (!api.IsPacketParameter)
            {
                // 不允许参数字典为空
                var dic = args == null || args.Total == 0 ?
                          new NullableDictionary <String, Object>(StringComparer.OrdinalIgnoreCase) :
                          enc.DecodeParameters(action, args);
                ctx.Parameters = dic;

                // 准备好参数
                var ps = GetParams(api.Method, dic, enc);
                ctx.ActionParameters = ps;
            }

            return(ctx);
        }
Пример #2
0
        /// <summary>订阅主题</summary>
        /// <param name="user"></param>
        /// <param name="session"></param>
        /// <returns></returns>
        public Boolean Add(String user, IApiSession session)
        {
            if (Subscribers.ContainsKey(user))
            {
                return(false);
            }

            var scb = new Subscriber
            {
                User    = user,
                Session = session
            };

            Subscribers[user] = scb;

            var ds = session as IDisposable2;

            if (ds != null)
            {
                ds.OnDisposed += (s, e) => Remove(user);
            }

#if DEBUG
            var msg = new Message
            {
                Sender = user,
                Body   = "上线啦"
            };
            Enqueue(msg);
#endif

            return(true);
        }
Пример #3
0
        /// <summary>执行过滤器</summary>
        /// <param name="host"></param>
        /// <param name="session"></param>
        /// <param name="msg"></param>
        /// <param name="issend"></param>
        internal static void ExecuteFilter(this IApiHost host, IApiSession session, IMessage msg, Boolean issend)
        {
            var fs = host.Filters;

            if (fs.Count == 0)
            {
                return;
            }

            // 接收时需要倒序
            if (!issend)
            {
                fs = fs.Reverse().ToList();
            }

            var ctx = new ApiFilterContext {
                Session = session, Packet = msg.Payload, Message = msg, IsSend = issend
            };

            foreach (var item in fs)
            {
                item.Execute(ctx);
            }
            msg.Payload = ctx.Packet;
        }
Пример #4
0
        private IMessage OnProcess(IApiSession session, IMessage msg)
        {
            var enc = Encoder;

            var    action = "";
            Object result = null;
            var    code   = 0;

            try
            {
                if (!ApiHostHelper.Decode(msg, out action, out _, out var args))
                {
                    return(null);
                }

                result = Handler.Execute(session, action, args);
            }
            catch (Exception ex)
            {
                ex = ex.GetTrue();

                // 支持自定义错误
                if (ex is ApiException aex)
                {
                    code   = aex.Code;
                    result = ex?.Message;
                }
                else
                {
                    code   = 500;
                    result = ex?.Message;
                }
            }

            // 单向请求无需响应
            if (msg is DefaultMessage dm && dm.OneWay)
            {
                return(null);
            }

            // 编码响应数据包,二进制优先
            var pk = result as Packet;

            if (pk == null)
            {
                pk = enc.Encode(action, code, result);
            }
            pk = ApiHostHelper.Encode(action, code, pk);

            // 构造响应消息
            var rs = msg.CreateReply();

            rs.Payload = pk;
            if (code > 0 && rs is DefaultMessage dm2)
            {
                dm2.Error = true;
            }

            return(rs);
        }
Пример #5
0
        /// <summary>
        /// Usecase: Investors provides a Purchase Advice document after purchasing a closed loan
        /// 1. Query for loan
        /// 2. Acquire Shared Lock
        /// 3. Create Document
        /// 4. Upload Attachments
        /// 5. Assign Attachments to Document
        /// 6. Release Shared Lock
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        private static async Task PurchaseAdvise(IApiSession session)
        {
            // 1. Query for loan
            var loanId = await QueryForLoan(session, Configuration.LoanNumber, Configuration.LoanFolder);

            // 2. Acquire Shared Lock
            using (await AcquireSharedLock(session, loanId))
            {
                // 3. Create Document
                var document = await CreateDocument(session, loanId);

                /**
                 * We have 2 attachemnts ready to be uploaded in the directory {DIR_OF_THIS_EXE}\res\attachments
                 * "Sample BBT PA.pdf"
                 * "Sample Purchase Advice.pdf"
                 */
                var attachmentsDirPath = Path.Combine(Directory.GetCurrentDirectory(), @"res\attachments");

                // 4. Upload Attachments
                var attachmentIds = await UploadAttachments(session, loanId, attachmentsDirPath);

                // 5. Assign Attachments to Document
                await AssignAttachmentsToDocument(session, loanId, document.Id, attachmentIds);
            } // 6. Release Shared Lock
        }
Пример #6
0
        private Packet ProcessHandler(IApiSession session, Packet pk)
        {
            var enc = Encoder;

            // 这里会导致二次解码,因为解码以后才知道是不是请求
            var dic = enc.Decode(pk);

            var    action = "";
            Object args   = null;

            if (!enc.TryGet(dic, out action, out args))
            {
                return(null);
            }

            Object result = null;
            var    code   = 0;

            try
            {
                result = Handler.Execute(session, action, args as IDictionary <String, Object>).Result;
            }
            catch (Exception ex)
            {
                var aex = ex as ApiException;
                code   = aex != null ? aex.Code : 500;
                result = ex;
            }

            // 编码响应数据包
            return(enc.Encode(code, result));
        }
Пример #7
0
        private static async Task <ExportJobStatusContract> CreateExportJob(IApiSession session, string loanId, FileAttachmentReferenceContract[] attachments)
        {
            var exportJobsApi = session.GetApi <ExportJobsApi>();

            // Build the payload to fetch documents using eFolder export job api
            var exportJobInput = new ExportJobContract()
            {
                AnnotationSettings = new AnnotationSettingsContract()
                {
                    Visibility = new VisibilityType[] { VisibilityType.Internal, VisibilityType.Private, VisibilityType.Public }
                },
                Entities = attachments.Select(attachment => new EFolderEntityRef()
                {
                    EntityId   = attachment.EntityId,
                    EntityType = EFolderEntityType.Attachment
                }).ToArray(),
                Source = new EFolderEntityRef()
                {
                    EntityId   = loanId,
                    EntityType = EFolderEntityType.Loan
                }
            };

            return(await exportJobsApi.CreateExportJob(exportJobInput));
        }
Пример #8
0
        /// <summary>处理请求消息。重载、事件、控制器 共三种消息处理方式</summary>
        /// <param name="session"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        protected virtual IMessage OnReceive(IApiSession session, IMessage msg)
        {
            // 优先调用外部事件
            if (Received != null)
            {
                var e = new ApiMessageEventArgs
                {
                    Session = session,
                    Message = msg
                };
                Received(this, e);

                if (e.Handled)
                {
                    return(e.Message);
                }
            }

            var pk = msg.Payload;

            // 如果外部事件未处理,再交给处理器
            pk = ProcessHandler(session, pk);

            // 封装响应消息
            var rs = msg.CreateReply();

            rs.Payload = pk;

            return(rs);
        }
Пример #9
0
        /// <summary>调用</summary>
        /// <param name="host"></param>
        /// <param name="session"></param>
        /// <param name="action">服务操作</param>
        /// <param name="args">参数</param>
        /// <param name="flag">标识</param>
        /// <returns></returns>
        public static Boolean Invoke(IApiHost host, IApiSession session, String action, Object args, Byte flag = 0)
        {
            if (session == null)
            {
                return(false);
            }

            host.StatSend?.Increment();

            // 编码请求
            var pk = EncodeArgs(host.Encoder, action, args);

            // 构造消息
            var msg = new DefaultMessage
            {
                OneWay  = true,
                Payload = pk,
            };

            if (flag > 0)
            {
                msg.Flag = flag;
            }

            return(session.Send(msg));
        }
Пример #10
0
        private Packet ProcessHandler(IApiSession session, Packet pk)
        {
            var enc = Encoder;

            var    action = "";
            Object result = null;
            var    code   = 0;
            var    seq    = -1;

            try
            {
                // 这里会导致二次解码,因为解码以后才知道是不是请求
                var dic = enc.Decode(pk);

                // 请求响应,由code决定
                if (dic.ContainsKey("code"))
                {
                    return(null);
                }

                Object args = null;
                //if (!enc.TryGet(dic, out action, out args)) return null;
                Object obj = null;
                if (!dic.TryGetValue("action", out obj))
                {
                    return(null);
                }

                // 参数可能不存在
                dic.TryGetValue("args", out args);

                action = obj + "";

                // 针对Http前端Json,可能带有序列号
                if (dic.TryGetValue("seq", out obj))
                {
                    seq = obj.ToInt();
                }

                result = Handler.Execute(session, action, args as IDictionary <String, Object>);
            }
            catch (Exception ex)
            {
                ex = ex.GetTrue();
                var aex = ex as ApiException;
                code   = aex != null ? aex.Code : 500;
                result = ex?.Message;
            }

            // 编码响应数据包
            //return enc.Encode(code, result);

            if (seq >= 0)
            {
                return(enc.Encode(new { action, code, result, seq }));
            }

            return(enc.Encode(new { action, code, result }));
        }
Пример #11
0
        private IMessage OnProcess(IApiSession session, IMessage msg)
        {
            var enc = Encoder;

            var    action = "";
            Object result = null;
            var    code   = 0;

            try
            {
                if (!enc.Decode(msg, out action, out _, out var args))
                {
                    return(null);
                }

                result = OnProcess(session, action, args);
            }
            catch (Exception ex)
            {
                ex = ex.GetTrue();

                if (ShowError)
                {
                    WriteLog("{0}", ex);
                }

                // 支持自定义错误
                if (ex is ApiException aex)
                {
                    code   = aex.Code;
                    result = ex?.Message;
                }
                else
                {
                    code   = 500;
                    result = ex?.Message;
                }
            }

            // 单向请求无需响应
            if (msg.OneWay)
            {
                return(null);
            }

            //// 编码响应数据包,二进制优先
            //if (!(result is Packet pk)) pk = enc.Encode(action, code, result);
            //pk = enc.Encode(action, code, pk);

            //// 构造响应消息
            //var rs = msg.CreateReply();
            //rs.Payload = pk;
            //if (code > 0) rs.Error = true;
            var rs = enc.CreateResponse(msg, action, code, result);

            return(rs);
        }
Пример #12
0
        /// <summary>处理消息</summary>
        /// <param name="session"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        IMessage IApiHost.Process(IApiSession session, IMessage msg)
        {
            if (msg.Reply)
            {
                return(null);
            }

            StatReceive?.Increment();

            return(OnProcess(session, msg));
        }
Пример #13
0
        /// <summary>准备上下文,可以借助Token重写Session会话集合</summary>
        /// <param name="session"></param>
        /// <param name="action"></param>
        /// <param name="args"></param>
        /// <param name="api"></param>
        /// <param name="msg">消息内容,辅助数据解析</param>
        /// <returns></returns>
        protected virtual ControllerContext Prepare(IApiSession session, String action, Packet args, ApiAction api, IMessage msg)
        {
            //var enc = Host.Encoder;
            var enc = session["Encoder"] as IEncoder ?? Host.Encoder;

            // 当前上下文
            var ctx = ControllerContext.Current;

            if (ctx == null)
            {
                ctx = new ControllerContext();
                ControllerContext.Current = ctx;
            }
            ctx.Action     = api;
            ctx.ActionName = action;
            ctx.Session    = session;
            ctx.Request    = args;

            // 如果服务只有一个二进制参数,则走快速通道
            if (!api.IsPacketParameter)
            {
                // 不允许参数字典为空
                var dic = args == null || args.Total == 0 ?
                          new NullableDictionary <String, Object>(StringComparer.OrdinalIgnoreCase) :
                          enc.DecodeParameters(action, args, msg);
                ctx.Parameters     = dic;
                session.Parameters = dic;

                // 令牌,作为参数或者http头传递
                if (dic.TryGetValue("Token", out var token))
                {
                    session.Token = token + "";
                }
                if (session.Token.IsNullOrEmpty() && msg is HttpMessage hmsg && hmsg.Headers != null)
                {
                    // post、package、byte三种情况将token 写入请求头
                    if (hmsg.Headers.TryGetValue("x-token", out var token2))
                    {
                        session.Token = token2;
                    }
                    else if (hmsg.Headers.TryGetValue("Authorization", out token2))
                    {
                        session.Token = token2.TrimStart("Bearer ");
                    }
                }

                // 准备好参数
                var ps = GetParams(api.Method, dic, enc);
                ctx.ActionParameters = ps;
            }

            return(ctx);
        }
Пример #14
0
        /// <summary>创建控制器实例</summary>
        /// <param name="host"></param>
        /// <param name="session"></param>
        /// <param name="api"></param>
        /// <returns></returns>
        public static Object CreateController(this IApiHost host, IApiSession session, ApiAction api)
        {
            var controller = api.Controller;

            if (controller != null)
            {
                return(controller);
            }

            controller = api.Type.CreateInstance();

            return(controller);
        }
Пример #15
0
        private static Task <IDisposable> AcquireSharedLock(IApiSession session, string loanId)
        {
            var resourceLockApi      = session.GetApi <ResourceLocksApi>();
            var resourceLockApiInput = new ResourceLockContract()
            {
                LockType = ResourceLockType.NGSharedLock,
                Resource = new EncompassEntityRef()
                {
                    EntityId   = loanId,
                    EntityType = EncompassEntityType.Loan
                }
            };

            return(resourceLockApi.CreateResourceLock(resourceLockApiInput));
        }
Пример #16
0
        /// <summary>处理消息</summary>
        /// <param name="session"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        IMessage IApiHost.Process(IApiSession session, IMessage msg)
        {
            if (msg.Reply) return null;

            var st = StatProcess;
            var sw = st.StartCount();
            try
            {
                return OnProcess(session, msg);
            }
            finally
            {
                st.StopCount(sw);
            }
        }
Пример #17
0
        /// <summary>创建控制器实例</summary>
        /// <param name="host"></param>
        /// <param name="session"></param>
        /// <param name="api"></param>
        /// <returns></returns>
        public static Object CreateController(this IApiHost host, IApiSession session, ApiAction api)
        {
            var controller = api.Controller;

            if (controller != null)
            {
                return(controller);
            }

            var att = api.Type?.GetCustomAttribute <ApiAttribute>(true);

            if (att != null && att.IsReusable)
            {
                var ts = session["Controller"] as IDictionary <Type, Object>;
                if (ts == null)
                {
                    session["Controller"] = ts = new NullableDictionary <Type, Object>();

                    // 析构时销毁所有从属控制器
                    var sd = session as IDisposable2;
                    if (sd != null)
                    {
                        sd.OnDisposed += (s, e) =>
                        {
                            foreach (var item in ts)
                            {
                                item.Value.TryDispose();
                            }
                        }
                    }
                    ;
                }

                controller = ts[api.Type];
                if (controller == null)
                {
                    controller = ts[api.Type] = api.Type.CreateInstance();
                }

                return(controller);
            }

            controller = api.Type.CreateInstance();

            return(controller);
        }
    }
Пример #18
0
        private static async Task <DocumentContract> CreateDocument(IApiSession session, string loanId)
        {
            var documentsApi = session.GetApi <DocumentsApi>();
            var documents    = await documentsApi.AddDocuments(
                loanId,
                new DocumentContract[]
            {
                new DocumentContract()
                {
                    Title       = "Purchase Advice",
                    Description = "Purchase Advice Documents"
                }
            },
                view : "entity");

            return(documents.FirstOrDefault());
        }
Пример #19
0
        private static Task <AttachmentUploadDataContract> CreateAttachmentUploadUrl(IApiSession session, string loanId, string fileName, long fileSizeInBytes, string contentType)
        {
            var attachmentsApi = session.GetApi <AttachmentsApi>();

            return(attachmentsApi.GenerateAttachmentUploadUrl(
                       loanId,
                       new AttachmentUploadInputContract()
            {
                File = new AttachmentUploadInputContract.FileData()
                {
                    ContentType = contentType,
                    Name = fileName,
                    Size = fileSizeInBytes
                },
                Title = fileName
            }));
        }
Пример #20
0
        /// <summary>处理消息</summary>
        /// <param name="session"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        IMessage IApiHost.Process(IApiSession session, IMessage msg)
        {
            if (msg.Reply)
            {
                return(null);
            }

            // 过滤器
            this.ExecuteFilter(session, msg, false);

            var rs = OnReceive(session, msg);

            // 过滤器
            this.ExecuteFilter(session, rs, true);

            return(rs);
        }
Пример #21
0
        /// <summary>
        /// Usecase: Lenders need to export documents from the eFolder after a loan has closed
        /// 1. Query for Attachments
        /// 2. Create Export Job
        /// 3. Poll for status
        /// 4. Download and save merged file
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        private static async Task ExportAttachments(IApiSession session)
        {
            var loanId = await QueryForLoan(session, Configuration.LoanNumber, Configuration.LoanFolder);

            // 1.Query for Attachments
            var attachments = await GetLatestDocumentAttachmentRefs(session, loanId);

            // 2. Create Export Job
            var jobStatus = await CreateExportJob(session, loanId, attachments);

            // 3. Poll for status
            jobStatus = await PollExportStatus(session, jobStatus.JobId);

            // 4. Download and save merged file
            var downloadFilePath = Path.Combine(Directory.GetCurrentDirectory(), @"res\downloads", Path.GetRandomFileName() + ".pdf");

            await DownloadMergedAttachments(session, jobStatus, downloadFilePath);
        }
Пример #22
0
        private static async Task <string> QueryForLoan(IApiSession session, string loanNumber, string loanFolder)
        {
            var loanPipelineApi = session.GetApi <LoanPipelineApi>();
            var pipelineItems   = await loanPipelineApi.QueryLoanPipeline(new LoanPipelineQueryContract()
            {
                Fields = new List <string>()
                {
                    "LoanId"
                },
                Filter = new QueryCriterionContract()
                {
                    Operator = BinaryOperator.And,
                    Terms    = new QueryCriterionContract[]
                    {
                        new QueryCriterionContract()
                        {
                            CanonicalName = "Loan.LoanNumber",
                            Value         = loanNumber,
                            MatchType     = MatchType.Exact
                        },
                        new QueryCriterionContract()
                        {
                            CanonicalName = "Loan.LoanFolder",
                            Value         = loanFolder,
                            MatchType     = MatchType.Exact
                        }
                    }
                }
            });


            // Get the loanId from the pipeline items
            var loanId = pipelineItems.FirstOrDefault()?.LoanId;

            if (string.IsNullOrEmpty(loanId))
            {
                // Loan not found, exiting the program!!
                Environment.Exit(1);
            }

            return(loanId);
        }
Пример #23
0
        /// <summary>准备上下文,可以借助Token重写Session会话集合</summary>
        /// <param name="session"></param>
        /// <param name="action"></param>
        /// <param name="args"></param>
        /// <param name="api"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        protected override ControllerContext Prepare(IApiSession session, String action, Packet args, ApiAction api, IMessage msg)
        {
            var ctx = base.Prepare(session, action, args, api, msg);

            var token = session.Token;

            if (!token.IsNullOrEmpty())
            {
                // 第一用户数据是本地字典,用于记录是否启用了第二数据
                if (session is ApiNetSession ns && ns.Items["Token"] + "" != token)
                {
                    var key = GetKey(token);
                    // 采用哈希结构。内存缓存用并行字段,Redis用Set
                    ns.Items2         = Cache.GetDictionary <Object>(key);
                    ns.Items["Token"] = token;
                }
            }

            return(ctx);
        }
Пример #24
0
        /// <summary>处理消息</summary>
        /// <param name="session"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        IMessage IApiHost.Process(IApiSession session, IMessage msg)
        {
            if (msg.Reply)
            {
                return(null);
            }

            //StatReceive?.Increment();
            var st = StatProcess;
            //var sw = st == null ? 0 : Stopwatch.GetTimestamp();
            var sw = st.StartCount();

            try
            {
                return(OnProcess(session, msg));
            }
            finally
            {
                //if (st != null) st.Increment(1, (Stopwatch.GetTimestamp() - sw) / 10);
                st.StopCount(sw);
            }
        }
 public SessionBasedApiBase(IApiSession session, IApiClient apiClient) : base(apiClient)
 {
     _session = ArgumentChecks.IsNotNull(session, nameof(session));
 }
 public DocumentsApi(IApiSession session, IApiClient apiClient) : base(session, apiClient)
 {
 }
Пример #27
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="session"></param>
 public Devices(IApiSession session)
 {
     deviceSession = session;
 }
Пример #28
0
        /// <summary>调用</summary>
        /// <param name="host"></param>
        /// <param name="session"></param>
        /// <param name="resultType">结果类型</param>
        /// <param name="action">服务操作</param>
        /// <param name="args">参数</param>
        /// <param name="flag">标识</param>
        /// <returns></returns>
        public static async Task <Object> InvokeAsync(IApiHost host, IApiSession session, Type resultType, String action, Object args, Byte flag)
        {
            if (session == null)
            {
                return(null);
            }

            host.StatSend?.Increment();

            // 编码请求
            var enc = host.Encoder;
            var pk  = EncodeArgs(enc, action, args);

            // 构造消息
            var msg = new DefaultMessage {
                Payload = pk,
            };

            if (flag > 0)
            {
                msg.Flag = flag;
            }

            var rs = await session.SendAsync(msg);

            if (rs == null)
            {
                return(null);
            }

            // 特殊返回类型
            if (resultType == typeof(IMessage))
            {
                return(rs);
            }
            //if (resultType == typeof(Packet)) return rs.Payload;

            if (!Decode(rs, out var act, out var code, out var data))
            {
                throw new InvalidOperationException();
            }

            // 是否成功
            if (code != 0)
            {
                throw new ApiException(code, data.ToStr());
            }

            if (data == null)
            {
                return(null);
            }
            if (resultType == typeof(Packet))
            {
                return(data);
            }

            // 解码结果
            var result = enc.Decode(action, data);

            if (resultType == typeof(Object))
            {
                return(result);
            }

            // 返回
            return(enc.Convert(result, resultType));
        }
Пример #29
0
        /// <summary>执行</summary>
        /// <param name="session"></param>
        /// <param name="action"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public Object Execute(IApiSession session, String action, Packet args)
        {
            var api = session.FindAction(action);

            if (api == null)
            {
                throw new ApiException(404, "无法找到名为[{0}]的服务!".F(action));
            }

            // 全局共用控制器,或者每次创建对象实例
            var controller = session.CreateController(api);

            if (controller == null)
            {
                throw new ApiException(403, "无法创建名为[{0}]的服务!".F(api.Name));
            }

            if (controller is IApi capi)
            {
                capi.Session = session;
            }

            var enc = Host.Encoder;
            IDictionary <String, Object> ps = null;

            // 上下文
            var ctx = new ControllerContext
            {
                Controller = controller,
                Action     = api,
                ActionName = action,
                Session    = session,
                Request    = args,
            };

            // 当前上下文
            ControllerContext.Current = ctx;

            // 如果服务只有一个二进制参数,则走快速通道
            var fast = api.IsPacketParameter && api.IsPacketReturn;

            if (!fast)
            {
                // 不允许参数字典为空
                var dic = args == null || args.Total == 0 ?
                          new NullableDictionary <String, Object>(StringComparer.OrdinalIgnoreCase) :
                          enc.Decode(action, args) as IDictionary <String, Object>;
                ctx.Parameters = dic;

                // 准备好参数
                ps = GetParams(api.Method, dic, enc);
                ctx.ActionParameters = ps;
            }

            Object rs = null;

            try
            {
                // 执行动作前的过滤器
                if (controller is IActionFilter filter)
                {
                    filter.OnActionExecuting(ctx);
                    rs = ctx.Result;
                }

                // 执行动作
                if (rs == null)
                {
                    if (fast)
                    {
                        var func = api.Method.As <Func <Packet, Packet> >(controller);
                        rs = func(args);
                    }
                    else
                    {
                        // 特殊处理参数和返回类型都是Packet的服务
                        rs = controller.InvokeWithParams(api.Method, ps as IDictionary);
                    }
                    ctx.Result = rs;
                }
            }
            catch (ThreadAbortException) { throw; }
            catch (Exception ex)
            {
                //rs = OnException(ctx, ex);
                ctx.Exception = ex.GetTrue();
            }
            finally
            {
                // 执行动作后的过滤器
                if (controller is IActionFilter filter)
                {
                    filter.OnActionExecuted(ctx);
                    rs = ctx.Result;
                }
                ControllerContext.Current = null;

                if (ctx.Exception != null && !ctx.ExceptionHandled)
                {
                    throw ctx.Exception;
                }
            }

            //// 二进制优先通道
            //if (api.IsPacketReturn && rs is Packet pk) return pk;

            return(rs);
        }
Пример #30
0
 /// <summary>新会话。服务端收到新连接,客户端每次连接或断线重连后,可用于做登录</summary>
 /// <param name="session">会话</param>
 /// <param name="state">状态。客户端ISocketClient</param>
 public virtual void OnNewSession(IApiSession session, Object state)
 {
 }