验证用户在聊天脚本中的存在

Mal*_*Mal 3 javascript chat

用户何时离开聊天页面(通过注销或仅通过简单关闭浏览器窗口).聊天脚本立即检测到该用户离开并显示脱机签名.这个过程在几秒钟内发生,这是如何真正起作用的?

我是ASP.NET/c#开发人员,除此之外我使用JavaScripts而很少使用PHP.请不要超过其他语言的答案.

Pri*_*ERO 6

正如所承诺的,这里有一些用于实现长轮询的类.基本上有6个类(见下文).为了您的目的,其中一些类可能最终不需要,但它们对我来说是有道理的.这些"大部分"已经为您消毒了.

  1. 控制器:处理创建有效响应所需的操作(数据库操作等)
  2. 处理器:管理与网页的异步通信(本身)
  3. IAsynchProcessor:服务处理实现此接口的实例
  4. 服务:处理实现IAsynchProcessor的请求对象
  5. 请求:包含您的响应的IAsynchProcessor包装器(对象)
  6. 响应:包含自定义对象或字段

如果您需要有关JavaScript或HTML插件的帮助,请在下方发表评论...我会为您写一些东西.

HTTP处理程序:

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

namespace Concept.LongPolling.Handlers
{
    /// <summary>
    /// Summary description for Controller
    /// </summary>
    public class Controller : 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>
        public bool IsReusable { get { return true; } }

        #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>
        public void ProcessRequest(HttpContext context)
        {
            throw new NotImplementedException();
        }

        /// <summary>Creates the response object which is serialized back to the client</summary>
        /// <param name="response"></param>
        public static 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;

namespace Concept.LongPolling.Handlers
{
    /// <summary>
    /// Summary description for Processor
    /// </summary>
    public class Processor : 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>
        public bool IsReusable { get { return false; } }

        #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>
        public void ProcessRequest(HttpContext context)
        {
            throw new 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>
        public void EndProcessRequest(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
    }
}
Run Code Online (Sandbox Code Playgroud)

支持课程:

using System;
using System.Runtime.InteropServices;

namespace Concept.LongPolling.LongPolling
{
    /// <summary>Represents the executable instance of an asynchronous operation.</summary>
    [ComVisible(true)]
    public interface IAsynchProcessor : IAsyncResult
    {
        /// <summary>
        /// Gets a value that indicates whether the operation completed sucessfully.
        /// </summary>
        /// <returns>true if the operation completed sucessfully; otherwise, false.</returns>
        bool ProcessRequest();
    }
}


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

namespace Concept.LongPolling.LongPolling
{
    public class Service
    {
        #region CONSTRUCTORS

        private Service()
        {
            requests = new List<IAsynchProcessor>();
            backgroundThread = new Thread(new ThreadStart(MainLoop));
            backgroundThread.IsBackground = true;
            backgroundThread.Start();
        }

        #endregion

        #region PROPERTIES

        static readonly object _padlock = new object();

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

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

        #endregion

        #region METHODS

        private void MainLoop()
        {
            while (true)
            {
                foreach (IAsynchProcessor request in requests.ToArray())
                {
                    if (request.ProcessRequest())
                        requests.Remove(request);
                }
                Thread.Sleep(500);
            }
        }

        public void AddRequest(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;

namespace Concept.LongPolling.Handlers
{
    public class Response
    {
        #region CONSTRUCTORS

        public Response()
        {
            SessionValid = true;
            Exception = String.Empty;
        }

        #endregion

        #region PROPERTIES

        public const int TimeOffset = 120;

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

        #endregion

        #region METHODS

        public void Generate()
        {
            // do some desired operation
            Number += 1;
        }

        #endregion
    }
}

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

namespace Concept.LongPolling.Handlers
{
    public class Request : IAsynchProcessor
    {
        #region CONSTRUCTORS

        public Request(AsyncCallback callback, HttpContext context)
        {
            asyncCallback = callback;
            httpContext = context;
            createdTime = DateTime.Now;

            Response = new Response();
        }

        #endregion

        #region PROPERTIES

        public const int TimeoutSeconds = 15;

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

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

        public Response Response { get; set; }

        #region IAsyncResult Members

        public HttpContext HttpContext
        {
            get
            {
                return httpContext;
            }
        }
        public object AsyncState { get; set; }

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

        bool IAsyncResult.CompletedSynchronously
        {
            get { return false; }
        }

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

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

        #endregion

        #endregion

        #region METHODS

        public bool ProcessRequest()
        {
            this.Response = Controller.CreateResponse(this.Response);
            this.IsCompleted = true;

            return this.IsCompleted;
        }

        #endregion
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

只需让您的JavaScript聊天代码每2秒使用XMLHttpRequest向服务器发送一条消息.当您没有收到消息时,这意味着用户已关闭窗口.