2012-06-26 67 views
0

我想提供一項服務,以便在發送給他的新消息的情況下通知用戶。因此我想使用一些提供服務器推送能力的Comet框架。所以我看了看PokeInASP.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

你不應該用這種方式來實現,那個樣本只能這樣實現,因爲保持PokeIn相關部分是清楚的。您應該按照提及的http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events 執行SQL部分,以便跟蹤數據庫上的更改。

因此,當您有要發送的內容時,請爲客戶端傳送調用其中一個PokeIn方法。我不知道,你的應用程序有多少時間是至關重要的,因爲除了逆轉阿賈克斯,PokeIn的內部websocket特點是很容易激活,並將消息傳遞到客戶端的速度相當快。

+0

感謝您的信息。關於數據事件的變化,是否還有一種方法可以檢測天藍色表中檢測到的數據變化? – starcorn

+0

沒有。也許你應該在另一個問題上提出這個問題。 (用於Azuretable的類似SQLDependency解決方案等) – Zuuum

0

你可以用@Zuuum所說的做數據庫,但我用不同的方式實現它。

我在Windows Azure的環境中使用ASP.NET MVC與PokeIn和EF:

  • 域事件類似這樣的方法: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); 
    } 
}