Могу ли я сообщить WebRequest, когда отправлять чанк из потока запросов? - PullRequest
1 голос
/ 16 октября 2010

Я отправляю запрос HTTP PUT из приложения WinForms, и я хотел бы отправить медленный поток данных PUT на страницу, которая будет записывать сообщения в базу данных по мере поступления данных PUT. Я использую WebRequest и установил для SendChunked значение true, но кажется, что отправка фрагмента происходит только после записи 8 КБ данных в поток запросов.

Хуже того, кажется, что веб-страница перестает получать примерно через 42 КБ, а отправитель выдает WebException примерно через 77 КБ с сообщением «Запрос был прерван: запрос был отменен».

На самом деле я отправляю очень малые объемы данных в каждом сообщении, поэтому, если бы я мог убедить WebRequest просто отправить небольшой фрагмент, содержащий каждое сообщение, я был бы в порядке.

Вот что я экспериментирую до сих пор:

var request = 
    (HttpWebRequest)WebRequest.Create("http://localhost/test.php");

request.Method = "PUT";
request.Timeout = 300 * 1000;
request.SendChunked = true;
request.AllowWriteStreamBuffering = false;
request.ContentType = "application/octet-stream";
using (var post = new StreamWriter(request.GetRequestStream()))
{
    post.AutoFlush = true;
    for (int i = 0; i < 100; i++)
    {
        if (i > 0)
        {
            // force flushing previous chunk
            post.Write(new String(' ', 1048));
            Thread.Sleep(2 * 1000);
        }
        Console.Out.WriteLine("Requesting {0} at {1}.", i, DateTime.Now);
        string chunk = i.ToString();
        post.WriteLine(i);
    }
}

Я пишу 1 КБ пробела после каждого сообщения, чтобы попытаться заставить WebRequest отправить чанк быстрее.

Ответы [ 2 ]

1 голос
/ 16 октября 2010

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

Я не думаю, что это будет очень легко сделать с помощью HttpWebRequest.Как вы заметили, в то время как HWR будет отправлять фрагментированные данные, он не дает вам контроля над тем, где именно начинается и заканчивается фрагмент.

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

Я бы посоветовал вам переосмыслить свой дизайн и создать простую модель на основе запросов / ответов, где запрос +данные представляют собой действие, которое должен выполнить сервер.

1 голос
/ 16 октября 2010

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

...