0

如果有一些新消息发送给他,我想做一个通知用户的服务。因此,我想使用一些提供服务器推送能力的 Comet 框架。所以我调查了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 的方式相同。

4

2 回答 2

2

您不应该以这种方式实现,该示例只能这样实现,因为保持 PokeIn 相关部分很清楚。您应该按照http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events中提到的那样实现 SQL 部分 ,以便跟踪数据库的更改。

因此,当您有东西要发送时,请调用其中一种 PokeIn 方法进行客户端交付。我不知道,您的应用程序对时间的要求有多少,因为除了反向 ajax 之外,PokeIn 的内部websocket功能非常容易激活,并且可以非常快速地将消息传递给客户端。

于 2012-06-27T00:10:12.710 回答
0

正如@Zuuum 所说,您可以使用数据库执行此操作,但我以不同的方式实现它。

我在 Windows Azure 环境中使用带有 PokeIn 和 EF 的 ASP.NET MVC:

  • 我有类似这种方法的领域事件:加强您的领域:领域事件
  • 当有人调用一个动作时,这就是一个工作单元
  • 如果该 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);
    }
}
于 2012-10-26T13:52:15.833 回答