聊天室显示在线人数和已上线人数

一开始我是以为这两个很类似

是用同一种方法就能实现的

但是,实际上在线人数可以用session实现,而已上线人数应该用servletcontext实现.

也就是一个监听servletcontext,一个监听session

而且为了记录数据要另写一个类来记录(counter)

public class ContextListener implements ServletContextListener {
    public static final String NAME = "name";
    public static final String Talks = "talks";
    //static final 静态最终啥的玩意 其实就是放在application里的数据
    //Talks是服务器内部调用的 ContextListener.Talks
    //talks是web前端调用的 applicationScope.talks
    private StringBuilder talks = new StringBuilder();
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // TODO Auto-generated method stub
        sce.getServletContext().removeAttribute(NAME);
        sce.getServletContext().removeAttribute(Talks);
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // TODO Auto-generated method stub
        Counter c = new Counter();
        sce.getServletContext().setAttribute(NAME, c);
//在服务器创建的时候,建立了一个counter
        sce.getServletContext().setAttribute(Talks, talks);
    }

}



public class SessionListener implements HttpSessionListener{
    public static final String NAME = "name";
    private int count = 0;
    @Override
    public void sessionCreated(HttpSessionEvent hse) {
        // TODO Auto-generated method stub
        HttpSession httpSession = hse.getSession();
        ServletContext sc = httpSession.getServletContext();
        Counter c = (Counter) sc.getAttribute(ContextListener.NAME);
        String name = "游客" + count;
        while (!c.addNowNames(name)){
//加入成功则在counter里改变数据
//加入不成功,就改变count知道加入成功
            count++;
            name = "游客" + count;
        }
        
        httpSession.setAttribute(NAME,name);
        
        StringBuilder sb = (StringBuilder)sc
                .getAttribute(ContextListener.Talks);
        sb.append(String.format("%s加入了!%n",name));
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent hse) {
        // TODO Auto-generated method stub
        HttpSession httpSession = hse.getSession();
        ServletContext sc = httpSession.getServletContext();
        Counter c = (Counter) sc.getAttribute(ContextListener.NAME);
        String name = httpSession.getAttribute(NAME).toString();
        c.removeNowNames(name);
        StringBuilder chatInfo = (StringBuilder) sc
                .getAttribute(ContextListener.Talks);
        chatInfo.append(String.format("%s离开了!%n", name));
    }

}
用Serializable序列化来排序
public class Counter implements Serializable {

    private static final long serialVersionUID = 45354343L;
    private int allNames = 0;
    private Set<String> nowNames = new LinkedHashSet<String>();
    public Counter() {
    }

    public boolean addNowNames(String name) {
        boolean r = nowNames.add(name);
        //如果原来有这个名字 就已上线人数增加
        if (r) {
            allNames++;
        }
        return r;
    }
    public boolean renameNowNames(String oldName, String newName) {
        if (nowNames.contains(oldName)) {
            nowNames.remove(oldName);
        } else {
            return false;
        }
        if (nowNames.add(newName)) {
            return true;
        } else {
            nowNames.add(oldName);
            return false;
        }
    }

    public void removeNowNames(String name) {
        nowNames.remove(name);
    }
//必须要有getxxxxxx的方法才能在jsp里被提取到
    public int getNowNamesSize() {
//这个就是在线人数
        return nowNames.size();
    }

    public int getAllNames() {
        return allNames;
    }

    public Set<String> getNowNames() {
        return Collections.unmodifiableSet(nowNames);
    }
}
    <table align="center">
            <tr>
                <td colspan="2">
                <table align="center" cellspacing="10">
            <tr>
                <td>历史访问人数:${applicationScope.name.allNames }</td>
                <td>在线人数:${applicationScope.name.nowNamesSize }
                 <select>
                    <c:forEach items="${applicationScope.name.nowNames}" var="line">
                    <!-- line是nowNames的其中一个值 -->
                        <option>${line}</option>
                    </c:forEach>
                </select>
                </td>
            <td>欢迎:${sessionScope.name}</td>
        </tr>
        <tr>
            <td colspan="3"><textarea rows="20" cols="80">${applicationScope.talks}</textarea>
            </td>
        </tr>
    </table>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏函数式编程语言及工具

SDP(9):MongoDB-Scala - data access and modeling

    MongoDB是一种文件型数据库,对数据格式没有硬性要求,所以可以实现灵活多变的数据存储和读取。MongoDB又是一种分布式数据库,与传统关系数据库不同...

3904
来自专栏PPV课数据科学社区

【学习】七天搞定SAS(二):基本操作(判断、运算、基本函数)

SAS生成新变量 SAS支持基本的加减乘除,值得一提的是它的**代表指数,而不是^。 * Modify homegarden data set with ass...

4634
来自专栏一个会写诗的程序员的博客

禅与 JavaScript 编程艺术, Zen and The Art of JavaScript Programming禅与 JavaScript 编程艺术

Zen and The Art of JavaScript Programming

1201
来自专栏学海无涯

Java Web之Struts2访问Servlet API

方法一:直接获取 Map类型 Map request = (Map)Actioncontext.getContext().get("request"); Map...

2814
来自专栏我是攻城师

Fastjson解析嵌套Map例子

3945
来自专栏扎心了老铁

java优雅的使用elasticsearch api

本文给出一种优雅的拼装elasticsearch查询的方式,可能会使得使用elasticsearch的方式变得优雅起来,使得代码结构很清晰易读。 建立elast...

1.1K7
来自专栏Hongten

原来还有这样的记词方法_Java版记不规则动词_博主推荐

昨天在看一本英语书的不规则动词的时候,突然产生的灵感:就是想把这样记单词简单方式,用程序代码实现,然后,使用户可以与之进行交互

922
来自专栏LhWorld哥陪你聊算法

Hadoop源码篇--Reduce篇

Reduce文件会从Mapper任务中拉取很多小文件,小文件内部有序,但是整体是没序的,Reduce会合并小文件,然后套个归并算法,变成一个整体有序的文件。

2451
来自专栏菩提树下的杨过

恶心的0.5四舍五入问题

四舍五入是财务类应用中常见的需求,按中国人的财务习惯,遇到0.5统一向上进位,但是c#与java中默认的却不是这样。 见c#代码: 1 stat...

21310
来自专栏数据结构与算法

P2580 于是他错误的点名开始了

题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人。 他会一边搓炉石一边点名以至于有一天他连续点到了某个同学两次,然后正好被路过的校长发现了然后就是一顿欧拉欧拉...

3007

扫码关注云+社区

领取腾讯云代金券