#vb.net #exchange-server #webrequest #betfair
#vb.net #exchange-сервер #webrequest #betfair
Вопрос:
Некоторое время назад я написал программу в VB.NET чтобы использовать API биржи Betfair. Он работал отлично в течение нескольких месяцев, но ночью во вторник он перестал работать. Я все еще могу войти в систему, но со среды я не смог получить что-либо еще с сервера.
Betfair проводит расследование, но, по их словам, больше никто, похоже, не сталкивается с такой же проблемой, хотя я не уверен, сколько из них будут использовать VB.NET .
Ниже приведена функция, которую я использовал для получения данных из API. Как я уже сказал, он работал во вторник вечером, но не с утра среды. Есть ли здесь что-нибудь, что «не идеально» или «могло бы быть лучше», или, возможно, есть какой-то альтернативный код, который я мог бы попробовать? Или на моем компьютере могло произойти что-то, что вызвало проблему?
Программа завершает работу на строке «dataStream = request.GetRequestStream () «. Ошибка «Получено неожиданное значение EOF или 0 байт из транспортного потока».
Я был бы благодарен за любой совет, который кто-либо может предложить. Спасибо!
Public Function CreateRequest(ByVal postData As String, Optional ByVal accountsApi As Boolean = False)
Dim Url As String = "https://api.betfair.com/exchange/betting/json-rpc/v1"
If accountsApi Then Url = "https://api.betfair.com/exchange/account/json-rpc/v1"
Dim request As WebRequest = Nothing
Dim dataStream As Stream = Nothing
Dim response As WebResponse = Nothing
Dim strResponseStatus As String = ""
Dim reader As StreamReader = Nothing
Dim responseFromServer As String = ""
Try
request = WebRequest.Create(New Uri(Url))
request.Method = "POST"
request.ContentType = "application/json-rpc"
request.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8")
request.Headers.Add("X-Application", appKey)
request.Headers.Add("X-Authentication", sessToken)
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData) ' Data to post such as ListEvents, ListMarketCatalogue etc
request.ContentLength = byteArray.Length ' Set the ContentLength property of the WebRequest.
dataStream = request.GetRequestStream() ' Get the request stream.
dataStream.Write(byteArray, 0, byteArray.Length) ' Write the data to the request stream.
dataStream.Close() ' Close the Stream object.
response = request.GetResponse() ' Get the response.
strResponseStatus = CType(response, HttpWebResponse).StatusDescription ' Display the status below if required
dataStream = response.GetResponseStream() ' Get the stream containing content returned by the server.
reader = New StreamReader(dataStream) ' Open the stream using a StreamReader for easy access.
responseFromServer = reader.ReadToEnd() ' Read the content.
reader.Close() : dataStream.Close() : response.Close()
Catch ex As Exception
MsgBox("CreateRequest Error" amp; vbCrLf amp; ex.Message, MsgBoxStyle.Critical, " Error")
End Try
Return responseFromServer
End Function
Комментарии:
1. Я бы получил все, что можно поместить в оператор using. Есть ли что-нибудь в вашей среде, что может блокировать связь? Защита от вирусов и т. Д. Происходит ли сбой вашего решения на всех рабочих станциях в вашей среде?
2. Если вы используете Windows 7 / Windows Server 2008 R2, вы должны установить
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
явно перед созданием любого соединения. Также обратите внимание, что сервер при обновлении до TSL12 может вводить наборы шифров, которые недоступны в Windows 7 / Windows Server 2008 R2 (последние шифры — поскольку срок службы обеих этих систем истек, их наборы шифров никогда не получат обновление Windows). Не имеет значения, может ли веб-браузер или Postman запрашивать API, поскольку они несут (и обрабатывают) эти наборы шифров вместе с ними.3. Добавление строки Tls12 сразу устранило проблему! Однако я внесу изменения в код, как было предложено, когда у меня будет время. Спасибо всем за вашу помощь!
Ответ №1:
Я бы проверил, не устарел ли провайдер в последнее время от использования TLS 1.0 (как, на самом деле, они должны были сделать раньше).
Если это так, ваш код должен принудительно использовать TLS 1.1 :
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
Это должно быть установлено только один раз, обычно в (статическом) инициализаторе типа или аналогичном.
И я на 100% согласен с Эндрю Мортимером в том, что вы должны использовать Using
блоки везде, где это возможно. Я бы также предложил переместить все ваши строковые значения в переменные или константы, чтобы очистить вещи и поддерживать их в рабочем состоянии. Например:
Const ContentType As String = "application/json-rpc"
...
request.ContentType = ContentType
Обновить
Я только что нашел это объявление на их сайте:
Комментарии:
1. В этом объявлении говорится: «С 1 декабря будет поддерживаться только TLS 1.2 и выше». так что это может быть
SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13
и вместо этого.2. @AndrewMorton В данном конкретном случае, да.
Ответ №2:
Если вам разрешено использовать внешние зависимости в этом проекте, я бы рекомендовал использовать пакет RestSharp nuget, он действительно хорошо работает для создания запросов API и получения ответа без необходимости использовать httpclient, что приводит к беспорядку.
Ссылка: https://restsharp.dev /