2012-06-26 9 views
0

Я хочу сделать сервис, который уведомляет пользователя, если есть новые сообщения, отправленные ему. Таким образом, я хочу использовать некоторую инфраструктуру Comet, которая обеспечивает возможность push-сервера. Поэтому я просмотрел PokeIn.ASP.net как долгий опрос с PokeIn?

Просто интересно. Я проверил образцы, которые у них есть на веб-сайте. Ни один из них не заглядывает в базу данных, чтобы получать новые записи, если они есть. Но я думаю, это просто вопрос модификации.

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

Эта часть взята из образца. Как видно, они спали там, чтобы обновить текущее время для всех.

static void UpdateClients() 
    { 
     while (true) 
     { 
      //.. code to check database 
      if (CometWorker.ActiveClientCount > 0) 
      { 
       CometWorker.SendToAll(JSON.Method("UpdateTime", DateTime.Now)); 
      } 
      Thread.Sleep(500); 
     } 
    } 

Так что я удивляюсь, как я должен внедрить уведомитель сообщения? Похоже, что вышеупомянутый подход все еще будет подталкивать огромную нагрузку на серверную сторону. Извещатель сообщения намерен работать так же, как тот, который нашел Facebook.

ответ

2

Вы не должны реализовывать этот способ, этот пример реализуется только так, потому что связанная часть keep PokeIn понятна. Вы должны реализовать SQL-часть, как упомянуто http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events , чтобы отслеживать изменения в базе данных.

Итак, когда у вас есть что отправить, позвоните по одному из методов PokeIn для доставки на стороне клиента. Я не знаю, насколько ваше приложение критично для времени, поскольку в дополнение к обратному ajax внутренняя функция PokeIn websocket очень легко активировать и доставляет сообщения клиенту довольно быстро.

+0

благодарит за информацию. Что касается изменений событий данных, существует ли также подход, в котором применяется обнаружение изменений данных в лазурной таблице? – starcorn

+0

№. возможно, вы должны задать это по отдельному вопросу. (аналогичное решение SQLDependency для Azuretable и т. д.) – Zuuum

0

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

Я использую ASP.NET MVC с PokeIn и EF в среде Windows Azure:

  • У меня есть события домена похож на этот подход: Strengthening your domain: Domain Events
  • Когда кто-то вызывает действие, это Unit of Work
  • Если UOW удастся, то я поднимаю событие домена (например, ChatMessageSent)
  • у меня есть подписчики на них чтобы они могли принимать событие и пересылать сообщение слушателям PokeIn.

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

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

Следующий пример не будет работать, потому что они являются лишь фрагменты, демонстрирующие поток

Здесь действие отрывок из моего кода:

[HttpPost] 
[UnitOfWork] 
[RestrictToAjax] 
[ValidateAntiForgeryToken] 
public JsonResult Post(SendMessageViewModel msg) 
{ 
    if (ModelState.IsValid) 
    { 
     var chatMessage = new ChatMessage 
     { 
      ContainerType = msg.ContainerType, 
      ContainerID = msg.ContainerID, 
      Message = _xssEncoder.Encode(msg.Message), 
      User = _profileService.CurrentUser 
     }; 

     _chatRepository.AddMessage(chatMessage); 
     OnSuccessfulUoW =() => EventBroker.Current.Send(this, new ChatMessageSentPayload(chatMessage)); 
    } 

    return Json(Constants.AjaxOk); 
} 

, И (упрощенный) реализации EventBroker :

public class UnityEventBroker : EventBroker 
{ 
    private readonly IUnityContainer _container; 

    public UnityEventBroker(IUnityContainer container) 
    { 
     _container = container; 
    } 

    public override void Send<TPayload>(object sender, TPayload payload) 
    { 
     var subscribers = _container.ResolveAll<IEventSubscriber<TPayload>>(); 
     if (subscribers == null) return; 
     foreach (var subscriber in subscribers) 
     { 
      subscriber.Receive(sender, payload); 
     } 
    } 
} 

И еще более упрощена абонент:

public class ChatMessageSentSubscriber : IEventSubscriber<ChatMessageSentPayload> 
{ 
    public void Receive(object sender, ChatMessageSentPayload payload) 
    { 
     var message = payload.Message; 
     var content = SiteContent.Global; 

     var clients = Client.GetClients(c => c.ContentID == message.ContainerID && c.Content == content) 
          .Select(c => c.ClientID) 
          .ToArray(); 

     var dto = ObjectMapper.Current.Map<ChatMessage, ChatMessageSentDto>(message); 

     var json = PokeIn.JSON.Method("pokein", dto); 
     CometWorker.SendToClients(clients, json); 
    } 
}