zoukankan      html  css  js  c++  java
  • ZT:ASP.NET 在线统计的研究 .

    其实刚进公司的时候就发现公司的OA系统上有在线统计功能,但那时候没有心情来研究这个东西,这不最近闲的慌,就研究了下它.

    这一研究,还真有满多学问在里面的.对于我个人的理解,在线统计的实时性不高,即一般不可能做到有人离开马上就改变在线人数的. 

    而离开又分两种情况:第一种是用户点击退出离开的,第二种是用户直接关闭浏览器的(即非正常离开的).

    第一种情况实时性要高点,好处理,毕竟是点击了退出按钮触发了事件的.而对于第二种情况的话,根本不存在实时性可言,而只能尽快的发现这个用户已经离开.

    首先新建一个Global.asax文件.在这个文件里面的Application_start中写:

    Hashtable ht = new Hashtable();
    Application[
    "UserName"= ht;

    Hashtable是一个键/值对,键用用户的登录名,值用用户活动的当前时间.(后面用到的Hashtable都是如此)

    在Session_end中写:

           Hashtable ht = (Hashtable)Application["UserName"];
            
    foreach (DictionaryEntry item in ht)
            
    {
                
    if (DateTime.Parse(item.Value.ToString()).AddSeconds(20.0< DateTime.Now)
                
    {
                    ht.Remove(item.Key);
                }

            }

    这里要补充说明下,有两种情况会触发Session_end事件.第一种是Session超时,第二种就是调用Session.Abandon()的时候.看到这里读者应该能猜到怎么处理用户非法离开的情况了把?没错,用户非法离开,那只能等Session超时了,然后就会触发Session_end事件,将Hashtable中该用户名删除.这里我们判断用户是不是非法离开的方法是,用用户最后一次活动时间加上20秒和当前时间进行比较,如果小的话,就表示用户已经离开了本站了.这里只是举例子,一般都不只20秒的.

    在登录按钮中写:

    protected void btnLogin_Click(object sender, EventArgs e)
        
    {
            SqlConnection conn 
    = new SqlConnection("server=localhost;database=test;uid=sa;pwd=");
            SqlCommand cmd 
    = conn.CreateCommand();
            conn.Open();
            cmd.CommandText 
    = "select * from UserInfo where username='" + txtUserName.Text + "' and userpwd='" + txtPwd.Text + "'";
            SqlDataReader sdr 
    = cmd.ExecuteReader();
            
    if (sdr.Read())
            
    {
                Session[
    "UserName"= txtUserName.Text;
                
    string str=DateTime.Now.ToString();
                Session[
    "Key"= str;
                Hashtable ht 
    = (Hashtable)Application["UserName"];
                ht.Add(txtUserName.Text,str);
                

                Response.Redirect("index.aspx");
            }

            
    else
            
    {
                Response.Write(
    "<script>alert('用户名或密码错误');</script>");
            }

        }
    index.aspx页面中有一个iframe和一个JS函数还有退出按钮需要注意.iframe的src是main.aspx,而main.aspx中的内容是在线统计信息.JS函数是用来不断的刷新这个IFRAME.
    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="index" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        
    <title>无标题页</title>
        
    <script>
        function getUser()
        
    {
            ifr.document.location.href
    =ifr.document.location.href;
            window.setTimeout(
    'getUser()',30000);
        }

        
    </script>
    </head>
    <body onload="getUser()">
        
    <form id="form1" runat="server">
        
    <div>
        
    <iframe id="ifr" name="ifr" src="main.aspx"></iframe>
            
    <asp:Button ID="btnCancle" runat="server" OnClick="btnCancle_Click" Text="退出" /></div>
        
    </form>
    </body>
    </html>
    index.aspx.cs中的退出按钮事件委托:
     protected void btnCancle_Click(object sender, EventArgs e)
        
    {
            Hashtable ht 
    = (Hashtable)Application["UserName"];
            
            ht.Remove(Session[
    "UserName"].ToString());
            Session.Clear();
            Session.Abandon();
            Response.Write(
    "<script>window.opener=null;window.close();</script>");
        }
    main.aspx.cs在page_load中写:
    if(!IsPostBack)
            
    {
                Session.Timeout 
    += 1;
                Response.Write(Session.Timeout);
                Response.Write(Session[
    "UserName"].ToString());
                
    if (Session["Key"].ToString() == DateTime.Now.ToString())
                
    {
                    Response.Write(
    "YES");
                }

                
    else
                
    {
                    Response.Write(
    "NO");
                }

                Hashtable ht 
    = (Hashtable)Application["UserName"];

                ht[Session[
    "UserName"].ToString()] = DateTime.Now.ToString();
                
    string str = "UserList:";
                
    string str1 = "";
                
    foreach (DictionaryEntry item in ht)
                
    {
                    str 
    += "|" + item.Value.ToString();
                    str1 
    += item.Key.ToString() + ",";
                }

                Response.Write(str);
                
                Response.Write(str1);
            }

    每被刷新一次,Session的过期时间就会加1分钟,这样做是为了区别当Session过期和用户点击退出同时成立的情况.

    只有当用户没有离开该页面,该页面才会被刷新,被刷新了Session过期时间就加1分钟.而用户直接关闭浏览器了该页面就不会被刷新,Session就会更早的过期.

  • 相关阅读:
    Codeforces Round #392 (Div. 2)
    hihocoder #1419 : 后缀数组四·重复旋律4
    hihocoder #1415 : 后缀数组三·重复旋律3
    LOJ #6284. 数列分块入门 8-分块(区间查询等于一个数c的元素,并将这个区间的所有元素改为c)
    LOJ #6283. 数列分块入门 7-分块(区间乘法、区间加法、单点查询)
    LOJ #6282. 数列分块入门 6-分块(单点插入、单点查询、数据随机生成)
    LOJ #6281. 数列分块入门 5-分块(区间开方、区间求和)
    LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)
    LOJ #6279. 数列分块入门 3-分块(区间加法、查询区间内小于某个值x的前驱(比其小的最大元素))
    LOJ #6278. 数列分块入门 2-分块(区间加法、查询区间内小于某个值x的元素个数)
  • 原文地址:https://www.cnblogs.com/qingshan/p/2114565.html
Copyright © 2011-2022 走看看