private async Task <IResponseMessage> GetResponseFromExecution(PostUrlParameters urlParameters, string key)
        {
            var executionTask = _executionDictionary.Get(key, false);

            if (executionTask != null)
            {
                return(await executionTask.ConfigureAwait(false));
            }

            return(null);
        }
        public async Task <string> ProcessMessage(PostUrlParameters urlParameters, Stream requestStream)
        {
            var requestMessage = BuildRequest(urlParameters, requestStream);

            var key = requestMessage.GetDuplicationKey();

            // 如果是正在处理中的重复消息, 则返回等待处理完成返回处理结果
            var responseText = await GetResponseFromExecution(urlParameters, key).ConfigureAwait(false);

            if (responseText != null)
            {
                OnResponseGenerated(responseText, ResponseSource.Executing);
                return(responseText);
            }

            // 如果是已处理的重复消息, 则直接返回待处理结果
            responseText = await GetResponseFromCache(key);

            if (responseText != null)
            {
                OnResponseGenerated(responseText, ResponseSource.Cache);
                return(responseText);
            }

            var handler = CreateHandler();
            var task    = handler.Handle(requestMessage);

            // 开始处理后, 保存正在处理的消息
            var done = task.IsCompleted;

            if (!done)
            {
                _executionDictionary.Add(key, task);
            }

            var responseMessage = await task.ConfigureAwait(false);

            responseText = SerializeResponse(urlParameters, responseMessage);

            // 处理完成后, 从正在处理转移到处理完成
            await _responseCache.Add(key, responseText).ConfigureAwait(false);

            if (!done)
            {
                _executionDictionary.Remove(key);
            }

            OnResponseGenerated(responseText, ResponseSource.New);
            return(responseText);
        }
        private string EncryptResponse(PostUrlParameters urlParameters, string responseText)
        {
            var outputData = responseText;

            if (_cryptor != null)
            {
                var encryptResult = _cryptor.EncryptMsg(responseText, urlParameters.timestamp, urlParameters.nonce, ref outputData);
                if (encryptResult != WXBizMsgCrypt.WXBizMsgCryptErrorCode.WXBizMsgCrypt_OK)
                {
                    throw new MessageException($"加密失败: {encryptResult}");
                }
            }

            return(outputData);
        }
        private RequestMessage BuildRequest(PostUrlParameters urlParameters, Stream requestStream)
        {
            var inputData = new StreamReader(requestStream, Encoding.UTF8).ReadToEnd();
            var request   = inputData;

            if (_cryptor != null)
            {
                var decryptResult = _cryptor.DecryptMsg(urlParameters.msg_signature, urlParameters.timestamp, urlParameters.nonce, inputData, ref request);
                if (decryptResult != WXBizMsgCrypt.WXBizMsgCryptErrorCode.WXBizMsgCrypt_OK)
                {
                    throw new MessageException($"解密失败: {decryptResult}");
                }
            }

            OnRequestRead(request);

            return(RequestMessage.Parse(request));
        }
        private string SerializeResponse(PostUrlParameters urlParameters, IResponseMessage responseMessage)
        {
            var response = responseMessage.Serialize();

            if (!responseMessage.EncryptionRequired)
            {
                return(response);
            }

            var outputData = response;

            if (_cryptor != null)
            {
                var encryptResult = _cryptor.EncryptMsg(response, urlParameters.timestamp, urlParameters.nonce, ref outputData);
                if (encryptResult != WXBizMsgCrypt.WXBizMsgCryptErrorCode.WXBizMsgCrypt_OK)
                {
                    throw new MessageException($"加密失败: {encryptResult}");
                }
            }

            return(outputData);
        }
Beispiel #6
0
        public async Task <string> ProcessMessage(PostUrlParameters urlParameters, Stream requestStream)
        {
            var requestMessage = BuildRequest(urlParameters, requestStream);

            var key = requestMessage.GetDuplicationKey();

            ResponseSource source;

            // 如果是正在处理中的重复消息, 则返回等待处理完成返回处理结果
            var responseMessage = await GetResponseFromExecution(urlParameters, key).ConfigureAwait(false);

            if (responseMessage != null)
            {
                source = ResponseSource.Executing;
            }
            else
            {
                // 如果是已处理的重复消息, 则直接返回待处理结果
                responseMessage = await GetResponseFromCache(key).ConfigureAwait(false);

                if (responseMessage != null)
                {
                    source = ResponseSource.Cache;
                }
                else
                {
                    var  handler = CreateHandler();
                    bool done    = false;
                    try
                    {
                        var task = handler.Handle(requestMessage);

                        // 开始处理后, 保存正在处理的消息
                        done = task.IsCompleted;
                        if (!done)
                        {
                            _executionDictionary.Add(key, task);
                        }

                        responseMessage = await task.ConfigureAwait(false);
                    }
                    finally
                    {
                        if (handler is IDisposable d)
                        {
                            d.Dispose();
                        }
                    }

                    // 处理完成后, 从正在处理转移到处理完成
                    await _responseCache.Add(key, responseMessage).ConfigureAwait(false);

                    if (!done)
                    {
                        _executionDictionary.Remove(key);
                    }

                    source = ResponseSource.New;
                }
            }

            var responseText = responseMessage.Serialize();

            OnResponseGenerated(responseText, source);

            if (responseMessage.EncryptionRequired)
            {
                responseText = EncryptResponse(urlParameters, responseText);
            }

            return(responseText);
        }