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

Verification of user's existence in chat script

本文关键字:用户 存在 验证 聊天 脚本      更新时间:2023-09-26

当用户离开聊天页面时(无论是注销还是关闭浏览器窗口)。聊天脚本立即检测到用户离开并显示脱机标志。这个过程在几秒钟内完成这到底是怎么回事?

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

如前所述,这里有一些用于实现长轮询的类。基本上有6类(见下文)。其中一些类最终可能不需要你的目的,但它们对我来说是有意义的。这些"大部分"已经为你消毒过了。

  1. 控制器:处理创建有效响应所需的操作(db操作等)
  2. Processor:管理与网页(自身)的异步通信
  3. IAsynchProcessor:服务处理实现这个接口的实例
  4. service :处理实现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
    }
}
支持类:


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
    }
}

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

聊天可以使用onunload事件发送注销消息,该事件在用户离开页面/关闭浏览器时触发,但它不可靠。服务器的第二个选项是在底层TCP连接关闭后立即开始超时倒计时,并在用户没有及时重新连接的情况下将用户显示为"脱机"。