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