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

时间:2011-08-31 19:04:26

标签: javascript chat

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

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

3 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:5)

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

答案 2 :(得分:1)

聊天可以使用onunload事件发送注销消息,如果用户离开页面/关闭浏览器,则会触发该消息,但这不可靠。服务器的第二个选项是在基础TCP连接关闭后立即开始超时倒计时,并在用户未及时重新连接时将其显示为“离线”。