Skip to content Skip to sidebar Skip to footer

Verification Of User's Existence In Chat Script

When ever user leaves chat page (Either by logging out or just by simple closing the browser window). Chat script instantly detects that user left and show offline sign. This proce

Solution 1:

As promised, here are some classes used in implementing long-polling. There are basically 6 classes (see below). Some of these classes may end-up being unneeded for YOUR purposes, but they made sense for mine. These have "mostly" been sanitized for you.

  1. Controller: Processes actions required to create a valid response (db operations etc.)
  2. Processor: Manages asynch communication with the web page (itself)
  3. IAsynchProcessor: The service processes instances that implement this interface
  4. Sevice: Processes request objects that implement IAsynchProcessor
  5. Request: The IAsynchProcessor wrapper containing your response (object)
  6. Response: Contains custom objects or fields

If you need help with the JavaScript or HTML add-in a comment below...I will write something for you.

HTTP HANDLERS:

using System;
using System.Configuration;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Services;
using System.Web.SessionState;

namespaceConcept.LongPolling.Handlers
{
    ///<summary>/// Summary description for Controller///</summary>publicclassController : IHttpHandler, IReadOnlySessionState
    {
        #region CONSTRUCTORS#endregion#region PROPERTIES///<summary>Gets a Boolean value indicating that another request can use the current instance of the DefaultHttpHandler class.</summary>///<remarks>Returning true makes the same AsyncHttpHandler object be used for all requests.</remarks>///<remarks>Returning false here makes ASP.Net create object per request.</remarks>publicbool IsReusable { get { returntrue; } }

        #endregion#region METHODS///<summary>Enables synchronous processing of HTTP Web requests</summary>///<param name="context">An HttpContext object that provides references to the intrinsic server objects</param>//////<remarks>This is where you would send commands to the controller that would affect processing in some manner.</remarks>publicvoidProcessRequest(HttpContext context)
        {
            thrownew NotImplementedException();
        }

        ///<summary>Creates the response object which is serialized back to the client</summary>///<param name="response"></param>publicstatic Response CreateResponse(Response response)
        {
            try
            {
                response.Generate();
            }
            catch (System.Exception ex)
            {
                response.SessionValid = false;
            }

            return response;
        }

        #endregion
    }
}

using System;
using System.Configuration;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Services;
using System.Web.SessionState;
using Concept.LongPolling.LongPolling;

namespaceConcept.LongPolling.Handlers
{
    ///<summary>/// Summary description for Processor///</summary>publicclassProcessor : IHttpHandler, IHttpAsyncHandler, IReadOnlySessionState
    {
        #region CONSTRUCTORS#endregion#region PROPERTIES///<summary>Gets a Boolean value indicating that another request can use the current instance of the DefaultHttpHandler class.</summary>///<remarks>Returning true makes the same AsyncHttpHandler object be used for all requests.</remarks>///<remarks>Returning false here makes ASP.Net create object per request.</remarks>publicbool IsReusable { get { returnfalse; } }

        #endregion#region METHODS///<summary>Enables synchronous processing of HTTP Web requests</summary>///<param name="context">An HttpContext object that provides references to the intrinsic server objects</param>publicvoidProcessRequest(HttpContext context)
        {
            thrownew NotImplementedException();
        }

        #region IHttpAsyncHandler Members///<summary>Enables asynchronous processing of HTTP Web requests</summary>///<param name="context">An HttpContext object that provides references to the intrinsic server objects</param>///<param name="cb">The method to call when the asynchronous method call is complete. If callback is null, the delegate is not called.</param>///<param name="extraData"></param>///<returns>Any state data that is needed to process the request.</returns>public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            Int32 someValueYouLikeToSendInYourClass = Convert.ToInt32(context.Request["Number"]);

            Request request = new Request(cb, context);
            request.Response.Number = someValueYouLikeToSendInYourClass;

            Service.Singleton.AddRequest(request);

            return request;
        }

        ///<summary>Provides an end method for an asynchronous process.</summary>///<param name="result">An object that contains information about the status of the process.</param>publicvoidEndProcessRequest(IAsyncResult result)
        {
            Request request = result as Request;
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            request.HttpContext.Response.ContentType = "text/json";
            request.HttpContext.Response.Write(serializer.Serialize(request.Response));
            request.HttpContext.Response.End();
        }

        #endregion#endregion
    }
}

