Обработка нескольких запросов с помощью C# HttpListener
у меня есть служба .NET Windows, которая порождает поток, который в основном действует как HttpListener
. Это отлично работает в Примере синхронного режима...
private void CreateLListener()
{
HttpListenerContext context = null;
HttpListener listener = new HttpListener();
bool listen = true;
while(listen)
{
try
{
context = listener.GetContext();
}
catch (...)
{
listen = false;
}
// process request and make response
}
}
проблема, которую я сейчас имею, заключается в том, что мне нужно работать с несколькими запросами и отвечать на них одновременно или, по крайней мере, перекрывать.
чтобы объяснить дальше-клиент-это приложение media player, которое начинается с запроса медиа-файла со свойством заголовка запроса Range bytes=0-
. Как насколько я могу судить, он делает это, чтобы выяснить, что такое медиа-контейнер.
после того, как он прочитал "кусок" (или если он прочитал достаточно, чтобы установить тип носителя), он делает другой запрос (из другого номера сокета клиента) с Range bytes=X-Y
. В этом случае Y-длина содержимого, возвращаемая в первом ответе, а X-на 250000 байт меньше (обнаружено с помощью IIS в качестве теста). На этом этапе он получает последний "кусок", чтобы увидеть, может ли он получить метку времени мультимедиа для измерения длина.
прочитав это, он делает еще один запрос с Range bytes=0-
(С другого номера сокета), чтобы правильно начать потоковую передачу медиафайла.
в любое время, хотя, если пользователь клиента выполняет операцию "пропустить", он отправляет другой запрос (из еще одного номера сокета) с Range bytes=Z-
где Z-позиция для перехода в медиафайле.
Я не очень хорошо разбираюсь в HTTP-материалах, но, насколько я могу судить, мне нужно использовать несколько потоков для обработки каждого запрос / ответ, разрешая оригинал HttpListener
вернуться к прослушиванию. Я много искал, но не могу найти модель, которая, кажется, подходит.
EDIT:
признание и благодарность Рик Штраль на следующем примере, который я смог адаптироваться, чтобы удовлетворить мои потребности...
добавьте веб-сервер в приложение .NET 2.0 с несколькими строками кода
3 ответов
Если вам нужна более простая альтернатива BeginGetContext, вы можете просто поставить задания в очередь в ThreadPool вместо их выполнения в основном потоке. Вроде таких:
private void CreateLListener() {
//....
while(true) {
ThreadPool.QueueUserWorkItem(Process, listener.GetContext());
}
}
void Process(object o) {
var context = o as HttpListenerContext;
// process request and make response
}
для обработки нескольких запросов необходимо использовать метод async. Таким образом, вы будете использовать e BeginGetContext
и EndGetContext
методы.
посмотреть здесь.
синхронный модель подходит, если ваше приложение должно блокировать в ожидании запроса клиента и если вы хотите обработать только один *запрос в то время*. Используя синхронную модель, вызовите GetContext метод, ожидающий клиента отправить запрос. Метод возвращает объект HttpListenerContext для обработки при его возникновении.
Если вы здесь из будущего и пытаетесь обработать несколько параллельных запросов с помощью одного потока, используя async / await..
public async Task Listen(string prefix, int maxConcurrentRequests, CancellationToken token)
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add(prefix);
listener.Start();
var requests = new HashSet<Task>();
for(int i=0; i < maxConcurrentRequests; i++)
requests.Add(listener.GetContextAsync());
while (!token.IsCancellationRequested)
{
Task t = await Task.WhenAny(requests);
requests.Remove(t);
if (t is Task<HttpListenerContext>)
{
var context = (t as Task<HttpListenerContext>).Result;
requests.Add(ProcessRequestAsync(context));
requests.Add(listener.GetContextAsync());
}
}
}
public async Task ProcessRequestAsync(HttpListenerContext context)
{
...do stuff...
}