public void BeginInvoke <TArgs>(string methodName, TArgs args, Action <RpcClientContext> callback)
        {
            if (callback == null)
            {
                throw new NotSupportedException("callback *MUST NOT* be null!");
            }

            _perfCounters.InvokeTotal.Increment();
            _perfCounters.InvokePerSec.Increment();
            _perfCounters.ConcurrentContext.Increment();

            RpcRequestHeader request = new RpcRequestHeader();

            request.FromComputer = ServiceEnviornment.ComputerName;
            request.FromService  = ServiceEnviornment.ServiceName;
            request.Service      = _serviceName;
            request.Method       = methodName;
            request.ServerUri    = _nexus.ServerUri.ToString();
            request.ToUri        = ObjectHelper.ToString(_toUri);
            request.HasBody      = typeof(TArgs) != typeof(RpcNull) && args != null;

            IRpcClientTransaction trans = _nexus.CreateTransaction();
            RpcClientContext      ctx   = new RpcClientContext(request, callback, trans, _nexus.ServiceRole);

            ctx.SendRequest <TArgs>(args, _timeout);
        }
        public TResults Invoke <TArgs, TResults>(string methodName, TArgs args, int timeoutMs)
        {
            ManualResetEvent evt     = new ManualResetEvent(false);
            RpcClientContext context = null;

            BeginInvoke <TArgs>(methodName, args,
                                delegate(RpcClientContext c) {
                context = c;
                evt.Set();
            }
                                );
            if (!evt.WaitOne(timeoutMs, false))
            {
                throw new RpcException("SyncInvoke Timeout", "", RpcErrorCode.TransactionTimeout, null);
            }
            else
            {
                return(context.EndInvoke <TResults>());
            }
        }
Exemple #3
0
        /// <summary>
        ///		带参数的异步的调用
        /// </summary>
        /// <param name="methodName">方法名</param>
        /// <typeparam name="TArgs">调用的参数类型</typeparam>
        /// <param name="args">调用的参数</param>
        /// <param name="callback">接受回调的delegate</param>
        public void BeginInvoke <TArgs>(string methodName, TArgs args, Action <RpcClientContext> callback)
        {
            IICAssert.IsNotNull(callback);

            //
            // 如果Interface声明为强类型检查(默认),则需要判断是否为合法的MethodName和类型
            bool isBatch = false;
            RpcClientMethodSensor method = null;

            if (_serviceInterface.ClientCheck)
            {
                method = _serviceInterface.GetMethod(methodName);
                if (method == null)
                {
                    string msg = string.Format("RpcService {0} not exists methods: {1}, please check your code", _serviceInterface.ServiceName, methodName);
                    throw new NotSupportedException(msg);
                }

                bool typeChecked = (method.ArgsType == null || method.ArgsType == typeof(RpcNull)) && (typeof(TArgs) == typeof(RpcNull)) ||
                                   method.ArgsType == typeof(TArgs);

                if (!typeChecked)
                {
                    string msg = string.Format("RpcMethod {0}.{1} Expired type<{2}>, not <{3}>",
                                               _serviceInterface.ServiceName, methodName,
                                               method.ArgsType == null ? "NULL" : ObjectHelper.GetTypeName(method.ArgsType, false),
                                               ObjectHelper.GetTypeName(typeof(TArgs), false));
                    //
                    // TODO: 暂时只记录错误Trace,不抛出异常
                    // throw new NotSupportedException(msg);
                    _tracing.Error(msg);
                }

                if (method.BatchManager != null)
                {
                    isBatch = true;
                }
            }

            RpcRequest request = new RpcRequest(_serviceInterface.ServiceName, methodName, _contextUri);

            if (typeof(TArgs) == typeof(RpcNull) || args == null)
            {
                request.BodyBuffer = null;
            }
            else
            {
                request.BodyBuffer = new RpcBodyBuffer <TArgs>(args);
            }

            RpcClientTransaction trans;

            if (isBatch)
            {
                _perfCounters.BatchPerSec.Increment();
                _perfCounters.BatchTotal.Increment();
                _perfCounters.BatchConcurrent.Increment();

                trans = method.BatchManager.CreateTransaction(_conn.RemoteUri, request);
            }
            else
            {
                _perfCounters.InvokeTotal.Increment();
                _perfCounters.InvokePerSec.Increment();
                _perfCounters.ConcurrentContext.Increment();

                trans = _conn.CreateTransaction(request);
            }

            RpcClientContext ctx = new RpcClientContext(trans);

            ctx.SendRequest(
                delegate(long ticks, RpcClientContext cx2, bool successed) {
                if (isBatch)
                {
                    _perfCounters.BatchConcurrent.Decrement();
                }
                else
                {
                    _perfCounters.ConcurrentContext.Decrement();
                }
                _perfCounters.AvgInvokeElapseMs.IncrementBy(ticks / FrequencyHelper.TicksPerMs);

                if (!successed)
                {
                    _perfCounters.InvokeFailed.Increment();
                }

                try {
                    callback(cx2);
                } catch (Exception ex) {
                    _tracing.Error(ex, "BeginInvoke.Calblack Failed");
                }
            },
                _timeout
                );
        }