正如@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);
}
}