Domanda

Ho il seguente HttpHandler; Sto usando per spingere gli aggiornamenti al browser (dove sono implementati jQuery e GrowlUI), senza la necessità per il browser per il polling. Credo che tutto quello che ho realizzato è in movimento il ciclo di polling al server.

Qualcuno può dirmi come posso fare questa classe più robusto e scalabile?

Ecco il codice.

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);
    }
È stato utile?

Soluzione

Se si prevede di utilizzare Thread.Sleep(), è necessario implementare sistema .Web.IHttpAsyncHandler o il vostro gestore non scala.

Altri suggerimenti

Come si chiama QueueUpdate? Ho notato che si prende le stringhe da questo e posizionarlo direttamente in javascript che si sta inviando indietro per l'utente. C'è qualche possibilità che un utente potrebbe inserire javascript in una voce e hanno in qualche modo QueueUpdate visualizzare indietro?

Inoltre, vorrei abbinare messaggio nei confronti di un messaggio di espressione regolare valida prima di metterla nel tuo stringa JavaScript. Sembra che qualcuno potrebbe completare la chiamata growlUi e quindi inserire il proprio javascript abbastanza facilmente. Per lo meno si potrebbe fare che il messaggio che si sta inserendo non contiene un apostrofo ( '), che potrebbe terminare la stringa e iniziare un nuovo comando javascript.

Forse questo è solo paranoia, ma renderà più robusto:)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top