Как мне реализовать часть длинного опроса на стороне сервера C # для запросов ajax? - PullRequest
3 голосов
/ 28 апреля 2010

У меня есть архитектура, в которой браузеры опрашивают обновления через ajax каждые 3 секунды, и я хотел бы изменить это на long-polling .

Я бы хотел, чтобы 1, 2 .. {n} клиентов долго опрашивали, ожидали обновления и что-то происходило на сервере, чтобы дать сигнал ожидающим клиентам вернуться. Моей первой мыслью было использовать EventWaitHandle, и я могу легко это сделать, если просто хочу поддержать 1 клиента. Мне просто нужно было бы AutoResetEvent WaitHandle, который WaitOne блокировал бы клиента, может быть с таймаутом, а может и нет. В любом случае, AutoResetEvent позволит мне поддерживать только 1 клиента (поскольку он пробуждает только 1 ожидающий поток), и я хочу n клиентов.

Я почти уверен, что мне нужно использовать ManualResetEvent WaitHandle, но я не уверен, когда позвонить Reset после того, как я Set (при пробуждении темы). Должен ли я просто Thread.Sleep некоторая произвольная сумма между Set и Reset?

В коде psuedo логика пробуждения будет

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

Это та третья строка, с которой мне трудно. В настоящее время я отказываюсь от идеи иметь LastTxID, которую клиент / сервер поддерживает, и, возможно, используя 2 маркера ожидания. Однако, прежде чем я сошел с ума от этой реализации, я хотел получить обратную связь, чтобы узнать, как они реализуют логику пробуждения.

Редактировать: предположим, у меня есть проблемы, связанные с определением максимального числа одновременных пользователей, путем настройки IIS или размещения через WCF или другого решения. Я только хочу сосредоточиться на логике бодрствования.

1 Ответ

0 голосов
/ 28 апреля 2010

Одна идея, в псевдокоде

  • Поддерживать потокобезопасный список идентификаторов соединений, возможно использовать идентификатор сеанса
  • Дайте каждому соединению свой собственный AutoResetEventWaitHandle
  • Поточно-ориентированным образом, переберите эти дескрипторы ожидания и установите их при обновлении
  • в конце сеанса потокобезопасным образом удалите этот идентификатор соединения / сеанса из списка

Я бы хотел получить отзыв об этом

против этого подхода

  • должен вести список соединений
  • необходимо сгенерировать {n} дескрипторов ожидания для {n} клиентов
...