2016-03-10 5 views
0

У меня есть следующий код подключения:Принудительный асинхронный WebRequest для очистки его буфера C#

_request = (HttpWebRequest)WebRequest.Create(complianceUrl); 
_request.Method = "GET"; 

var authInfo = string.Format("{0}:{1}", _username, _password); 
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo)); 
_request.Headers.Add("Authorization", "Basic " + authInfo); 

// set stream parameters 
_request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; 
_request.Headers.Add("Accept-Encoding", "gzip"); 
_request.Accept = "application/json"; 
_request.ContentType = "application/json"; 
_request.ReadWriteTimeout = 30000; 
_request.AllowReadStreamBuffering = false; 

_request.Timeout = 30; //seconds, sends 15-second heartbeat. 
_asyncCallback = HandleResult; //Setting handleResult as Callback method... 
_request.BeginGetResponse(_asyncCallback, _request); //Calling BeginGetResponse on 

Это прекрасно работает, и буфер заполняется данными, и в то время как у меня есть большие объемы данных, это хорошо. Но с небольшими объемами данных для заполнения буфера требуется некоторое время, и я хочу периодически очищать буфер, если у меня не было активности за какое-то время.

Я пытался сделать это таким образом:

_request.GetRequestStream().FlushAsync(); 

Но это не так, как он говорит мне, что я вызывает ProtocolViolationException я думаю, как это GET Глагол?

Может ли кто-нибудь сказать мне, как принудительно заставить соединение сбросить буфер клиенту?

Handling код ответа добавил:

private void HandleResult(IAsyncResult result) 
{ 
    using (var response = (HttpWebResponse) _request.EndGetResponse(result)) 
    using (var stream = response.GetResponseStream()) 
    using (var memory = new MemoryStream()) 
    { 
     var compressedBuffer = new byte[BlockSize]; 

     while (stream != null && stream.CanRead) 
     { 
      var readCount = stream.Read(compressedBuffer, 0, compressedBuffer.Length); 

      // if readCount is 0, then the stream must have disconnected. Process and abort! 
      if (readCount == 0) 
      { 

      } 
     } 
    } 
} 
+0

Что буфер вы говорите? Я не вижу здесь никакого кода для чтения или написания. – usr

+0

Добавлен код для обработки буфера, но это асинхронно, поэтому он ждет, пока буфер не будет заполнен на стороне сервера, а затем отправит лот. Мне нужно принудительно отключить соединение. – jimplode

+0

В чем проблема? Этот код выглядит отлично. Он истощает поток и правильно определяет, когда поток исчерпан (readCount == 0). Вы делаете какой-то длинный опрос или медленный поток по HTTP? – usr

ответ

0

Это не возможно сделать на стороне сервера вызова HTTP отправить вам данные определенным образом. Ни для протокола HTTP, ни для TCP нет. Вы должны взять то, что получаете, или поговорить с продавцом.

Read не блокируется до тех пор, пока буфер не будет заполнен. Это дает вам то, что прибывает немедленно. Такое поведение хорошо известно, это не моя догадка.

Служба сторонних организаций отправляет 15 секундные биты CRLF, которые также в конечном итоге заполнят буфер.

Звучит так, как будто сервис делает то, что вы хотите. Если это так, проблема должна быть в вашем коде. Но не в коде, указанном в вопросе. Попробуйте следующее:

while (true) 
    { 
     var readCount = stream.Read(compressedBuffer, 0, compressedBuffer.Length); 
     Console.WriteLine(readCount); 
    } 

Это должно показывать 2 байта каждые 15 секунд. Если нет, поставщик виноват. Если да, то есть.

while (stream != null && stream.CanRead) Это странно, потому что ни одно из этих условий не может стать ложным. И даже если они становятся фальшивыми, что вы делаете? Это должно быть while (true) плюс break по истощению потока.

// if readCount is 0, then the stream must have disconnected. 

Это условие означает, что удаленная сторона упорядочила свою отправку HTTP-ответа.

+0

Я добавил этот код, и я сделал свой буфер размером 10 байт. 15:48:17 READ: 10BYTES 15:49:32 READ: 10BYTES Если они посылают CRLF каждые 15 секунд, я должен получить больше читает, как вы предлагаете, я получаю данные, когда буфер заполнен – jimplode

+0

Исследуя это сейчас ... – usr

+0

Спасибо, я очень ценю вашу помощь в этом. То, что я пытаюсь сделать, должно быть легким, я чувствую, что это имеет какое-то отношение к асинхронному соединению. – jimplode

0

Для тех, кто заинтересован, вы можете читать и выкачать вручную, выполнив следующие действия:

using (var response = (HttpWebResponse) _request.EndGetResponse(result)) 
using (var stream = response.GetResponseStream()) 
using (var compressedMemory = new MemoryStream()) 
using (var uncompressedMemory = new MemoryStream()) // Added new memory stream 
using (var gzipStream = new GZipStream(compressedMemory, CompressionMode.Decompress)) 
{ 
    var compressedBuffer = new byte[BlockSize]; 

    while (stream != null && stream.CanRead) 
    { 
     var readCount = stream.Read(compressedBuffer, 0, compressedBuffer.Length); 

     compressedMemory.Write(compressedBuffer.Take(readCount).ToArray(), 0, readCount); 
     compressedMemory.Position = 0; 

     gzipStream.CopyTo(uncompressedMemory); // use copy to rather than trying to read 

     var outputString = Encoding.UTF8.GetString(uncompressedMemory.ToArray()); 
     Debug.WriteLine(outputString); 

     uncompressedMemory.Position = 0; 
     uncompressedMemory.SetLength(0); 

     compressedMemory.Position = 0; 
     compressedMemory.SetLength(0); // reset length 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^