Https звонки не подключаются к серверу - PullRequest
3 голосов
/ 04 марта 2020

Я работаю над Windows Service в visual studio 2017. В остальном вызов API, получение исключений при отладке кода. Иногда первые 2 3 вызова, работающие после этого, получают исключения.

Система. Net .WebException: 'Удаленный сервер возвратил ошибку: (503) Сервер недоступен.'

удаленный сервер возвратил ошибку: (429)

Невозможно подключиться к удаленному серверу

При вызове того же API-интерфейса из Почтальона, получение ответа успешно.

Это мой код

private void timer1_Tick(object sender, ElapsedEventArgs e)
{
    WriteToFile("timer1_Tick method called..");
try
{
    string jsonString = "";
    string jsonstring2 = "";
    string prodfetchurl = HOST;
    var req = WebRequest.Create(prodfetchurl) as HttpWebRequest;
    req.Method = "GET";
    InitializeRequest(req);
    req.Accept = MIME_TYPE;
    //System.Threading.Thread.Sleep(5000);
    var response = (HttpWebResponse)req.GetResponse();
    WriteToFile("First service called...");
    if (response.StatusCode == HttpStatusCode.OK)
    {
        Stream responseStream = response.GetResponseStream();
        StreamReader responseReader = new StreamReader(responseStream);
        jsonString = responseReader.ReadToEnd();
    }
    var deserialsseobj = JsonConvert.DeserializeObject<ProductList>(jsonString).Products.Where(i => i.Failed > 0).ToList();
    foreach (var a in deserialsseobj)
    {
        var pid = a.ID;
        string url = FailedDevicesUrl + pid.Value + "/failed";
        var req2 = WebRequest.Create(url) as HttpWebRequest;
        req2.Method = "GET";
        InitializeRequest(req2);

        req2.Timeout = 300000;
        req2.Accept = MIME_TYPE;
        var response1 = (HttpWebResponse)req2.GetResponse();
        Stream responsestream2 = response1.GetResponseStream();
        WriteToFile("Second service called...");
        if (response1.StatusCode == HttpStatusCode.OK)
        {
            StreamReader responsereader1 = new StreamReader(responsestream2);
            jsonstring2 = responsereader1.ReadToEnd();
        }

        var output = JsonConvert.DeserializeObject<List<FailedDeviceList>>(jsonstring2);  // Will get List of the Failed devices
        List<int> deviceids = new List<int>();
        Reprocessdata reproc = new Reprocessdata();
        Reprocessdata.DeviceId rprod = new Reprocessdata.DeviceId();

        reproc.ForceFlag = true;
        reproc.ProductID = pid.Value;
        foreach (var dd in output)
        {
            rprod.ID = dd.DeviceId;
            reproc.DeviceIds.Add(rprod);
        }

        // Reprocess the Product in Devices
        var req3 = WebRequest.Create(ReprocessUrl) as HttpWebRequest;
        req3.Method = "POST";
        InitializeRequest(req3);
        req3.Accept = MIME_TYPE;
        req3.Timeout = 300000;
        req3.ContentType = "application/json";
        using (StreamWriter writer = new StreamWriter(req3.GetRequestStream()))
        {
            string json = new JavaScriptSerializer().Serialize(reproc);

            writer.Write(json);
            writer.Close();
        }
        System.Threading.Thread.Sleep(5000);
        var response5 = (HttpWebResponse)req3.GetResponse();
        WriteToFile("Third service called...");
        if (response5.StatusCode == HttpStatusCode.OK)
        {
            string result;
            using (StreamReader rdr = new StreamReader(response5.GetResponseStream()))
            {
                result = rdr.ReadToEnd();
            }
        }
    }
    response.Close();
}
catch (Exception ex)
{
    WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);
}
}

Методы, использованные в приведенном выше коде

protected override void OnStart(string[] args)
{
    base.OnStart(args);
    timer1 = new System.Timers.Timer();
    timer1.Interval = 60000; //every 1 min
    timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick);
    timer1.Enabled = true;
    WriteToFile("Service has started..");
}

