Пример #1
0
        private Util.SchedulerTask Schedule(Service service, long sessionId, int millisecondsTimeout)
        {
            return(global::Zeze.Util.Scheduler.Instance.Schedule(
                       (ThisTask) =>
            {
                Rpc <TArgument, TResult> context = service.RemoveRpcContext <Rpc <TArgument, TResult> >(sessionId);
                if (null == context)     // 一般来说,此时结果已经返回。
                {
                    return;
                }

                context.IsTimeout = true;
                context.ResultCode = Zeze.Transaction.Procedure.Timeout;

                if (null != context.Future)
                {
                    context.Future.TrySetException(new RpcTimeoutException());
                }
                else
                {
                    this.ResponseHandle?.Invoke(context);
                }
            },
                       millisecondsTimeout,
                       -1));
        }
Пример #2
0
        /// <summary>
        /// 异步发送rpc请求。
        /// 1. 如果返回true,表示请求已经发送,并且建立好了上下文。
        /// 2. 如果返回false,请求没有发送成功,上下文也没有保留。
        /// </summary>
        /// <param name="so"></param>
        /// <param name="responseHandle"></param>
        /// <param name="millisecondsTimeout"></param>
        /// <returns></returns>
        public bool Send(AsyncSocket so,
                         Func <Protocol, int> responseHandle,
                         int millisecondsTimeout = 5000)
        {
            if (so == null || so.Service == null)
            {
                return(false);
            }

            this.IsRequest      = true;
            this.ResponseHandle = responseHandle;
            this.Timeout        = millisecondsTimeout;
            this.SessionId      = so.Service.AddRpcContext(this);
            if (base.UniqueRequestId == 0)
            {
                base.UniqueRequestId = this.SessionId;
            }
            var timeoutTask = Schedule(so.Service, SessionId, millisecondsTimeout);

            if (base.Send(so))
            {
                return(true);
            }

            // 发送失败,一般是连接失效,此时删除上下文。
            // 其中rpc-trigger-result的原子性由RemoveRpcContext保证。
            // Cancel不是必要的。
            timeoutTask.Cancel();
            // 【注意】当上下文已经其他并发过程删除(得到了处理),那么这里就返回成功。
            // see OnSocketDisposed
            // 这里返回 false 表示真的没有发送成功,外面根据自己需要决定是否重连并再次发送。
            Rpc <TArgument, TResult> context = so.Service.RemoveRpcContext <Rpc <TArgument, TResult> >(this.SessionId);

            return(context == null);
        }
Пример #3
0
        internal override void Dispatch(Service service, Service.ProtocolFactoryHandle factoryHandle)
        {
            if (IsRequest)
            {
                service.DispatchProtocol(this, factoryHandle);
                return;
            }

            // response, 从上下文中查找原来发送的rpc对象,并派发该对象。
            Rpc <TArgument, TResult> context = service.RemoveRpcContext <Rpc <TArgument, TResult> >(SessionId);

            if (null == context)
            {
                logger.Info("rpc response: lost context, maybe timeout. {0}", this);
                return;
            }

            context.IsRequest  = false;
            context.Result     = Result;
            context.Sender     = Sender;
            context.ResultCode = ResultCode;
            context.UserState  = UserState;

            if (context.Future != null)
            {
                context.Future.SetResult(context.Result);
                return;                // SendForWait,设置结果唤醒等待者。
            }
            context.IsTimeout = false; // not need
            if (null != context.ResponseHandle)
            {
                service.DispatchRpcResponse(context, context.ResponseHandle, factoryHandle);
            }
        }