Пример #1
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, Object session, String action, Object args, Byte flag = 0)
        {
            if (session == null)
            {
                return(false);
            }

            // 性能计数器,次数、TPS、平均耗时
            var st = host.StatInvoke;

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

            if (msg is DefaultMessage dm)
            {
                dm.OneWay = true;
                if (flag > 0)
                {
                    dm.Flag = flag;
                }
            }

            var sw = st.StartCount();

            try
            {
                if (session is IApiSession ss)
                {
                    return(ss.Send(msg));
                }
                else if (session is ISocketRemote client)
                {
                    return(client.SendMessage(msg));
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            finally
            {
                var msCost = st.StopCount(sw) / 1000;
                if (host.SlowTrace > 0 && msCost >= host.SlowTrace)
                {
                    host.WriteLog($"慢调用[{action}],耗时{msCost:n0}ms");
                }
            }
        }
Пример #2
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, Object session, Type resultType, String action, Object args, Byte flag)
        {
            if (session == null)
            {
                return(null);
            }

            // 性能计数器,次数、TPS、平均耗时
            //host.StatSend?.Increment();
            var st = host.StatInvoke;
            var sw = st.StartCount();

            // 编码请求,构造消息
            var enc = host.Encoder;
            var msg = enc.CreateRequest(action, args);

            if (flag > 0 && msg is DefaultMessage dm)
            {
                dm.Flag = flag;
            }

            var      invoker = session;
            IMessage rs      = null;

            try
            {
                if (session is IApiSession ss)
                {
                    rs = await ss.SendAsync(msg);
                }
                else if (session is ISocketRemote client)
                {
                    rs = (await client.SendMessageAsync(msg)) as IMessage;
                }
                else
                {
                    throw new InvalidOperationException();
                }

                if (rs == null)
                {
                    return(null);
                }
            }
            catch (AggregateException aggex)
            {
                var ex = aggex.GetTrue();
                if (ex is TaskCanceledException)
                {
                    throw new TimeoutException($"请求[{action}]超时!", ex);
                }
                throw aggex;
            }
            catch (TaskCanceledException ex)
            {
                throw new TimeoutException($"请求[{action}]超时!", ex);
            }
            finally
            {
                var msCost = st.StopCount(sw) / 1000;
                if (host.SlowTrace > 0 && msCost >= host.SlowTrace)
                {
                    host.WriteLog($"慢调用[{action}],耗时{msCost:n0}ms");
                }
            }

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

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

            // 是否成功
            if (code != 0)
            {
                throw new ApiException(code, $"远程[{invoker}]错误! {data.ToStr()}");
            }

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

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

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

            // 返回
            return(enc.Convert(result, resultType));
        }