0

次の HttpHandler があります。ブラウザーがポーリングする必要なく、更新をブラウザー (jQuery と GrowlUI が実装されている場所) にプッシュするために使用しています。私が達成したのは、ポーリングループをサーバーに移動したことだけだと思います。

このクラスをより堅牢でスケーラブルにする方法を誰か教えてもらえますか?

これがコードです。

public class LiveUpdates : IHttpHandler
{
    //TODO: Replace this with a repository that the application can log to.
    private static readonly Dictionary<string, Queue<string>> updateQueue;
    static LiveUpdates()
    {
        updateQueue = new Dictionary<string, Queue<string>>();
    }

    public void ProcessRequest(HttpContext context)
    {
        context.Response.Buffer = true;

        while (context.Response.IsClientConnected)
        {
            if (context.User == null) return;
            if (!context.User.Identity.IsAuthenticated) return;

            Thread.Sleep(1000);
            if (!updateQueue.ContainsKey(context.User.Identity.Name)) continue;
            if (updateQueue[context.User.Identity.Name].Count == 0) continue;

            GrowlStatus(context.Response, updateQueue[context.User.Identity.Name].Dequeue());
        }


    }

    protected static void GrowlStatus(HttpResponse Response, string Message)
    {
        // Write out the parent script callback.
        Response.Write(String.Format("<script type=\"text/javascript\">parent.$.growlUI('Message', '{0}');</script>", Message));
        // To be sure the response isn't buffered on the server.    
        Response.Flush();
    }

    public static void QueueUpdate(IPrincipal User, string UpdateMessage)
    {
        if (!updateQueue.ContainsKey(User.Identity.Name))
        {
            updateQueue.Add(User.Identity.Name, new Queue<string>());
        }
        updateQueue[User.Identity.Name].Enqueue(UpdateMessage);
    }

    public static void ClearUpdates(IPrincipal User)
    {
        if (updateQueue.ContainsKey(User.Identity.Name)) updateQueue.Remove(User.Identity.Name);
    }
4

2 に答える 2

2

を使用する場合は、 System.Web.IHttpAsyncHandlerThread.Sleep()を実装する必要があります。実装しないと、ハンドラーがスケーリングされません。

于 2009-10-19T14:08:15.473 に答える
1

QueueUpdate はどのように呼び出されますか? そこから文字列を取得し、ユーザーに送り返す JavaScript に直接配置していることに気付きました。ユーザーが javascript をエントリに挿入して、QueueUpdate に何らかの方法でそれを表示させる可能性はありますか?

また、Message を JavaScript 文字列に入れる前に、有効なメッセージの正規表現と照合します。誰かがあなたの growlUi 呼び出しを完了してから、独自の JavaScript を非常に簡単に挿入できるようです。少なくとも、挿入するメッセージに一重引用符 (') が含まれていないことを確認してください。これにより、文字列が終了し、新しい JavaScript コマンドが開始される可能性があります。

多分それはただのパラノイアですが、それはそれをより堅牢にします:)

于 2009-10-19T14:06:41.437 に答える