public void InitializeRequest(HttpWebRequest request)
{
    request.Headers.Add("aw-tenant-code", API_TENANT_CODE);
    request.Credentials = new NetworkCredential(USER_NAME, PASSWORD);
    request.KeepAlive = false;
    request.AddRange(1024);
}

Когда я связался со службой, они сказали, что все в порядке с той стороны. Это мой код глючит или windows служба не надежна? Как я могу решить эту проблему?

Примечание. Все APIS работают нормально из приложения Angular с использованием кода Visual Studio. Это означает, что мой код не работает.

Edit1: Три службы ниже, я использую с этот документ VMware.

private const string HOST = "https:host/api/mdm/products/search?";
private const string FailedDevicesUrl = "https:host/api/mdm/products/";
private const string ReprocessUrl = "https:host/api/mdm/products/reprocessProduct";

Ответы [ 2 ]

4 голосов
/ 18 марта 2020

HTTP-код ответа 429 указывает, что вы отправляете слишком много запросов на целевой веб-сервис.

Это означает, что служба, пытающаяся отправить запросы, имеет политики, блокирующие некоторые запросы по запросу -time limit.

Также я допускаю, что внешнюю службу можно настроить вручную для выдачи кода 403 в конкретном c случаях, о которых вы не можете знать. Если это так, эта информация может быть объяснена во внешней сервисной документации ... или нет:)

Что вы можете с этим сделать?

Вписать ограничения
Вы можете провести подробное исследование того, что ограничивает целевой веб-сервис, и настроить свой код, чтобы он соответствовал этим ограничениям. Например, если у службы есть ограничение на прием только одного запроса в 10 минут - вы должны настроить таймер на отправку одного запроса каждые 10 или более минут. Если в документации нет такой информации - вы можете проверить ее вручную, найдя некоторые шаблоны с ответами внешних служб.

Использовать прокси
Каждая политика ограничений основана на информации об отправителях запросов. Обычно эта информация состоит только из IP-адреса отправителя. Это означает, что если вы отправляете 2 запроса с двух разных IP-адресов - политика ограничения будет воспринимать это как 2 разных компьютера, отправляющих эти запросы. Таким образом, вы можете найти / купить / арендовать некоторые прокси-IP-адреса и отправить туда запросы на целевом веб-сервере.

Как подключиться через прокси в C#, используя WebRequest, вы можете увидеть в this ответ.

Переговоры с внешним поставщиком услуг
Если у вас есть возможность общаться с внешними разработчиками услуг или справочным центром, вы можете попросить их уменьшить ограничения для вашего IP-адреса ( если он установлен c) или предоставить некоторые механизмы, позволяющие избежать политики ограничения для вас. Если по какой-то причине они не могут предоставить такую ​​возможность, по крайней мере, вы можете запросить подробную информацию об ограничениях.

Механизм повторения
Иногда 503 код ошибки, который Внешнее исключение, которое вы получили, может быть вызвано недоступностью услуги. Это означает, что сервер может быть на обслуживании или временно перегружен. Таким образом, вы можете написать механизм повторения для непрерывной отправки запросов на сервер до тех пор, пока он не станет доступным.

Polly Библиотека может помочь вам с созданием механизма повторения

3 голосов
/ 18 марта 2020

Внутренняя ошибка этого 503:

Удаленный сервер возвратил ошибку: (429)

HTTP 429 указывает на слишком много запросов. Возможно, ваш вышестоящий сервер не может обработать все отправленные запросы.

Это может произойти, когда вы достигли значения ограничения / регулирования скорости, если вы вызываете сторонний API.

ОБНОВЛЕНИЕ

Согласно странице 28 в документах API, вы можете настроить регулирование при создании нового API. Проверьте, не является ли регулирование слишком маленьким или, возможно, отключите регулирование и посмотрите, может ли это исправить ошибку?

enter image description here

...