在JSP或Servlet中获取session数量

开发 后端
用ASP,PHP,JSP等来实现在线人员名单的显示的实现原理

    很多网友都问如何制作社区的在线人员显示问题,这也是个老大难的问题。由于笔者已经学习和实践了这些方面的编程已经有很长一段时间了。不说是有技术,也算是有些经验了,在这些问题解决方面我也曾遇到比较多的问题,后来总是解决了。   
    这次和大家讲的不关是一个程序的代码实现,而更重要的就是一个原理和思想问题,因为如何大家都知道这个该如何去做的话,就不存在技术上的难题了,而只是一个语法上的不熟罢了。   
    其实判断用户是否登录很简单,只要在登录的程序加上   "把用户设为在线"   就行了,这可以用SQL的update来做也可以用其他的如对文本文件的追加来做。如何登录时是设置的可以COOIKE登录的话,你只要在浏览页面或是发表贴子等的页面,进行更新也可以。   
    其实网友认为难的就在于如何知道用户已经离开社区了。下面有几个初学网友会犯的错误。   
    错误方法一:   当然有的网友会做在社区里做个   "退出社区"   可有的用户比较忙或是手比较快,就会直接的关闭浏览器了。那么在程序看来此用户根本就没有退出社区。   
    错误方法二:   为了这样也有的网友以关闭浏览器为标准,例如每当用户直接关闭浏览页面时,用JavaScript执行一个unload事件,跳出一个窗口,来执行相就在的更新,这也许是解决直接关闭的问题。可是网友没有考虑到如果因为贴子或文章太长,用户想断了线后,再好好的看看,那么他正好是直接断线后,看完所有贴子或文章再关闭浏览器的呢。此时跳出窗口页面的程序就等于没有执行。   
    错误方法三:使用session为例,一般的服务器中都有Session的失效时间,如IIS中为20分钟,有的网友以Session为标准,来判断,这显然也是行不通的,结果会和错误方法二一样。   
    那么如果才是正确的方法呢。到现在为此还没有一种方便的和精确的方法,除非你用Job事务来做,当那几乎是不可能的,因为免费的,即使是收费的主页空间也不会让你这么做的。所以只能能过普通的命令来实现了。     
  不过它的局限性就在于不能精确,但是我们可以让他更加的接近于精确。   
  下面我们会以IIS环境下的SQL   SERVER服务器为例子。其他的如PHP+MYSQL,JSP+MS   SQL   SERVER等举一反三,几乎语句都不用怎么变。   
    例子中采用程序片段,例如用户在表users中,除了基本要有的用户名字段(name)等,要有online字段,可以用bit类型就可以了。还要有一个登录时间的字段logintime,和***操作时间的字段logouttime,都为datetime类型。详细的作用我们会在后面谈到。   
    首先在用户登录进入时,要生成一个Session("name")字段的值,或是cookies("club")("name")的值,以便于在进行操作时,让SQL在社区中任意页面都知道是哪个用户的记录。接着更新用户的下online字段和logintime字段,语句如下:   
    conn.execute("Update   users   set   online=1,logintime='"&now&"'   where   name='"&session("name")&"'")   
    这条语句的作用在于当用户登录时,就把用户在线设为真,再把当前操作时间设为现在。其次在用户进行贴子或文章浏览时,也要用此语句,因为这样才可能更加的准确些。   
  在这些语句的后面再加上一句。   
    conn.execute("Update   users   set   online=0   where   diffdate(""n"",logintime,'"&now()&"')>10")     
    这条语句的作用表示把用户***操作时间和当前时间相比较,如果大于10分钟的话,就会把这些用户都设为离线。   
    好了,其实关键的也就是这两条语句而以,是不是很简单?说了这么多,其实想让大家了解的就是实现的原理,而不是什么代码。相信大家现在也可以很简单的做出关于PHP+MYSQL和JSP+数据库的在线人员显示的程序来了。   
    ***可以用"select   name   from   users   where   online=1"来调用在线的用户了,然后显示出来当然也没问题了。呵。。。  


***************************
namespace OnlineCount
{
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

/// 


///Online 的摘要说明。
/// 

public class Online : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.Label Label1;

private void Page_Load(object sender, System.EventArgs e)
{
if (Application["online"] == null)
{
DataTable dtnew = new DataTable();
dtnew.Columns.Add("userid",typeof(string));
dtnew.Columns.Add("lastaccesstime",typeof(DateTime));
Application["online"] = dtnew;
}

//DataTable dt = (DataTable)Application["online"];
DataTable dt = Application["online"] as DataTable;
DataRow[] rows = dt.Select("userid='"+Session.SessionID+"'");
if (rows.Length == 1)
{
DataRow dr = rows[0];
dr["lastaccesstime"] = DateTime.Now;
}
else
{
DataRow dr = dt.NewRow();
dr["userid"] = Session.SessionID;
dr["lastaccesstime"] = DateTime.Now;
dt.Rows.Add(dr);
}
for(int i = 0 ; i < dt.Rows.Count; i++)
{
DataRow dr = dt.Rows[i];
TimeSpan t = DateTime.Now - Convert.ToDateTime(dr["lastaccesstime"]);
if (t.Seconds > 8)
{
dr.Delete();
}
}
dt.AcceptChanges();

this.Label1.Text = dt.Rows.Count.ToString();

}

#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}

/// 
///设计器支持所需的方法 - 不要使用代码编辑器
///修改此方法的内容。
/// 

private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
}
}


