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; })); }
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; })); } }