예제 #1
0
        private Task <DataArgs <ViaElement> > RequestAsync <T>(string serviceName, string exchangeType, string queryName, DataArgs <T> queryData, string responceHandlerName, string responseHandlerData, Action <string> callback, MessageEntryParam parameters)
        {
            var responseResolve = parameters?.NeedResponseResolve ?? false;

            //TODO: подумать ExchangeTypes.EXCHANGETYPE_DIRECT для responceHandlers?
            var responseKind = callback == null ? ExchangeTypes.EXCHANGETYPE_FANOUT : ExchangeTypes.EXCHANGETYPE_DIRECT;

            var replayTo      = responseResolve ? Dispatcher.SelfServiceName : Dispatcher.GetConnectionByExchangeType(responseKind);
            var queryDataJson = queryData.ToJson();

            //записываем  текущее состояние запроса
            var currentViaElement = new ViaElement()
            {
                replyTo             = replayTo,
                mqWorkKind          = responseKind,
                messageId           = Guid.NewGuid().ToString(),
                queryHandlerName    = queryName,
                appId               = Dispatcher.AppId,
                priority            = parameters?.Priority ?? 0,
                doResolve           = responseResolve,
                responseHandlerName = responceHandlerName,
                responseHandlerData = responseHandlerData
            };

            this._via.queue.Push(currentViaElement);

            var properties = Dispatcher.Connection.CreateChannelProperties();

            properties.CorrelationId = ReceivedMessage?.Properties?.CorrelationId ?? parameters?.TransactionId ?? Guid.NewGuid().ToString();
            properties.ContentType   = currentViaElement.queryHandlerName;
            properties.MessageId     = currentViaElement.messageId;
            properties.ReplyTo       = currentViaElement.replyTo;
            properties.Priority      = currentViaElement.priority == 0 ? (byte)1 : currentViaElement.priority;
            properties.Headers       = new Dictionary <string, object>();
            properties.Headers.TryAdd(MessageBasicPropertiesHeaders.VIA, this._via.ToJson());
            properties.Headers.TryAdd(MessageBasicPropertiesHeaders.DIRECTION, MessageBasicPropertiesHeaders.DIRECTION_VALUE_REQUEST);
            properties.Headers.TryAdd(MessageBasicPropertiesHeaders.WORKKIND, responseKind);
            properties.Headers.TryAdd(MessageBasicPropertiesHeaders.WORKKIND_TYPE, MessageBasicPropertiesHeaders.WORKKIND_TYPE_VALUE);
            properties.Headers.TryAdd(MessageBasicPropertiesHeaders.VIA_TYPE, MessageBasicPropertiesHeaders.VIA_TYPE_VALUE);

            exchangeType = ExchangeTypes.Get(exchangeType);

            var link = LinkTypes.GetLinkByExchangeType(exchangeType);

            var routingKey = string.Empty;

            if (exchangeType == ExchangeTypes.EXCHANGETYPE_FANOUT)
            {
                routingKey = serviceName;
            }
            else if (responseKind == ExchangeTypes.EXCHANGETYPE_DIRECT)
            {
                routingKey = parameters?.AppId;
                if (string.IsNullOrEmpty(routingKey))
                {
                    throw new CoreException("Relation [Direct to Direct] - AppId must be initialized");
                }
            }

            var exchangeName = exchangeType == ExchangeTypes.EXCHANGETYPE_FANOUT ? "" : serviceName;

            return(Push(currentViaElement, parameters?.NeedRequestResolve ?? true, link, serviceName, exchangeName, routingKey, exchangeType, queryDataJson, properties)
                   .ContinueWith((result) =>
            {
                if (callback != null)
                {
                    if (result.Exception != null)
                    {
                        callback(new DataArgs <object>(result.Exception).ToJson());
                    }
                    else
                    {
                        Dispatcher.DeclareResponseCallback(currentViaElement.messageId, callback, parameters?.Timeout);
                    }
                }
                return result.Result;
            }));
        }
예제 #2
0
        private Task <DataArgs <ViaElement> > Push(ViaElement via, bool requestResolve, string link, string service, string exchangeName, string routingKey, string exchangeType, string queryData, IBasicProperties properties)
        {
            DataArgs <ViaElement> messageEventArgs = new DataArgs <ViaElement>();

            if (requestResolve)
            {
                //Для начала надо узнать в какие очереди посылать запросы
                return(this.Dispatcher.Resolve(service, link)
                       .ContinueWith(resolver_link =>
                {
                    //try
                    //{
                    if (resolver_link.Exception != null)
                    {
                        messageEventArgs.SetException(resolver_link.Exception);
                    }
                    var link_str = resolver_link.Result;
                    var exchange = ExchangeTypes.GetExchangeName(link_str, null, exchangeType);
                    bool isFanout = ExchangeType.Fanout.Equals(exchangeType, StringComparison.CurrentCultureIgnoreCase);

                    var rk = isFanout ? exchange : routingKey;

                    var options = new ProducerParam()
                    {
                        RoutingKey = rk
                    };

                    if (!isFanout)
                    {
                        options.ExchangeParam = new ChannelExchangeParam()
                        {
                            Name = exchange,
                            Type = exchangeType ?? ExchangeTypes.EXCHANGETYPE_FANOUT
                        };
                    }

                    var data = Encoding.UTF8.GetBytes(queryData);
                    //посылаем сообщение
                    Dispatcher.Connection.Publish(options, data, properties);
                    messageEventArgs.result = true;
                    messageEventArgs.data = via;
                    //}
                    //catch (Exception ex)
                    //{
                    //    messageEventArgs.SetException(ex);
                    //}
                    return messageEventArgs;
                }));
            }
            else
            {
                return(Task.Run(() =>
                {
                    //try
                    //{
                    //для запросов, где очереди известны
                    var options = new ProducerParam()
                    {
                        RoutingKey = routingKey
                    };
                    if (!string.IsNullOrEmpty(exchangeName))
                    {
                        options.ExchangeParam = new ChannelExchangeParam()
                        {
                            Name = exchangeName,
                            Type = exchangeType ?? ExchangeTypes.EXCHANGETYPE_FANOUT
                        };
                    }

                    var data = Encoding.UTF8.GetBytes(queryData);
                    //посылаем сообщение
                    Dispatcher.Connection.Publish(options, data, properties);
                    //}
                    //catch (Exception ex)
                    //{
                    //    messageEventArgs.result = false;
                    //    messageEventArgs.SetException(ex);
                    //}
                    return messageEventArgs;
                }));
            }
        }