websocket做手机页面聊天与PC页面聊天一对一的即时通讯

时间:2024-02-23 07:06:08

  当时要写这个需求的时候,很头痛,手机端页面的客服功能,相当于QQ这样一个一对一聊天室功能了,瞬间蒙蔽的我也不知道用什么去写这个东西,一开始用ajax,定时器去写,写着写着发现这尼玛不在同一个页面怎么做数据传输,而且很难做到点对点信息聊天。郁闷了几个小时后决定用websocket试着去学习然后去写这个聊天功能。写到半截才知道网上客服功能都是买的叫IM即时通讯,网易云是1800一个月,当时就吐了一碗血,调调接口就行了,还写了三天左右的websocket,BOSS赶紧感激我每年给他活活省了21600.

  废话少说上代码。

  首先我们把PC端的页面代码跟手机端的页面代码放到一个jsp文件中去,根据屏幕的分辨率分别叫他们显示手机端页面或者PC端页面。

  

  1 <%@ page language="java" contentType="text/html; charset=UTF-8"
  2     pageEncoding="UTF-8"%>
  3 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
  4 <%@ include file="/login/path.jsp"%> 
  5 
  6 <html>
  7 
  8 <head>
  9     <meta charset="utf-8">
 10     <title>阿斯蒂芬</title>
 11     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
 12     <meta name="author" content="jQuery插件库(www.jq22.com)">
 13     <meta name="weburl" content="http://www.jq22.com/">
 14     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
 15     <link rel="stylesheet" href="<%=basePath%>css/reset.css">
 16     <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
 17     <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
 18     <link rel="stylesheet" href="<%=basePath%>css/cS.css" media="only screen and (max-width:1024px)">
 19     <link rel="stylesheet" type="text/css" href="<%=basePath%>css/qq.css" media="only screen and (min-width:1025px)">
 20 </head>
 21 
 22 <body>
 23 <input type="hidden" value="or-bevkBoF0HWRS3d4M2MAXdb9yE" id="openid" />
 24     <div class="wrap">
 25         <div class="menu">
 26             <p>每天9:30-18:00在线</p>
 27             <span>退出客服</span>
 28         </div>
 29         <div class="talk">
 30             <div class="time">${dateTime }</div>
 31             <div class="serviceCustom" id="APPContent">
 32                 <c:forEach items="${contentList}" var="contentList" varStatus="vs">
 33                    <div>
 34                       <p class="servicejiao"></p>
 35                       <p class="serviceword">${contentList.customerService_content }</p>
 36                    </div>
 37                 </c:forEach>
 38             </div>            
 39             <!-- <div class="custom" id="faceImg">
 40                 
 41             </div> -->
 42         </div>
 43         <div class="downfoot">
 44             <div class="up">
 45                 <span class="glyphicon glyphicon-apple emotion"></span>
 46                <span id="chooseImage" class="glyphicon glyphicon-picture"></span>
 47             </div>
 48             <div class="down">
 49                 
 50                 <input class="input" id="saytext" name="saytext" placeholder="输入新消息">
 51                 <button class="send sub_btn" type="button">发送</button>
 52             </div>
 53         </div>
 54     </div>
 55     <!-- ================================================================= -->
 56             
 57             <div class="qqBox">
 58             <div class="BoxHead">
 59                 <div class="headImg">
 60                     <img src="<%=basePath%>arclist/logo.png"/>
 61                 </div>
 62                 <div class="internetName">阿斯顿发射点</div>
 63             </div>
 64             <div class="context">
 65                 <div class="conLeft">
 66                     <ul id="liContent">
 67                         <%-- <li class="bg">
 68                             <div class="liLeft"><img src="<%=basePath%>arclist/tx.png"/></div>
 69                             <div class="liRight">
 70                                 <span  class="intername">赵鹏1 </span>
 71                                 <span class="badge">5</span>
 72                                 <span class="infor">[流泪]</span>
 73                                 <!-- <input type="hidden" value="" id="valueNum"/> -->
 74                             </div>
 75                         </li> --%>
 76                     </ul>
 77                 </div>
 78                 <div class="conRight">
 79                     <div class="Righthead" id="name">
 80                         <!-- <div class="headName">赵鹏</div> -->
 81                     </div>
 82                     <div class="RightCont">
 83                         <ul class="newsList" id="PCContent">
 84                         
 85                         </ul>
 86                     </div>
 87                     <div class="RightFoot">
 88                         <div class="emjon">
 89                             <ul>
 90                                 <li><img src="<%=basePath%>arclist/1.gif"/></li>
 91                                 <li><img src="<%=basePath%>arclist/2.gif"/></li>
 92                                 <li><img src="<%=basePath%>arclist/3.gif"/></li>
 93                                 <li><img src="<%=basePath%>arclist/4.gif"/></li>
 94                                 <li><img src="<%=basePath%>arclist/5.gif"/></li>
 95                                 <li><img src="<%=basePath%>arclist/6.gif"/></li>
 96                                 <li><img src="<%=basePath%>arclist/7.gif"/></li>
 97                                 <li><img src="<%=basePath%>arclist/8.gif"/></li>
 98                                 <li><img src="<%=basePath%>arclist/9.gif"/></li>
 99                                 <li><img src="<%=basePath%>arclist/10.gif"/></li>
