/// <summary> /// Отправка запроса на канал. Если канал "упал", выбирается следующий доступный /// </summary> /// <param name="currentChannel">Канал, по которому надо отправить запрос</param> /// <param name="request">Экземпляр заполненного запроса</param> /// <param name="tpe">Запрашиваемый заголовок запроса (нужен, если канал упал)</param> /// <returns>Экземпляр HttpResponseMessage</returns> private HttpResponseMessage GetResult(WebHostCacheChannel currentChannel, WebHostCacheRequest request, ContentTypes tpe = ContentTypes.xml) { try { // Добавляем в список запрос и обновляем значение коэффициента нагрузки currentChannel.RequestsList.Add(request); Task <HttpResponseMessage> response = currentChannel.Client.SendAsync(request); HttpResponseMessage result = response.Result; result.EnsureSuccessStatusCode(); currentChannel.ReqSended++; return(result); } catch (Exception ee) { // Канал не доступен, выбираем другой менее нагруженный, но не этот WebHostCacheChannel nextCannel = GetLessLoadedEndPoint(request.UsedChannels); request.UsedChannels.Add(nextCannel); WebHostCacheRequest newRequest = new WebHostCacheRequest(nextCannel, request.RequestUri.AbsolutePath, request.UsedChannels, request.Content == null ? null : request.Content.ReadAsAsync <XElement>().Result, tpe); return(GetResult(nextCannel, newRequest)); } finally { // Пришёл ответ или была ошибка, удаляем запрос из списка и обновляем значение коэффициента нагрузки currentChannel.RequestsList.Remove(request); } }
public byte[] GetResponseBinary(string uri, XElement PostBody = null) { WebHostCacheChannel channel = GetLessLoadedEndPoint(); List <WebHostCacheChannel> UsedChannels = new List <WebHostCacheChannel>() { channel }; WebHostCacheRequest request = new WebHostCacheRequest(channel, uri, UsedChannels, PostBody, ContentTypes.binary); HttpResponseMessage response = GetResult(channel, request, ContentTypes.binary); return(response.Content.ReadAsByteArrayAsync().Result); }
/// <summary> /// "Helper" - получение типизированного результата. /// </summary> /// <typeparam name="TResult">Тип</typeparam> /// <param name="tpe">Запрашиваемый заголовок запроса</param> /// <param name="uri">uri запроса</param> /// <returns>Возвращаемое значение</returns> public TResult GetResponse <TResult>(string uri, XElement PostBody = null, ContentTypes tpe = ContentTypes.xml) { // WebHostCacheChannel channel = this.ZoneChannelsList[0];//GetLessLoadedEndPoint(); // WebHostCacheChannel channel = GetLessLoadedEndPoint(); // Проверяем наличие в запросе ключа сессии string sessionKey = ExtractSessionKey(uri, PostBody); if (String.IsNullOrEmpty(sessionKey)) { throw new ArgumentException("Направляемый запрос не содержит ключ сессии"); } // Обеспечиваем привязку клиенту SignalR ResponseHubClient client = ResponseHubClientRepository.GetClient(sessionKey); var waitHandler = new System.Threading.AutoResetEvent(false); var requestId = RequestID; // Получаем очередной ID для запроса в локальную копию client.WaitHandlers.Add(requestId, waitHandler); AttachIdToRequest(ref uri, PostBody, requestId); // Формируем запрос WebHostCacheChannel channel = GetLessLoadedEndPoint(); List <WebHostCacheChannel> UsedChannels = new List <WebHostCacheChannel>() { channel }; WebHostCacheRequest request = new WebHostCacheRequest(channel, uri, UsedChannels, PostBody, tpe); try { // Отправляем запрос HttpResponseMessage response = GetResult(channel, request, tpe); // Получаем результаты waitHandler.WaitOne(); var retValue = client.RequestResults[requestId]; return((TResult)retValue); } finally { // Завершаем обработку запроса client.WaitHandlers[requestId].Dispose(); client.WaitHandlers.Remove(requestId); client.RequestResults.Remove(requestId); } }