我有以下HttpHandler;我正在使用它来推动浏览器的更新(实现jQuery和GrowlUI),而无需浏览器进行轮询。我认为我所完成的只是将轮询循环移动到服务器。
有谁能告诉我如何让这个课程更加强大和可扩展?
这是代码。
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);
}
答案 0 :(得分:2)
如果您打算使用Thread.Sleep()
,则必须实施System.Web.IHttpAsyncHandler,否则您的处理程序将无法扩展。
答案 1 :(得分:1)
如何调用QueueUpdate?我注意到你从中获取字符串并将其直接放入要发送回用户的javascript中。用户是否有可能将javascript插入条目并让QueueUpdate以某种方式显示回来?
此外,我会在将消息放入您的javascript字符串之前将Message与有效消息regex匹配。似乎有人可以完成你的growlUi调用,然后很容易插入自己的JavaScript。至少你可以确保你插入的消息不包含单个引号('),它可以终止字符串并开始一个新的javascript命令。
也许这只是偏执狂,但它会使它更强大:)