*********** OnlineUser.java ************

package org.sunxin.lesson.jsp.ch09.online;

import javax.servlet.*;
import java.io.*;
import javax.servlet.http.*;
import java.util.Enumeration;

public class OnlineUser extends HttpServlet
{
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
               throws ServletException,IOException
    {
        req.setCharacterEncoding("gb2312");
        String name=req.getParameter("user");
        String pwd=req.getParameter("password");
            
        if(null==name || null==pwd || name.equals("") || pwd.equals(""))
        {
            resp.sendRedirect("login.html");
        }
        else
        {
            HttpSession session=req.getSession();
            User user=(User)session.getAttribute("user");
            if(null==user || !name.equals(user.getName()))
            {
                user=new User(name);
                session.setAttribute("user",user);
            }
            
            resp.setContentType("text/html;charset=gb2312");
            PrintWriter out=resp.getWriter();
            
            out.println("欢迎用户"+name+"登录");
            UserList ul=UserList.getInstance();
            out.println("
当前在线的用户列表:
");
            Enumeration enums=ul.getUserList();
            int i=0;
            while(enums.hasMoreElements())
            {
                out.println(enums.nextElement());
                out.println("    ");
                if(++i==10)
                {
                    out.println("
");
                }
            }
            out.println("
当前在线的用户数:"+i);
            out.println("

退出登录");
            out.close();
        }
    }
    
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
               throws ServletException,IOException
    {
        doGet(req,resp);
    }
}

*********** LogoutServlet.java ************

package org.sunxin.lesson.jsp.ch09.online;

import javax.servlet.*;
import java.io.*;
import javax.servlet.http.*;

public class LogoutServlet extends HttpServlet
{
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
               throws ServletException,IOException
    {
        resp.setContentType("text/html;charset=gb2312");
        
        HttpSession session=req.getSession();
        User user=(User)session.getAttribute("user");
        session.invalidate();
        
        PrintWriter out=resp.getWriter();
        out.println("");
        out.println(user.getName()+",你已退出登录
");
        out.println("重新登录");
        out.println("");
        out.close();
    }
}


*********** User.java ************

package org.sunxin.lesson.jsp.ch09.online;

import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class User implements HttpSessionBindingListener
{
    private String name;
    private UserList ul=UserList.getInstance();
    
    public User()
    {
    }
    public User(String name)
    {
        this.name=name;
    }
    public void setName(String name)
    {
        this.name=name;
    }
    public String getName()
    {
        return name;
    }
    public void valueBound(HttpSessionBindingEvent event)
    {
        ul.addUser(name);
    }
    public void valueUnbound(HttpSessionBindingEvent event)
    {
        ul.removeUser(name);
    }
}

*********** UserList.java ************
package org.sunxin.lesson.jsp.ch09.online;

import java.util.Vector;
import java.util.Enumeration;

public class UserList
{
    private static final UserList userList=new UserList();
    private Vector v;
    
private UserList()
{
    v=new Vector();
}

public static UserList getInstance()
{
return userList;
}
    
    public void addUser(String name)
    {
        if(name!=null)
            v.addElement(name);
    }
    
    public void removeUser(String name)
    {
        if(name!=null)
            v.remove(name);
    }
    
    public Enumeration getUserList()
    {
        return v.elements();
    }
    
    public int getUserCount()
    {
        return v.size();
    }
}


****************************
Java代码的思路是将所有登陆用户放到集合中。
用户登陆成功就添加到用户列表,用户退出就从用户列表中移出。

lz 注意User类所实现的接口以及其中以下两个方法:

    //对象被绑定到session中时通知该对象
    public void valueBound(HttpSessionBindingEvent event)
    {
        ul.addUser(name);
    }

    //从session中删除对象时通知该对象
    public void valueUnbound(HttpSessionBindingEvent event)
    {
        ul.removeUser(name);
    }

【编辑推荐】

  1. 浅析Java Servlet构建系统
  2. HTTP Servlet应用编程接口介绍
  3. 再谈如何理解JSP和Servlet的概念
  4. 优化Servlet配置为web.xml瘦身
  5. ServletResponse是什么
责任编辑:王观 来源: 编程爱好者
相关推荐

2009-07-07 12:34:54

Servlet在ses

2009-07-07 11:18:59

JSP Servlet

2009-06-25 14:26:07

JSPJavaBeanServlet

2009-07-03 10:46:48

JSP ServletJavaBean

2009-07-06 15:57:56

获取数据库连接JSP

2009-06-29 16:19:57

JSP Servlet

2009-07-08 15:01:00

Servlet Ses

2009-08-10 09:19:28

Servlet JSP

2009-07-07 14:04:55

JSP入门

2009-07-02 09:56:24

导入事件驱动技术JSP Servlet

2009-07-06 15:41:14

JSP应用

2009-07-09 10:49:56

Servlet和JSP

2009-07-06 15:03:53

JSP向Servlet

2009-07-01 17:34:03

Servlet和JSP

2009-07-06 15:34:56

JSP和Servlet

2009-06-30 15:37:27

Servlet和JSP

2009-03-02 09:45:45

2009-07-03 14:16:30

JSP Servlet

2009-07-07 13:42:57

Servlet JSP

2010-12-10 14:24:02

JSPServlet
点赞
收藏

51CTO技术栈公众号