Pergunta

Eu tenho o seguinte httphandler; Estou usando -o para empurrar atualizações para o navegador (onde o jQuery e o Growlui são implementados) sem a necessidade de o navegador pesquisar. Acho que tudo o que realizei é mover o loop de votação para o servidor.

Alguém pode me dizer como posso tornar essa classe mais robusta e escalável?

Aqui está o 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);
    }
Foi útil?

Solução

Se você planeja usar Thread.Sleep(), você deve implementar System.web.ihttpasynchandler Ou seu manipulador não vai escalar.

Outras dicas

Como é chamado o QueueUpdate? Percebi que você pega as cordas disso e o coloca diretamente no JavaScript que você está enviando de volta ao usuário. Existe alguma chance de que um usuário possa inserir o JavaScript em uma entrada e ter o QueueUpdate de alguma forma exibi -lo de volta?

Além disso, eu corresponderia à mensagem com uma mensagem válida REGEX antes de colocá -la na sua sequência JavaScript. Parece que alguém poderia completar sua chamada Growlui e, em seguida, inserir seu próprio JavaScript com bastante facilidade. No mínimo, você pode garantir que a mensagem que está inserindo não contenha uma única citação (') que possa encerrar a string e iniciar um novo comando javascript.

Talvez isso seja apenas paranóia, mas será mais robusto :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top