我想提供一个服务,以便在发送给他的新消息时通知用户。因此,我想使用一些提供服务器推送能力的Comet框架。所以我调查了PokeIn。
只是想知道一件事。我查看了他们在网站上的样本。如果有的话,他们都不会查看数据库以检索新条目。但我想这只是一个修改问题。
其中一个示例通过在服务器端使用sleep来实现此长轮询。因此,如果我使用相同的方法,我可以检查数据库,如果有任何新条目,则每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的方式相同。
答案 0 :(得分:2)
你不应该以这种方式实现,该样本只是这样实现的,因为保持PokeIn相关部分是清楚的。您应该按照提到的那样实现SQL部分http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events 为了跟踪数据库的变化。
因此,当您要发送内容时,请调用其中一个PokeIn方法进行客户端交付。我不知道,你的应用程序对时间要求多少很重要,因为除了反向ajax之外,PokeIn的内部websocket功能非常容易激活,并且可以非常快速地向客户端发送消息。
答案 1 :(得分:0)
你可以用@Zuuum说的那样用数据库来做,但是我用不同的方式实现了它。
我在Windows Azure环境中使用带有PokeIn和EF的ASP.NET MVC:
我将这种模式用于游戏网站上的所有实时需求(在游戏中进行移动,操作等),我不想在这里做广告,如果你愿意,你可以通过我找到它。 / p>
我总是将此模式用作双工通信解决方案,因此每个人都可以通过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);
}
}