Tornando este httphandler mais robusto?
-
22-09-2019 - |
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);
}
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 :)