Pregunta

Tengo el siguiente HttpHandler; Lo estoy usando para empujar cambios al navegador (donde se implementan jQuery y GrowlUI) sin la necesidad de que el navegador para sondeo. Creo que todo lo que he logrado es mover el bucle de sondeo con el servidor.

Puede alguien decirme cómo puedo hacer esta clase más robusta y escalable?

Este es el código.

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);
    }
¿Fue útil?

Solución

Si va a utilizar Thread.Sleep(), debe implementar Sistema .Web.IHttpAsyncHandler o el controlador no se escala.

Otros consejos

¿Cómo se llama QueueUpdate? Me di cuenta de que tome las cadenas de eso y lo coloca directamente en el código JavaScript que va a enviar de vuelta al usuario. ¿Hay alguna posibilidad de que un usuario podría insertar JavaScript en una entrada y tienen QueueUpdate alguna manera mostrar de nuevo?

Además, yo coincidiría con mensaje contra una expresión regular mensaje válido antes de ponerlo en su cadena de JavaScript. Parece como si alguien pudiera completar su llamada growlUi y luego insertar su propio código JavaScript con bastante facilidad. Por lo menos que podría hacer que el mensaje va a insertar no contiene una comilla simple ( ') que podría poner fin a la cadena y comenzar un nuevo comando de JavaScript.

Tal vez eso es sólo la paranoia, pero que hará que sea más robusto:)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top