SUPPORTING CLASSES:

using System;
using System.Runtime.InteropServices;

namespaceConcept.LongPolling.LongPolling
{
    ///<summary>Represents the executable instance of an asynchronous operation.</summary>
    [ComVisible(true)]
    publicinterfaceIAsynchProcessor : IAsyncResult
    {
        ///<summary>/// Gets a value that indicates whether the operation completed sucessfully.///</summary>///<returns>true if the operation completed sucessfully; otherwise, false.</returns>boolProcessRequest();
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;

namespaceConcept.LongPolling.LongPolling
{
    publicclassService
    {
        #region CONSTRUCTORSprivateService()
        {
            requests = new List<IAsynchProcessor>();
            backgroundThread = new Thread(new ThreadStart(MainLoop));
            backgroundThread.IsBackground = true;
            backgroundThread.Start();
        }

        #endregion#region PROPERTIESstaticreadonlyobject _padlock = newobject();

        privatestatic Service singleton;
        private Thread backgroundThread;
        private List<IAsynchProcessor> requests;

        publicstatic Service Singleton
        {
            get
            {
                lock (_padlock)
                {
                    if (_singleton == null)
                        _singleton = new Service();
                    return _singleton;
                }
            }
        }

        #endregion#region METHODSprivatevoidMainLoop()
        {
            while (true)
            {
                foreach (IAsynchProcessor request in requests.ToArray())
                {
                    if (request.ProcessRequest())
                        requests.Remove(request);
                }
                Thread.Sleep(500);
            }
        }

        publicvoidAddRequest(IAsynchProcessor request)
        {
            requests.Add(request);
        }

        #endregion
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Concept.LongPolling.Business;
using System.Data;

namespaceConcept.LongPolling.Handlers
{
    publicclassResponse
    {
        #region CONSTRUCTORSpublicResponse()
        {
            SessionValid = true;
            Exception = String.Empty;
        }

        #endregion#region PROPERTIESpublicconstint TimeOffset = 120;

        public Int32 Number { get; set; }
        publicbool SessionValid { get; set; }
        public String Exception { get; set; }

        #endregion#region METHODSpublicvoidGenerate()
        {
            // do some desired operation
            Number += 1;
        }

        #endregion
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Concept.LongPolling.LongPolling;

namespaceConcept.LongPolling.Handlers
{
    publicclassRequest : IAsynchProcessor
    {
        #region CONSTRUCTORSpublicRequest(AsyncCallback callback, HttpContext context)
        {
            asyncCallback = callback;
            httpContext = context;
            createdTime = DateTime.Now;

            Response = new Response();
        }

        #endregion#region PROPERTIESpublicconstint TimeoutSeconds = 15;

        private AsyncCallback asyncCallback;
        private HttpContext httpContext;
        private DateTime createdTime;

        publicbool TimedOut
        {
            get
            {
                return ((DateTime.Now - createdTime).TotalSeconds >= TimeoutSeconds);
            }
        }

        public Response Response { get; set; }

        #region IAsyncResult Memberspublic HttpContext HttpContext
        {
            get
            {
                return httpContext;
            }
        }
        publicobject AsyncState { get; set; }

        System.Threading.WaitHandle IAsyncResult.AsyncWaitHandle
        {
            get { thrownew NotImplementedException(); }
        }

        bool IAsyncResult.CompletedSynchronously
        {
            get { returnfalse; }
        }

        publicbool IsCompleted
        {
            get { return isCompleted; }
            set
            {
                if (!value) return;

                this.isCompleted = true;
                asyncCallback(this);
            }
        }
        bool isCompleted = false;

        #endregion#endregion#region METHODSpublicboolProcessRequest()
        {
            this.Response = Controller.CreateResponse(this.Response);
            this.IsCompleted = true;

            returnthis.IsCompleted;
        }

        #endregion
    }
}

Solution 2:

Just have your JavaScript chat code send a message to the server every 2 seconds using XMLHttpRequest. When you don't receive a message, that means that the user has closed the window.

Solution 3:

The chat can send a logout message using the onunload event, which is triggered if the user leaves the page/closes the browser, however it is not reliable. A second option for the server is to begin a timeout countdown as soon as the underlying TCP connection is closed and show the user as "offline" in case he does not reconnect in time.

Post a Comment for "Verification Of User's Existence In Chat Script"