示例#1
0
        private async Task <ActionExecutingContext> GetContext()
        {
            var onceCallParam = await _convert.GetServiceOnceCallParamAsync();

            var(instanceMethodInfo, contractMethod, instance) = ApiWrapper.GetMethodInfo(onceCallParam.Action, _instances);

            //get parameters
            var parameters = contractMethod.MethodInfo.GetParameters();

            //callback, cancel when exception
            async Task Callback(object?i)
            {
                try
                {
                    if (!_serviceCts.IsCancellationRequested)
                    {
                        await _convert.SendCallbackAsync(i);
                    }
                    else
                    {
                        _logger.LogWarning("Call back ignored, action is canceled.");
                    }
                }
                catch (Exception e)
                {
                    _logger.LogWarning(e, "Callback error, cancel action.");
                    _serviceCts.Cancel();
                    throw;
                }
            }

            //args
            var args = ApiWrapper.GetArgs(parameters, onceCallParam.PureArgs, Callback, _serviceCts.Token, onceCallParam.Stream);

            return(new ActionExecutingContext(
                       _serviceProvider,
                       onceCallParam.Header,
                       instance,
                       instanceMethodInfo,
                       contractMethod,
                       args,
                       onceCallParam.PureArgs,
                       onceCallParam.Action,
                       onceCallParam.Stream,
                       instance.Contract,
                       _channelType,
                       Callback,
                       _serviceCts.Token));
        }
        public async Task HandleRequestAsync()
        {
            ServiceCallParam scp = await GetServiceCallParamAsync();

            object ret;

            try
            {
                var apiContext = ApiWrapper.Convert(scp, _instances);
                ret = await _middlewareRegister.InvokeAsync(new MiddlewareContext(apiContext));
            }
            catch (Exception e)
            {
                //send fault
                await _convert.SendFaultAsync(e, scp.Action, scp.Args);

                return;
            }

            var hasStream = ret.TryGetStream(out Stream retStream);

            //send result
            await _convert.SendResultAsync(new CustomResult(ret, retStream.GetLength()), scp.Action, scp.Args);

            //send stream
            if (hasStream)
            {
                try
                {
                    await Helper.SendStreamAsync(i => _convert.SendBufferAsync(i), () =>
                                                 _convert.SendBufferEndAsync(), retStream, scp.Token);
                }
                catch (TaskCanceledException)
                {
                    await _convert.SendBufferCancelAsync();
                }
                catch (Exception)
                {
                    await _convert.SendBufferFaultAsync();
                }
            }
        }