Click here to Skip to main content
15,894,720 members
Articles / Web Development / HTML

Using IHttpAsyncHandler and XMLHttpRequest to “push” messages to the client

Rate me:
Please Sign up or sign in to vote.
4.75/5 (14 votes)
30 Sep 2009CPL4 min read 84.5K   2K   61  
How you can let a web browser be a "listener" for chat messages pushed from a web server.
//
// This code is released under Common Public License Version 1.0 (CPL)
// Full license text is available at http://www.opensource.org/licenses/cpl1.0.php
//
// Author  : Karel Boek
// Date    : Sept 29, 2009
// Contact : karel.boek@raskenlund.com
//

using System;
using System.Collections.Generic;
using System.Web;

namespace SandBox.CometSample
{
    /// <summary>
    /// An IHttpAsyncHandler to "push" messages to the intended recipients
    /// </summary>
    public class MyAsyncHandler : IHttpAsyncHandler
    {
        /// <summary>
        /// The queue holds a list of asynchronous results with information about registered sessions
        /// </summary>
        public static List<MyAsyncResult> Queue;

        /// <summary>
        /// Static constructor
        /// </summary>
        static MyAsyncHandler()
        {
            // Initialize the queue
            Queue = new List<MyAsyncResult>();
        }

        #region IHttpAsyncHandler Members

        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            // Fetch the session id from the request
            var sessionId   = context.Request["sessionId"];
            
            // Check if the session is already registered
            if (Queue.Find(q => q.SessionId == sessionId) != null)
            {
                var index = Queue.IndexOf(Queue.Find(q => q.SessionId == sessionId));

                // The session has already been registered, just refresh the HttpContext and the AsyncCallback
                Queue[index].Context  = context;
                Queue[index].Callback = cb;

                return Queue[index];
            }

            // Create a new AsyncResult that holds the information about the session
            var asyncResult = new MyAsyncResult(context, cb, sessionId);

            // This session has not been registered yet, add it to the queue
            Queue.Add(asyncResult);

            return asyncResult;
        }

        public void EndProcessRequest(IAsyncResult result)
        {
            var rslt  = (MyAsyncResult) result;
            
            // send the message to the recipient using the recipients HttpContext.Response object
            rslt.Context.Response.Write(rslt.Message);

            // reset the message object
            rslt.Message = string.Empty;
        }

        #endregion

        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return true; }
        }

        /// <summary>
        /// In an asychronous solution, this message shouldn't be called
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)


Written By
Software Developer Raskenlund
Norway Norway
Professional System Architect and Developer

Comments and Discussions