100                                 <li><img src="<%=basePath%>arclist/11.gif"/></li>
101                                 <li><img src="<%=basePath%>arclist/12.gif"/></li>
102                                 <li><img src="<%=basePath%>arclist/13.gif"/></li>
103                                 <li><img src="<%=basePath%>arclist/14.gif"/></li>
104                                 <li><img src="<%=basePath%>arclist/15.gif"/></li>
105                                 <li><img src="<%=basePath%>arclist/16.gif"/></li>
106                                 <li><img src="<%=basePath%>arclist/17.gif"/></li>
107                                 <li><img src="<%=basePath%>arclist/18.gif"/></li>
108                                 <li><img src="<%=basePath%>arclist/19.gif"/></li>
109                                 <li><img src="<%=basePath%>arclist/20.gif"/></li>
110                                 <li><img src="<%=basePath%>arclist/21.gif"/></li>
111                                 <li><img src="<%=basePath%>arclist/22.gif"/></li>
112                                 <li><img src="<%=basePath%>arclist/23.gif"/></li>
113                                 <li><img src="<%=basePath%>arclist/24.gif"/></li>
114                                 <li><img src="<%=basePath%>arclist/25.gif"/></li>
115                                 <li><img src="<%=basePath%>arclist/26.gif"/></li>
116                                 <li><img src="<%=basePath%>arclist/27.gif"/></li>
117                                 <li><img src="<%=basePath%>arclist/28.gif"/></li>
118                                 <li><img src="<%=basePath%>arclist/29.gif"/></li>
119                                 <li><img src="<%=basePath%>arclist/30.gif"/></li>
120                                 <li><img src="<%=basePath%>arclist/31.gif"/></li>
121                                 <li><img src="<%=basePath%>arclist/32.gif"/></li>
122                                 <li><img src="<%=basePath%>arclist/33.gif"/></li>
123                                 <li><img src="<%=basePath%>arclist/34.gif"/></li>
124                                 <li><img src="<%=basePath%>arclist/35.gif"/></li>
125                                 <li><img src="<%=basePath%>arclist/36.gif"/></li>
126                                 <li><img src="<%=basePath%>arclist/37.gif"/></li>
127                                 <li><img src="<%=basePath%>arclist/38.gif"/></li>
128                                 <li><img src="<%=basePath%>arclist/39.gif"/></li>
129                                 <li><img src="<%=basePath%>arclist/40.gif"/></li>
130                                 <li><img src="<%=basePath%>arclist/41.gif"/></li>
131                                 <li><img src="<%=basePath%>arclist/42.gif"/></li>
132                                 <li><img src="<%=basePath%>arclist/43.gif"/></li>
133                                 <li><img src="<%=basePath%>arclist/44.gif"/></li>
134                                 <li><img src="<%=basePath%>arclist/45.gif"/></li>
135                                 <li><img src="<%=basePath%>arclist/46.gif"/></li>
136                                 <li><img src="<%=basePath%>arclist/47.gif"/></li>
137                                 <li><img src="<%=basePath%>arclist/48.gif"/></li>
138                                 <li><img src="<%=basePath%>arclist/49.gif"/></li>
139                                 <li><img src="<%=basePath%>arclist/50.gif"/></li>
140                                 <li><img src="<%=basePath%>arclist/51.gif"/></li>
141                                 <li><img src="<%=basePath%>arclist/52.gif"/></li>
142                                 <li><img src="<%=basePath%>arclist/53.gif"/></li>
143                                 <li><img src="<%=basePath%>arclist/54.gif"/></li>
144                                 <li><img src="<%=basePath%>arclist/55.gif"/></li>
145                                 <li><img src="<%=basePath%>arclist/56.gif"/></li>
146                                 <li><img src="<%=basePath%>arclist/57.gif"/></li>
147                                 <li><img src="<%=basePath%>arclist/58.gif"/></li>
148                                 <li><img src="<%=basePath%>arclist/59.gif"/></li>
149                                 <li><img src="<%=basePath%>arclist/60.gif"/></li>
150                                 <li><img src="<%=basePath%>arclist/61.gif"/></li>
151                                 <li><img src="<%=basePath%>arclist/62.gif"/></li>
152                                 <li><img src="<%=basePath%>arclist/63.gif"/></li>
153                                 <li><img src="<%=basePath%>arclist/64.gif"/></li>
154                                 <li><img src="<%=basePath%>arclist/65.gif"/></li>
155                                 <li><img src="<%=basePath%>arclist/66.gif"/></li>
156                                 <li><img src="<%=basePath%>arclist/67.gif"/></li>
157                                 <li><img src="<%=basePath%>arclist/68.gif"/></li>
158                                 <li><img src="<%=basePath%>arclist/69.gif"/></li>
159                                 <li><img src="<%=basePath%>arclist/70.gif"/></li>
160                                 <li><img src="<%=basePath%>arclist/71.gif"/></li>
161                                 <li><img src="<%=basePath%>arclist/72.gif"/></li>
162                                 <li><img src="<%=basePath%>arclist/73.gif"/></li>
163                                 <li><img src="<%=basePath%>arclist/74.gif"/></li>
164                                 <li><img src="<%=basePath%>arclist/75.gif"/></li>
165                             </ul>
166                         </div>
167                         <div class="footTop">
168                             <ul>
169                                 <li class="ExP"><img src="<%=basePath%>arclist/download-14.jpg"/></li>
170                                 <li><img src="<%=basePath%>arclist/download-18.jpg"/></li>
171                             </ul>
172                         </div>
173                         <div class="inputBox">
174                             <textarea id="dope" style="width: 99%;height: 75px; border: none;outline: none;" name="" rows="" cols=""></textarea>
175                             <button class="sendBtn">发送(s)</button>
176                         </div>
177                     </div>
178                 </div>
179             </div>
180         </div>
181 </body>
182 <script src="<%=basePath%>js/touch-0.2.14.min.js"></script>
183 <script src="<%=basePath%>js/size.js"></script>
184 <script  src="<%=basePath%>js/jquery.min.js"></script>
185 <script type="text/javascript" src="<%=basePath%>js/jquery.qqFace.js"></script>
186 <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"> </script> 
187 
188 <script>
189     (function(){
190         if (document.body.clientWidth<=1024){
191         $(".wrap").css("visibility","none");
192         $(".qqBox").css("visibility","hidden");
193         document.writeln("<script type=\"text/javascript\" src=\"../js/cS.js\"><\/script>");
194     }else  {
195         $(".wrap").css("visibility","hidden");
196         $(".qqBox").css("visibility","none");
197         document.writeln("<script type=\"text/javascript\" src=\"../js/qq.js\"><\/script>");
198     }
199     })();
211 </script>
212 
213 </html>

  当我初始化打开或者刷新这个页面的时候就会自动链接跟断开websocket。如果我以手机屏幕展现出来的时候他会只加载cs.js以PC端屏幕展现只会加载qq.js,下面分别是两个js文件内容。

  cs.js

  

  1     var ipt=$(".wrap .downfoot .down input");
  2     var send=$(".wrap .downfoot .down .send");
  3     var serviceCustom=$(".wrap .talk .serviceCustom");
  4     var talk=$(".wrap .talk");
  5     var menu=$(".wrap .menu");
  6     var gif=$(".wrap .gif");
  7     var gifSpan=$(".wrap .gif div span");
  8     var sumTop=0;
  9 
 10     
 11     
 12 $(function(){
 13     $(\'.emotion\').qqFace({
 14 
 15         id : \'facebox\', 
 16 
 17         assign:\'saytext\', 
 18 
 19         path:\'../arclist/\' //表情存放的路径
 20 
 21     });
 22 
 23     ipt[0].oninput = function() {
 24         if (ipt[0].value) {
 25             send.css({
 26                 backgroundColor:"#b0070e"
 27             })
 28         }else {
 29             send.css({
 30                 backgroundColor:"lightgray"
 31             })
 32         }
 33     }
 34     var websocket = null;
 35     //判断当前浏览器是否支持WebSocket
 36     if (\'WebSocket\' in window) {
 37         websocket = new WebSocket("ws://localhost:8080/jhmyManage/websocket/1");
 38     }
 39     else {
 40         alert(\'当前浏览器 Not support websocket\')
 41     }
 42 
 43     //连接发生错误的回调方法
 44     websocket.onerror = function () {
 45         /*setMessageInnerHTML("WebSocket连接发生错误");*/
 46     };
 47 
 48     //连接成功建立的回调方法
 49     websocket.onopen = function () {
 50         /*setMessageInnerHTML("WebSocket连接成功");*/
 51     }
 52 
 53     //接收到消息的回调方法
 54     websocket.onmessage = function (event) {
 55         setMessageInnerHTML(event.data);
 56     }
 57 
 58     //连接关闭的回调方法
 59     websocket.onclose = function () {
 60         /*setMessageInnerHTML("WebSocket连接关闭");*/
 61     }
 62 
 63     //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
 64     window.onbeforeunload = function () {
 65         closeWebSocket();
 66     }
 67 
 68     //将消息显示在网页上
 69     function setMessageInnerHTML(innerHTML) {
 74         if(innerHTML.indexOf("jhmyManage")>-1){
 75             $("<div><p class=serviceJiao></p><p class=serviceWord><img src="+innerHTML+" border=0 /></p></div>").appendTo("#APPContent");
 76         }else{
 77             $("<div><p class=serviceJiao></p><p class=serviceWord>"+innerHTML+"</p></div>").appendTo("#APPContent");
 78         }
 79     }
 80 
 81     //关闭WebSocket连接
 82     function closeWebSocket() {
 83         websocket.close();
 84     }
 85   //发送消息
 86     send.click(function(){
 87         if (ipt[0].value){
 88             var topOne=talk.height();
 89             var str = $("#saytext").val();
 90             var div=document.createElement("div");
 91             // $(div).html(replace_em(str));
 92             div.innerHTML=\'<p class="customJiao"></p><p class="customWord">\'+replace_em(str)+\'</p>\';
 93             serviceCustom[0].appendChild(div);
 94             ipt[0].value="";
 95             var topTwo=talk.height();
 96             sumTop+=topOne-topTwo;
 97             talk.animate({
 98                 top:sumTop+topTwo-topOne
 99             },100);
100             send.css({
101                 backgroundColor:"lightgray"
102             });
103             var openid = document.getElementById("openid").value;
104             websocket.send(str+","+"kehu"+","+openid);
105         }
106     });
107 
108 
143 
144 });
145 
146 //查看结果
147 function replace_em(str){
148     str = str.replace(/\</g,\'&lt;\');
149     str = str.replace(/\>/g,\'&gt;\');
150     str = str.replace(/\n/g,\'<br/>\');
151     str = str.replace(/\[em_([0-9]*)\]/g,\'<img src="../arclist/$1.gif" border="0" />\');
152     
153     return str;
154 }
155 
156     // 上下滑动屏幕
157     touch.config.drag=true;
158     console.log(talk[0].style.top);
159     //定义初始位置
160     var disY=0;
161     //定义偏移量
162     var y=0;
163     touch.on(document,\'touchstart touchmove\',function(event){
164         event.preventDefault();
165     });
166     touch.on(talk,\'drag\',function(event){
167         y=disY+event.y;
168         if (y>menu.height()||$(".wrap").innerHeight()>talk.height()){
169             y=menu.height();
170         }else if (y<$(".wrap").innerHeight()-talk.height()){
171             y=$(".wrap").innerHeight()-talk.height();
172         }                talk[0].style.top=y+\'px\';
173     });
174     touch.on(talk,\'dragend\',function(){
175         disY=y;
176     });

  qq.js文件

  

  1 var PCindex=0;//默认左侧打开的是第一个窗口
  2 var websocket = null;
  3     //判断当前浏览器是否支持WebSocket
  4     if (\'WebSocket\' in window) {
  5         websocket = new WebSocket("ws://localhost:8080/jhmyManage/websocket/2");
  6     }
  7     else {
  8         alerrt(\'当前浏览器 Not support websocket\')
  9     }
 10 
 11     //连接发生错误的回调方法
 12     websocket.onerror = function () {
 13         /*setMessageInnerHTML("WebSocket连接发生错误");*/
 14     };
 15 
 16     //连接成功建立的回调方法
 17     websocket.onopen = function () {
 18         /*setMessageInnerHTML("WebSocket连接成功");*/
 19     }
 20 
 21     //接收到消息的回调方法
 22     websocket.onmessage = function (event) {
 23         setMessageInnerHTML(event.data);
 24     }
 25 
 26     //连接关闭的回调方法
 27     websocket.onclose = function () {
 28         /*setMessageInnerHTML("WebSocket连接关闭");*/
 29     }
 30 
 31     //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
 32     window.onbeforeunload = function () {
 33         closeWebSocket();
 34     }
 35     var ipt="";
 36     //将消息显示在网页上
 37     function setMessageInnerHTML(innerHTML) {
 38         var re = /^[0-9]+.?[0-9]*$/;
 39         var numif="";
 40         var stringNum = innerHTML.split(",");
 41         var intername=$(".qqBox .context .conLeft ul li .liRight .intername");
 42         var ppppp=null;
 43         if(intername.length==0){
 44             
 45             if (re.test(stringNum[0])) {
 46                 $("<div><li><div class=answerHead><img src=\'../arclist/tx.png\' /></div><div class=answers><img class=jiao src=\'../arclist/jiao.jpg\' /><img class=Expr src=../arclist/"+stringNum[0]+".gif /></div></li></div>").appendTo("#PCContent");
 47                 $("<li class=bg><div class=liLeft><img src=../arclist/tx.png /></div><div class=liRight><span class=intername>"+stringNum[2]+"</span><span class=badge>0</span><span class=infor >[图片]</span><input type=hidden value="+stringNum[1]+" /></div></li>").appendTo("#liContent");
 48             }else{
 49                 $("<div><li><div class=answerHead><img src=\'../arclist/tx.png\' /></div><div class=answers><img class=jiao src=\'../arclist/jiao.jpg\' /><span>"+stringNum[0]+"</span></div></li></div>").appendTo("#PCContent");
 50                 $("<li class=bg><div class=liLeft><img src=../arclist/tx.png /></div><div class=liRight><span class=intername>"+stringNum[2]+"</span><span class=badge>0</span><span class=infor >"+stringNum[0]+"</span><input type=hidden value="+stringNum[1]+" /></div></li>").appendTo("#liContent");
 51             }
 52             $("<div class=headName>"+stringNum[2]+"</div>").appendTo("#name");
 53             $("#PCContent>div")[0].showNum=1;
 54             $("#liContent li")[0].children[1].children[1].innerHTML=$("#PCContent>div")[0].showNum;
 55             showNum();
 56             $("#PCContent>div").css("display","none");
 57         }else{
 58             for (let i=0;i<intername.length;i++){
 59                 if(intername[i].innerHTML==stringNum[2]){
 60                     if (re.test(stringNum[0])) {
 61                         $("<div><li><div class=answerHead><img src=\'../arclist/tx.png\' /></div><div class=answers><img class=jiao src=\'../arclist/jiao.jpg\' /><img class=Expr src=../arclist/"+stringNum[0]+".gif /></div></li></div>").appendTo($($("#PCContent>div")[i]));
 62                     }else{
 63                         $("<li><div class=answerHead><img src=\'../arclist/tx.png\' /></div><div class=answers><img class=jiao src=\'../arclist/jiao.jpg\' /><span>"+stringNum[0]+"</span></div></li>").appendTo($($("#PCContent>div")[i]));
 64                         $("#liContent li")[i].children[1].children[2].innerHTML=$("#PCContent>div")[i].lastChild.children[1].children[1].innerHTML;
 65                     }
 66                     $("#PCContent>div")[i].showNum+=1;
 67                     $("#liContent li")[i].children[1].children[1].innerHTML=$("#PCContent>div")[i].showNum;
 68                     
 69                     showNum();
 70                     //document.getElementById("contentUpdate").innerHTML=stringNum[0];
 71                     numif=1;
 72                 }
 73             }
 74             if(numif!=1){
 75                 /*$("<div><li><div class=answerHead><img src=\'../arclist/tx.png\' /></div><div class=answers><img class=jiao src=\'../arclist/jiao.jpg\' />"+stringNum[0]+"</div></li></div>").appendTo("#PCContent");
 76                 $("<li><div class=liLeft><img src=../arclist/tx.png /></div><div class=liRight><span class=intername>"+stringNum[2]+"</span><span class=badge>0</span><span class=infor id=contentUpdate>"+stringNum[0]+"</span><input type=hidden value="+stringNum[1]+" /></div></li>").appendTo("#liContent");*/
 77                 if (!re.test(stringNum[1])) {
 78                     $("<div><li><div class=answerHead><img src=\'../arclist/tx.png\' /></div><div class=answers><img class=jiao src=\'../arclist/jiao.jpg\' /><img class=Expr src=../arclist/"+stringNum[0]+".gif /></div></li></div>").appendTo("#PCContent");
 79                     $("<li class=bg><div class=liLeft><img src=../arclist/tx.png /></div><div class=liRight><span class=intername>"+stringNum[2]+"</span><span class=badge>0</span><span class=infor >[图片]</span><input type=hidden value="+stringNum[1]+" /></div></li>").appendTo("#liContent");
 80                 }else{
 81                     $("<div><li><div class=answerHead><img src=\'../arclist/tx.png\' /></div><div class=answers><img class=jiao src=\'../arclist/jiao.jpg\' />"+stringNum[0]+"</div></li></div>").appendTo("#PCContent");
 82                     $("<li class=bg><div class=liLeft><img src=../arclist/tx.png /></div><div class=liRight><span class=intername>"+stringNum[2]+"</span><span class=badge>0</span><span class=infor >"+stringNum[0]+"</span><input type=hidden value="+stringNum[1]+" /></div></li>").appendTo("#liContent");
 83                 }
 84                 $("#PCContent>div")[$("#PCContent>div").length-1].showNum=1;
 85                 $("#liContent li")[$("#PCContent>div").length-1].children[1].children[1].innerHTML=$("#PCContent>div")[$("#PCContent>div").length-1].showNum;
 86                 showNum();
 87                 $("#PCContent>div").css("display","none");
 88             }
 89         }
 90         
 91         /*document.getElementById(\'PCContent\').innerHTML += innerHTML + \'<br/>\';*/
 92         
 93         $(\'.conLeft li\').on(\'click\',function(){
 94             $(this).addClass(\'bg\').siblings().removeClass(\'bg\');
 95             var intername=$(this).children(\'.liRight\').children(\'.intername\').text();
 96             $(\'.headName\').text(intername);
 97             ipt=$(this).children(\'.liRight\').children(\'input\').val();
 98             //$(\'.newsList\').html(\'\');
 99             PCindex=$(this).index();
100             $($("#PCContent>div")[PCindex])[0].showNum=0;
101             console.log($($("#PCContent>div")[PCindex])[0].showNum);
102             $($("#PCContent>div")[PCindex]).css("display","block").siblings().css("display","none");
103             showNum();                    
104             $("#liContent li")[PCindex].children[1].children[1].style.display="none";
105         });
106     }
107     function showNum(){
108         for (let i=0;i<$("#liContent li").length;i++){
109             if ($($("#PCContent>div")[i])[0].showNum==0){
110                 console.log($($("#PCContent>div")[i])[0].showNum);
111                 $("#liContent li")[i].children[1].children[1].style.display="none";
112             }else {
113                 console.log($($("#PCContent>div")[i])[0].showNum);
114                 $("#liContent li")[i].children[1].children[1].style.display="block";
115             }
116         }
117     }
118 
119     //关闭WebSocket连接
120     function closeWebSocket() {
121         websocket.close();
122     }
123     
124    /* $(\'.conLeft li\').on(\'click\',function(){
125         $(this).addClass(\'bg\').siblings().removeClass(\'bg\');
126         var intername=$(this).children(\'.liRight\').children(\'.intername\').text();
127         $(\'.headName\').text(intername);
128         //$(\'.newsList\').html(\'\');
129     });*/
130     
131 
132     $(\'.sendBtn\').on(\'click\',function(){
133         var news=$(\'#dope\').val();
134         if(!news){
135             alert(\'不能为空\');
136         }else{
137             $(\'#dope\').val(\'\');
138             var str=\'\';
139             str+=\'<li>\'+
140                     \'<div class="nesHead"><img src="../arclist/logo.png"/></div>\'+
141                     \'<div class="news"><img class="jiao" src="../arclist/jiao.jpg"><span>\'+news+\'</span></div>\'+
142                 \'</li>\';
143             $($(\'.newsList>div\')[PCindex]).append(str);
144             //setTimeout(answers,1000); 
145             $(\'.conLeft\').find(\'li.bg\').children(\'.liRight\').children(\'.infor\').text(news);
146             $(\'.RightCont\').scrollTop($(\'.RightCont\')[0].scrollHeight );
147             longLong();
148             websocket.send(news+","+ipt);
149         }
150     });
151     var isSend=false;
152     $(document).keydown(function(event){
153         if (event.keyCode==13&&isSend){
154             var news=$(\'#dope\').val();
155             console.log(news);
156             if(!news){
157                 alert(\'不能为空\');
158             }else{
159                 $(\'#dope\').val(\'\');
160                 var str=\'\';
161                 str+=\'<li>\'+
162                         \'<div class="nesHead"><img src="../arclist/logo.png"/></div>\'+
163                         \'<div class="news"><img class="jiao" src="../arclist/jiao.jpg"><span>\'+news+\'</span></div>\'+
164                     \'</li>\';
165                 $($(\'.newsList>div\')[PCindex]).append(str);
166                 $(\'.conLeft\').find(\'li.bg\').children(\'.liRight\').children(\'.infor\').text(news);
167                 $(\'.RightCont\').scrollTop($(\'.RightCont\')[0].scrollHeight );
168                 longLong();
169                 websocket.send(news+","+ipt);
170             }
171             isSend=false;
172         }
173     });
174     $(document).keyup(function(event){
175         if (event.keyCode==13&&!isSend){
176             isSend=true;
177         }
178     });
179     /*function answers(){
180         var arr=["你好"];
181         var aa=Math.floor((Math.random()*arr.length));
182         var answer=\'\';
183         answer+=\'<li>\'+
184                     \'<div class="answerHead"><img src="../arclist/tx.png"/></div>\'+
185                     \'<div class="answers"><img class="jiao" src="../arclist/jiao.jpg">\'+arr[aa]+\'</div>\'+
186                 \'</li>\';
187         $(\'.newsList\').append(answer);    
188         $(\'.RightCont\').scrollTop($(\'.RightCont\')[0].scrollHeight );
189     }*/
190     $(\'.ExP\').on(\'mouseenter\',function(){
191         $(\'.emjon\').show();
192     })
193     $(\'.emjon\').on(\'mouseleave\',function(){
194         $(\'.emjon\').hide();
195     })
196     $(\'.emjon li\').on(\'click\',function(){
197         var imgSrc=$(this).children(\'img\').attr(\'src\');
198         var str="";
199         str+=\'<li>\'+
200                 \'<div class="nesHead"><img src="../arclist/logo.png"/></div>\'+
201                 \'<div class="news"><img class="jiao" src="../arclist/jiao.jpg"><img class="Expr" src="\'+imgSrc+\'"></div>\'+
202             \'</li>\';
203         /*$(\'.newsList\').append(str);*/
204         $($(\'.newsList>div\')[PCindex]).append(str);
205         $(\'.emjon\').hide();
206         $(\'.RightCont\').scrollTop($(\'.RightCont\')[0].scrollHeight );
207         longLong();
208         websocket.send(imgSrc+","+ipt);
209     });
210     function longLong(){
211         var news=document.querySelectorAll(".news");
212         for (let i=0;i<news.length;i++){
213             if (news[i].offsetWidth>=490){
214                 news[i].parentNode.style.height=news[i].offsetHeight+"px";
215             }
216         }
217     }

 

  每当你刷新页面的时候他会自动加载走后台你所定义的接口,不需要配置web.xml文件

  当我发送一条信息后会自动走后台然后创建一个只属于本窗口的相应id,没打开一个手机端窗口都有一个相应的唯一值,发送信息时统一去找PC端那个id,PC端发送消息时在拿着当前用户的id去找就行了。

  

  1   2 import java.io.IOException;
  3 import java.util.HashMap;
  4 import java.util.List;
  5 import java.util.Map;
  6 import java.util.concurrent.CopyOnWriteArraySet;
  7 import java.util.concurrent.atomic.AtomicInteger;
  8 import java.util.regex.Matcher;
  9 import java.util.regex.Pattern;
 10 
 11 import javax.websocket.*;
 12 import javax.websocket.server.PathParam;
 13 import javax.websocket.server.ServerEndpoint;
 14 
 15 import com.bjth.bjthManage.web.customer.entity.customer;
 16 import com.bjth.bjthManage.web.customer.util.customerActionUtil;
 17 
 18 /**
 19  * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 20  * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 21  */
 22 @ServerEndpoint("/websocket/{relationId}")
 23 public class WebSocketTest {
 24     //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
 25     private static int onlineCount = 0;
 26     private customerActionUtil customerUtil = new customerActionUtil();
 27 
 28     //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
 29     //private static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();
 30     private static final Map<String,Object> webSocketSet = new HashMap<String,Object>();  
 31     private static final AtomicInteger connectionIds = new AtomicInteger(0);  
 32     //与某个客户端的连接会话,需要通过它来给客户端发送数据
 33     private Session session;
 34     private final String nickname;
 35     private static final String GUEST_PREFIX = "Guest";
 36     public WebSocketTest() {  
 37         nickname = GUEST_PREFIX + connectionIds.getAndIncrement();
 38         System.out.println(nickname+"==当前id值是");
 39     } 
 40     /**
 41      * 连接建立成功调用的方法
 42      * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
 43      */
 44     @OnOpen
 45     public void onOpen(@PathParam("relationId") int relationId,Session session){
 46         this.session = session;
 47         //webSocketSet.add(this);     //加入set中
 48         webSocketSet.put(nickname, this);
 49         if(relationId==2){
 50             webSocketSet.put("typeKefu", nickname);
 51         }
 52         
 53         addOnlineCount();           //在线数加1
 54         System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
 55     }
 56 
 57     /**
 58      * 连接关闭调用的方法
 59      */
 60     @OnClose
 61     public void onClose(){
 62         webSocketSet.remove(this);  //从set中删除
 63         subOnlineCount();           //在线数减1
 64         System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
 65     }
 66 
 67     /**
 68      * 收到客户端消息后调用的方法
 69      * @param message 客户端发送过来的消息
 70      * @param session 可选的参数
 71      */
 72     @OnMessage
 73     public void onMessage(String message, Session session) {
 74         String[] stringNum = message.split(",");
 75         if(stringNum[0].contains("em")&&stringNum[1].equals("kehu")){
 76             try {
 77                 String regEx="[^0-9]";
 78                 Pattern p = Pattern.compile(regEx);   
 79                 Matcher m = p.matcher(stringNum[0]);   
 80                 List<customer> customerlist = customerUtil.getCustomerByOpenid(stringNum[2]);//这个是去数据库查找数据的。怎么存储数据等就看你们的性格 了。
 81                 String key = (String)webSocketSet.get("typeKefu");
 82                 WebSocketTest c = (WebSocketTest)webSocketSet.get(key);
 83                 try {  
 84                     c.session.getBasicRemote().sendText(m.replaceAll("").trim()+","+nickname+","+customerlist.get(0).getMobile());   
 85                 } catch (IOException e) {  
 86                     webSocketSet.remove(c); 
 87                     try {  
 88                         c.session.close(); 
 89                     } catch (IOException e1) {  
 90                         // Ignore  
 91                     }  
 92                     try {
 93                         sendMessage("发送信息失败");
 94                     } catch (IOException e1) {
 95                         // TODO Auto-generated catch block
 96                         e1.printStackTrace();
 97                     }
 98                 } 
 99             } catch (Exception e2) {
100                 // TODO Auto-generated catch block
101                 e2.printStackTrace();
102             }
103         }else{
104             if(stringNum[1].equals("kehu")){
105                 try {
106                     List<customer> customerlist = customerUtil.getCustomerByOpenid(stringNum[2]);
107                     String key = (String)webSocketSet.get("typeKefu");
108                     WebSocketTest c = (WebSocketTest)webSocketSet.get(key);
109                     try {  
110                         c.session.getBasicRemote().sendText(stringNum[0]+","+nickname+","+customerlist.get(0).getMobile());   
111                     } catch (IOException e) {  
112                         webSocketSet.remove(c); 
113                         try {  
114                             c.session.close(); 
115                         } catch (IOException e1) {  
116                             // Ignore  
117                         }  
118                         try {
119                             sendMessage("发送信息失败");
120                         } catch (IOException e1) {
121                             // TODO Auto-generated catch block
122                             e1.printStackTrace();
123                         }
124                     } 
125                 } catch (Exception e2) {
126                     // TODO Auto-generated catch block
127                     e2.printStackTrace();
128                 }
129             }else{
130                     WebSocketTest c = (WebSocketTest)webSocketSet.get(stringNum[1]);
131                     try {  
132                         c.session.getBasicRemote().sendText(stringNum[0]);   
133                     } catch (IOException e) {  
134                         webSocketSet.remove(c); 
135                         try {  
136                             c.session.close(); 
137                         } catch (IOException e1) {  
138                             // Ignore  
139                         }  
140                         try {
141                             sendMessage("发送信息失败");
142                         } catch (IOException e1) {
143                             // TODO Auto-generated catch block
144                             e1.printStackTrace();
145                         }
146                     } 
147             }
148         }
149         
150         //群发消息
151         System.out.println("来自客户端的消息:" + message);
152         /*for (String key : webSocketSet.keySet()) {  
153             WebSocketTest client = null ;  
154             try {  
155                 client = (WebSocketTest) webSocketSet.get(key);  
156                 synchronized (client) {  
157                     client.session.getBasicRemote().sendText(message);
158                 }  
159             } catch (IOException e) {
160                 webSocketSet.remove(client);  
161                 try {  
162                     client.session.close();  
163                 } catch (IOException e1) {  
164                     // Ignore  
165                 }  
166                 try {
167                     sendMessage("发送信息失败");
168                 } catch (IOException e1) {
169                     // TODO Auto-generated catch block
170                     e1.printStackTrace();
171                 } 
172             }  
173         }  */
174     }
175 
176     /**
177      * 发生错误时调用
178      * @param session
179      * @param error
180      */
181     @OnError
182     public void onError(Session session, Throwable error){
183         System.out.println("发生错误");
184         error.printStackTrace();
185     }
186 
187     /**
188      * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
189      * @param message
190      * @throws IOException
191      */
192     public void sendMessage(String message) throws IOException{
193         this.session.getBasicRemote().sendText(message);
194         //this.session.getAsyncRemote().sendText(message);
195     }
196 
197     public static synchronized int getOnlineCount() {
198         return onlineCount;
199     }
200 
201     public static synchronized void addOnlineCount() {
202         WebSocketTest.onlineCount++;
203     }
204 
205     public static synchronized void subOnlineCount() {
206         WebSocketTest.onlineCount--;
207     }
208 }

  信息返回到相应js到页面上。

  效果图展示。