none
请教下如何获取用户的登陆状态来判断在线离线 RRS feed

  • 问题

  • 用Forms安全认证做了个登陆但因为有个在线和离线状态不知道怎么做。。看了网上一些说法。新开1张表拿来记录用户的最后一次活动的时间和现在服务器上的时间相差多少就认定他为离线。是不是每一秒钟都要去用ajax异步去连接处理判断的页面啊。每一秒都要去更新数据库?还有什么方法能做到用户的在线离线状态呢。请教高手。。这里不用session!
    2009年9月9日 8:19

答案

  • 因为每个请求处理完毕之后,客户端与服务器端之间就没有联系了,所以,采用ajax请求是一个做法,但不要每秒去执行,这样太费服务器资源了,3分钟或者5分钟做一次就可以了,当然,这样会存在误差。这个方法是常用的方法。

    另外一个做法是使用长连接,一直保持客户端与服务器端的连接,这个实现起来不如前面的方法简单。这个做法sohu的论坛使用过。可参考http://www.seewind.cn/blog/article.asp?id=69

    【孟子E章】
    • 已建议为答案 肖小勇Moderator 2009年9月9日 8:34
    • 已标记为答案 Xhp 2009年9月10日 3:24
    2009年9月9日 8:29
    版主

全部回复

  • 因为每个请求处理完毕之后,客户端与服务器端之间就没有联系了,所以,采用ajax请求是一个做法,但不要每秒去执行,这样太费服务器资源了,3分钟或者5分钟做一次就可以了,当然,这样会存在误差。这个方法是常用的方法。

    另外一个做法是使用长连接,一直保持客户端与服务器端的连接,这个实现起来不如前面的方法简单。这个做法sohu的论坛使用过。可参考http://www.seewind.cn/blog/article.asp?id=69

    【孟子E章】
    • 已建议为答案 肖小勇Moderator 2009年9月9日 8:34
    • 已标记为答案 Xhp 2009年9月10日 3:24
    2009年9月9日 8:29
    版主
  • 呵呵谢谢孟大哥。。但如果2分钟连接去另外的处理页面。。做处理。那如果我一打开网页没到2分钟我就X掉了。ajax就没连过去处理页面那做数据库的更新。。那样的话怎么办
    2009年9月9日 8:41
  • 呵呵谢谢孟大哥。。但如果2分钟连接去另外的处理页面。。做处理。那如果我一打开网页没到2分钟我就X掉了。ajax就没连过去处理页面那做数据库的更新。。那样的话怎么办

    如果ajax没连接上的话 做个服务端定时检查所有在线时间判断
    2009年9月9日 8:54
  • 页面A(定义ajax5分钟去传值过去页面B)
    页面B(接收页面A的请求比如用户名。。去更新数据库对应的活动时间)
    要在页面B上面做个Timers?当页面A传值过来时。更新数据库之后定时20分钟后再用服务器上的时间和数据库的活动时间去做对比?看它们是否相差不大于5分钟。。如果活动的话5分钟就传一次嘛。。如果大于5分钟的话就是定时的20分钟内没有再传过来?就是不活动了。就认定他为离线?


    页面B代码
    public partial class outt : System.Web.UI.Page
    {
        public int id;
        private static System.Timers.Timer aTimer;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request["Name"] != null)
            {
                string strUserName = Request["Name"];
    
              //一直统计按名字更新数据库时间..
                aTimer = new System.Timers.Timer(120000);
                aTimer.Elapsed += new System.Timers.ElapsedEventHandler(aTimer_Elapsed);
                aTimer.Enabled = true;
            }
        }
    
        void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
    //这里读出对应用户的活动时间,再去和现在的服务器时间做对比,,看是否相差5分钟。。否着就认定他离线? }
    2009年9月9日 9:06
  •  protected void Page_Load(object sender, EventArgs e)
     {
    直接更新数据库的最后时间,显示在线肯定不是给当前用户看的,其他用户使用时使用sql的DateDiff直接查询数据库
    }


    无需使用 Timer


    【孟子E章】
    2009年9月9日 9:30
    版主
  • 不是很明白。
    2009年9月9日 9:51
  • 这样吧 在线请求每个页更新一段时间 设定一段时间判断如果超过这个时间把数据删除  用户浏览帖子页面判断这个表发帖子用户有没有用户在线更新相关的数据  
    2009年9月9日 10:01
  • 问题是如果不用Timer  B页面一接收到就更新。。再在下面读数据库的刚才那个时间出来?那如何能在它传值过来时延迟比如2分钟再去判断刚加入数据库里面的时间和延迟后的时间相差多少啊。
    2009年9月9日 10:22
  • 有人做过类似的吗。搞不懂哦。。
    2009年9月9日 11:13
  • 问题是如果不用Timer  B页面一接收到就更新。。再在下面读数据库的刚才那个时间出来?那如何能在它传值过来时延迟比如2分钟再去判断刚加入数据库里面的时间和延迟后的时间相差多少啊。
    自己判断自己没有用处的,假如用户A登录了,那么如果在线的话,如果5分钟更新下数据库,那么,要显示某个用户是否在线,只需要
    select * from User表 WHERE (DATEDIFF(n, LastUpdated, GETDATE()) < 5)

    就可以得到所有线搜用户了.比如很多论坛有一块显示全部在线用户的列表.


    【孟子E章】
    2009年9月9日 12:45
    版主
  • 有人做过类似的吗。搞不懂哦。。
    好好想想

    【孟子E章】
    2009年9月9日 12:46
    版主
  • 好的我再认真想想。谢谢了不懂再提出。。呵呵
    2009年9月9日 13:32
  • 考虑研究下membership的在线机制类似的
    2009年9月9日 14:08
  • 有个问题。。这里select * from User表 WHERE (DATEDIFF(n, LastUpdated, GETDATE()) < 5)
    LastUpdated是记录活动的时间吗?之后用服务器的时间去减活动时间。。看小于5的话就。。。

    select * from User表 WHERE (DATEDIFF(n, LastUpdated, GETDATE()) < 5)要写去哪啊??

    A页面是ajax传值页。。B页更新对应的活动时间。。GETDATE())返回服务器的现在时间。。B页收到A页传的值之后更新数据库里面的活动时间了。那select * from User表 WHERE (DATEDIFF(n, LastUpdated, GETDATE()) < 5)这个东西。。是要自己再别开页面时执行sql命令?在B页上只负责更新活动时间。。还是说能在B页面那进行延迟判断下前5分钟在线的对应的用户呢?
    2009年9月9日 15:18
  • 做法:假如 ajax请求的页面是Online.aspx
    Online.aspx的内容:

    protected void Page_Load(object sender, EventArgs e)
    {
      if (Page.User.Identity.IsAuthenticated)
        {
          String UserName = Page.User.Identity.Name;
          sql = "UPDATE User表 Set LastUpdated = getdate() WHere UserName = '" +  UserName + "'";
         cn.Exe......//将当前登录的用户状态进行更新。
         //如果还要返回所有在线的用户,则可以
        sql = "select * from User表 WHERE (DATEDIFF(n, LastUpdated, GETDATE()) < 5)";
       执行查询,返回所有的在线用户。
        }
    }

    一般这里只更新自己的在线状态,查看所有在线用户的一般是在另外的页面的。

    一般情况下下,上面的页面只更新当前用户的信息

    不要延迟。就可以得到所有在线的用户啊。


    【孟子E章】
    2009年9月9日 15:29
    版主
  •   ajax.aspx页面。。
      <script type="text/javascript">
        function doRequertUsingPOST(){
            $.ajax({
                type:"POST",
                url:"Online.aspx",
                data:"Name=admin",
                success:function(){}
            });
        }
        window.setInterval("doRequertUsingPOST()",600000); 


    那Online.aspx
    protected void Page_Load(object sender, EventArgs e)
    {
      if (Page.User.Identity.IsAuthenticated)
        {
          String UserName = Page.User.Identity.Name;
          sql = "UPDATE User表 Set LastUpdated = getdate() WHere UserName = '" +  UserName + "'";
    //前面的页面不发送请求了那Online.aspx页就接不到了。而且getdate() 把当前时间加进去了,之后再在下面读数据库出来?DATEDIFF(n, LastUpdated, GETDATE()) < 5?我还是有点不明白如何能判断到单个用户的在线离线哦而且。如果他在请求还没发送过来的情况下关闭浏览器了呢。。那不是误差好大?
          }
    }
    2009年9月9日 15:48
  • 如何能判断到单个用户的在线离线哦??

     sql = "select * from User表 WHERE (DATEDIFF(n, LastUpdated, GETDATE()) < 5) And UserNamae='admin'";


    如果他在请求还没发送过来的情况下关闭浏览器了呢。。那不是误差好大?

    误差跟你发送请求之间的时间间隔有关系,间隔越大误差越大。但时间短,会占用更多的服务器资源。




    【孟子E章】
    2009年9月10日 1:26
    版主
  • 恩恩明白了。。呵呵谢谢了 。
    2009年9月10日 3:24