zoukankan      html  css  js  c++  java
  • javaweb聊天小项目

    本人最近在学习一个javaweb聊天项目,在这个项目中所要实现的功能比较简单:实现登陆之后可以在里面进行选择对象进行聊天,在线人数和在线人员名称都可以即时显示,信息message可以时时更新在每一个登录页面中,管理员admin具有把普通用户user踢下线的功能,而自己刚刚整合了SSM(struts+spring+mybatis)框架,并且通过maven进行jar包管理,在这里虽说不能很好体现框架的优势,但也是麻雀虽小五脏俱全。下图是项目后台的文件列表:

     

    在这里,通过定义的监听器Mylistener使其在项目初始化的时候便声明一个Map<user,httpsession>,放在application中,用于在用户登录时保存用户相关信息,在管理员将用户踢下线的时候将Map中相对应的session的 invalidate()销毁并通过map.remove()清除即可,以下放在webchartAction中登录功能login()代码

    public String login() throws IOException{   
           List<user> list=new ArrayList<user>();
           String username=request.getParameter("username");
           String password=request.getParameter("password");
           user user=new user();
           user.setPassword(password);
           user.setUsername(username);
           session.setAttribute("username", username);
           list=userService.login(user);
           String message="";
           if (null!=application.getAttribute("message")) {
                 message=application.getAttribute("message")
                         .toString();    
           }
          System.out.println(username+"进来了");
           String i=username ;
           Map<user,HttpSession> userMap=(Map<user, HttpSession>) application.getAttribute("userMap");
           if(list.size()>0){  
           String kk=list.get(0).getType();
           session.setAttribute("type", kk);
           //判断list.get(0),即当前登录用户是否已经登录,若已经登录则不增加在线人数,并且不再重新保存session
           if (userMap.containsKey(list.get(0))!=true) {
               userMap.put(list.get(0), session);
               application.setAttribute("userMap", userMap);
             //记录在线人数
               int j=userMap.entrySet().size();
               application.setAttribute("mapcount",j);
           }
                        message+= "系统公告:<font color='gray'>"
                      + user.getUsername() + "走进了聊天室!</font><br>";          
                       application.setAttribute("message", message);
               return "login_success";
           }
           else
               return "login_fail";
           }

    管理员踢下线功能代码:

    public String kick() throws IOException{
           // 1.接收参数
           System.out.println("管理员要踢人啦");
           String username = request.getParameter("username");
           List<user> list=userService.queryUserList(username);
           user user1=list.get(0);
           System.out.println(user1);
           // 2.踢人:从userMap中将用户对应的session销毁.
           // 获得userMap集合(在线列表)
           Map<user, HttpSession> userMap = (Map<user, HttpSession>)application.getAttribute("userMap");
           // 获得这个用户对应的session.如何知道是哪个用户呢? id已经传递过来.去数据库中查询.
           // 重写user的equals 和 hashCode 方法 那么只要用户的id相同就认为是同一个用户   
          // 从map集合中获得用户的对应的session
           HttpSession session = userMap.get(user1);
           // 销毁session
           session.invalidate();
           //从usermap中将此用户删除
           userMap.remove(user1);
           //刷新在线人数
           int j=userMap.entrySet().size();
           application.setAttribute("mapcount",j);
           // 通过跳转到登录界面
           return "login_success";
        }

    下图是前端的文件列表

     

    以下是前端聊天界面的javascript中的代码

    <script type="text/javascript">
    var sysBBS = "<span style='font-size:14px; line-height:30px;'>欢迎光临心之语聊天室,请遵守聊天室规则,不要使用不文明用语。</span><br><span style='line-height:22px;'>";
        window.setInterval("showContent();",1000);
        window.setInterval("showOnLine();",1000);
        window.setInterval("check();",1000);
        // 相当于window.onload
         $(function(){
           showOnLine();
           showContent();
           check();
        });
        function check(){
           $.post("<%=path%>/webchart/webchart_check.action",function(data){
               if(data == 1){
                  // 提示用户下线了
                  alert("用户已经被踢下线了!");
                  // 回到登录页面!通过action跳转
                  window.location="webchart_loginfails.action";
               }
           });
        }
        // 显示在线人员列表
        function showOnLine(){
           // 异步发送请求 获取在线人员列表
           // Jquery发送异步请求
           $.post("<%=path%>/online.jsp?"+new Date().getTime(),function(data){
               // $("#online") == document.getElementById("online");
               $("#online").html(data);
           });
        }
       // 显示聊天的内容
          function showContent(){
           $.post("<%=path%>/webchart/webchart_getMessage.action",function(data){
               $("#content").html(sysBBS+data);
           });
        } 
        function set(selectPerson){ //自动添加聊天对象
           if(selectPerson != "<%=session.getAttribute("username")%>"){
                  form1.to.value=selectPerson;
           }else{
               alert("请重新选择聊天对象!");
           }
        }
        function send(){
           if(form1.to.value==""){
               alert("请选择聊天对象!");
               return false;
           }
           if(form1.content.value==""){
               alert("发送信息不可以为空!");
               form1.content.focus();
               return false;
           }
           // $("#form1").serialize():让表单中所有的元素都提交.
           // jquery提交数据.{id:1,name:aa,age:25}
           $.post("<%=path%>/webchart/webchart_sendMessage.action",$("#form1").serialize(),function(data){
               $("#content").html(sysBBS+data+"哈哈"+"</span>");
           });
        }
       function exit(){
           alert("欢迎您下次光临!");
           window.location.href="<%=path%>/index.jsp";
        }
        function checkScrollScreen(){
           if(!$("#scrollScreen").attr("checked")){
            $("#content").css("overflow","scroll");
            }else{
            $("#content").css("overflow","hidden");
                //当聊天信息超过一屏时,设置最先发送的聊天信息不显示
                //alert($("#content").height());
                $("#content").scrollTop($("#content").height()*2);
            }
            setTimeout('checkScrollScreen()',500);
        }
    </script>

    在上面的代码中,window.setInterval()是保证页面在一定时间间隔内自动刷新,这样保证信息的及时显现,id为“content”的便是信息sysBBS+message展示页面;

    以下代码是online.jsp中的table代码,用于展现现在人员的信息,并且通过判断用户的type是否为admin来决定是否可以出现踢下线的功能;

    在这个项目中,因为刚开始做这些小项目,我遇到的问题有很多,列出几条:

    1. 信息及时刷新问题,虽说通过window.setInterval()解决了,但是总感觉这样比较浪费资源,不知道是否可以有更好的办法去解决这个问题;
    2. Map中的键值对<user,httpsession>获取问题,通过这个可以保存登陆者的很多信息,包括session,但是在编码的时候发现获取了user,也就是sessionid,但是却不能获取相对应的session,后来通过百度查资料才发现需要重写实体类中的tostring()和Hascode()方法,不然读取的session一直为空,这样在销毁的时候就会报错。
    3. 在这个项目中,前期一直用火狐浏览器进行测试,后来在判断用户类型是否为admin而可以有踢下线的功能的时候,在同一个浏览器中的session一直被最近一个登录者的session刷新,导致判断的用户type一直是显示最近登陆的用户type,当用两个不同浏览器登陆的时候,这个问题就得到了解决,管理员可以删除普通用户,而普通用户不可以,我猜测这应该是session共享问题,在同一台机器的同一个浏览器测试不同登录人员登录同一个项目,之前的session会被后者登录所用的session给冲掉,这个问题需要注意;

    首次发博客,内容表述不够严谨,如果所讲述内容有二解,望能共同探讨;

  • 相关阅读:
    Codeforces 177G2 Fibonacci Strings KMP 矩阵
    Codeforces Gym100187C Very Spacious Office 贪心 堆
    Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
    AtCoder SoundHound Inc. Programming Contest 2018 E + Graph (soundhound2018_summer_qual_e)
    BZOJ3622 已经没有什么好害怕的了 动态规划 容斥原理 组合数学
    NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分
    Codeforces 555C Case of Chocolate 其他
    NOIP2017提高组Day2T3 列队 洛谷P3960 线段树
    NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp
    NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序
  • 原文地址:https://www.cnblogs.com/AsherBlog/p/5389918.html
Copyright © 2011-2022 走看看