0

ユーザーに新しいメッセージが送信された場合にユーザーに通知するサービスを作成したいと考えています。したがって、サーバーのプッシュ機能を提供する Comet フレームワークを使用したいと考えています。だから私はPokeInを調べました。

不思議に思っているだけです。ウェブサイトにあるサンプルを確認しました。それらのいずれも、データベースを調べて、新しいエントリがあればそれを取得しません。しかし、それは単なる修正の問題だと思います。

サンプルの 1 つは、サーバー側でスリープを使用してこのロング ポーリングを実装します。したがって、同じアプローチを使用すると、新しいエントリがあるかどうかを 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

このように実装するべきではありません。そのサンプルは、keep PokeIn 関連部分が明確であるため、そのように実装されているだけです。 データベースの変更を追跡するには、http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-eventsに記載されている SQL 部分を実装する必要があります。

したがって、送信するものがある場合は、クライアント側の配信用に PokeIn メソッドの 1 つを呼び出します。リバース 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 に答える