Frage

Ich habe das folgende httphandler; Ich benutze es, um Updates an den Browser (in dem JQuery und Growlui implementiert werden) zu übertragen, ohne dass der Browser die Umfrage befreit muss. Ich denke, ich habe alles, was ich erreicht habe, die Wahlschleife auf den Server verlagert.

Kann mir jemand sagen, wie ich diese Klasse robuster und skalierbarer machen kann?

Hier ist der Code.

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);
    }
War es hilfreich?

Lösung

Wenn Sie vorhaben zu verwenden Thread.Sleep(), Sie müssen implementieren System.Web.ihttpasynchandler Oder Ihr Handler wird nicht skalieren.

Andere Tipps

Wie heißt Queueupdate? Mir ist aufgefallen, dass Sie Strings davon nehmen und es direkt in das JavaScript legen, das Sie an den Benutzer senden. Gibt es eine Chance, dass ein Benutzer JavaScript in einen Eintrag einfügen und Queueupdate irgendwie wieder anzeigen lassen kann?

Außerdem würde ich die Nachricht mit einer gültigen Meldungsregex übereinstimmen, bevor ich sie in Ihre JavaScript -Zeichenfolge einfügt. Es scheint, als könnte jemand Ihren Knurrenanruf vervollständigen und dann ziemlich leicht sein eigenes JavaScript einfügen. Zumindest können Sie sicherstellen, dass die von Ihnen eingefütterte Nachricht kein einzelnes Zitat (') enthält, das die Zeichenfolge beenden und einen neuen JavaScript -Befehl starten kann.

Vielleicht ist das nur Paranoia, aber es wird es robuster machen :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top