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

时间:2024-10-06 14:33:26

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

  废话少说上代码。

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

  

 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ include file="/login/path.jsp"%> <html> <head>
<meta charset="utf-8">
<title>阿斯蒂芬</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="author" content="jQuery插件库(www.jq22.com)">
<meta name="weburl" content="http://www.jq22.com/">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="<%=basePath%>css/reset.css">
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="<%=basePath%>css/cS.css" media="only screen and (max-width:1024px)">
<link rel="stylesheet" type="text/css" href="<%=basePath%>css/qq.css" media="only screen and (min-width:1025px)">
</head> <body>
<input type="hidden" value="or-bevkBoF0HWRS3d4M2MAXdb9yE" id="openid" />
<div class="wrap">
<div class="menu">
<p>每天9:30-18:00在线</p>
<span>退出客服</span>
</div>
<div class="talk">
<div class="time">${dateTime }</div>
<div class="serviceCustom" id="APPContent">
<c:forEach items="${contentList}" var="contentList" varStatus="vs">
<div>
<p class="servicejiao"></p>
<p class="serviceword">${contentList.customerService_content }</p>
</div>
</c:forEach>
</div>
<!-- <div class="custom" id="faceImg"> </div> -->
</div>
<div class="downfoot">
<div class="up">
<span class="glyphicon glyphicon-apple emotion"></span>
<span id="chooseImage" class="glyphicon glyphicon-picture"></span>
</div>
<div class="down"> <input class="input" id="saytext" name="saytext" placeholder="输入新消息">
<button class="send sub_btn" type="button">发送</button>
</div>
</div>
</div>
<!-- ================================================================= --> <div class="qqBox">
<div class="BoxHead">
<div class="headImg">
<img src="<%=basePath%>arclist/logo.png"/>
</div>
<div class="internetName">阿斯顿发射点</div>
</div>
<div class="context">
<div class="conLeft">
<ul id="liContent">
<%-- <li class="bg">
<div class="liLeft"><img src="<%=basePath%>arclist/tx.png"/></div>
<div class="liRight">
<span class="intername">赵鹏1 </span>
<span class="badge">5</span>
<span class="infor">[流泪]</span>
<!-- <input type="hidden" value="" id="valueNum"/> -->
</div>
</li> --%>
</ul>
</div>
<div class="conRight">
<div class="Righthead" id="name">
<!-- <div class="headName">赵鹏</div> -->
</div>
<div class="RightCont">
<ul class="newsList" id="PCContent"> </ul>
</div>
<div class="RightFoot">
<div class="emjon">
<ul>
<li><img src="<%=basePath%>arclist/1.gif"/></li>
<li><img src="<%=basePath%>arclist/2.gif"/></li>
<li><img src="<%=basePath%>arclist/3.gif"/></li>
<li><img src="<%=basePath%>arclist/4.gif"/></li>
<li><img src="<%=basePath%>arclist/5.gif"/></li>
<li><img src="<%=basePath%>arclist/6.gif"/></li>
<li><img src="<%=basePath%>arclist/7.gif"/></li>
<li><img src="<%=basePath%>arclist/8.gif"/></li>
<li><img src="<%=basePath%>arclist/9.gif"/></li>
<li><img src="<%=basePath%>arclist/10.gif"/></li>
<li><img src="<%=basePath%>arclist/11.gif"/></li>
<li><img src="<%=basePath%>arclist/12.gif"/></li>
<li><img src="<%=basePath%>arclist/13.gif"/></li>
<li><img src="<%=basePath%>arclist/14.gif"/></li>
<li><img src="<%=basePath%>arclist/15.gif"/></li>
<li><img src="<%=basePath%>arclist/16.gif"/></li>
<li><img src="<%=basePath%>arclist/17.gif"/></li>
<li><img src="<%=basePath%>arclist/18.gif"/></li>
<li><img src="<%=basePath%>arclist/19.gif"/></li>
<li><img src="<%=basePath%>arclist/20.gif"/></li>
<li><img src="<%=basePath%>arclist/21.gif"/></li>
<li><img src="<%=basePath%>arclist/22.gif"/></li>
<li><img src="<%=basePath%>arclist/23.gif"/></li>
<li><img src="<%=basePath%>arclist/24.gif"/></li>
<li><img src="<%=basePath%>arclist/25.gif"/></li>
<li><img src="<%=basePath%>arclist/26.gif"/></li>
<li><img src="<%=basePath%>arclist/27.gif"/></li>
<li><img src="<%=basePath%>arclist/28.gif"/></li>
<li><img src="<%=basePath%>arclist/29.gif"/></li>
<li><img src="<%=basePath%>arclist/30.gif"/></li>
<li><img src="<%=basePath%>arclist/31.gif"/></li>
<li><img src="<%=basePath%>arclist/32.gif"/></li>
<li><img src="<%=basePath%>arclist/33.gif"/></li>
<li><img src="<%=basePath%>arclist/34.gif"/></li>
<li><img src="<%=basePath%>arclist/35.gif"/></li>
<li><img src="<%=basePath%>arclist/36.gif"/></li>
<li><img src="<%=basePath%>arclist/37.gif"/></li>
<li><img src="<%=basePath%>arclist/38.gif"/></li>
<li><img src="<%=basePath%>arclist/39.gif"/></li>
<li><img src="<%=basePath%>arclist/40.gif"/></li>
<li><img src="<%=basePath%>arclist/41.gif"/></li>
<li><img src="<%=basePath%>arclist/42.gif"/></li>
<li><img src="<%=basePath%>arclist/43.gif"/></li>
<li><img src="<%=basePath%>arclist/44.gif"/></li>
<li><img src="<%=basePath%>arclist/45.gif"/></li>
<li><img src="<%=basePath%>arclist/46.gif"/></li>
<li><img src="<%=basePath%>arclist/47.gif"/></li>
<li><img src="<%=basePath%>arclist/48.gif"/></li>
<li><img src="<%=basePath%>arclist/49.gif"/></li>
<li><img src="<%=basePath%>arclist/50.gif"/></li>
<li><img src="<%=basePath%>arclist/51.gif"/></li>
<li><img src="<%=basePath%>arclist/52.gif"/></li>
<li><img src="<%=basePath%>arclist/53.gif"/></li>
<li><img src="<%=basePath%>arclist/54.gif"/></li>
<li><img src="<%=basePath%>arclist/55.gif"/></li>
<li><img src="<%=basePath%>arclist/56.gif"/></li>
<li><img src="<%=basePath%>arclist/57.gif"/></li>
<li><img src="<%=basePath%>arclist/58.gif"/></li>
<li><img src="<%=basePath%>arclist/59.gif"/></li>
<li><img src="<%=basePath%>arclist/60.gif"/></li>
<li><img src="<%=basePath%>arclist/61.gif"/></li>
<li><img src="<%=basePath%>arclist/62.gif"/></li>
<li><img src="<%=basePath%>arclist/63.gif"/></li>
<li><img src="<%=basePath%>arclist/64.gif"/></li>
<li><img src="<%=basePath%>arclist/65.gif"/></li>
<li><img src="<%=basePath%>arclist/66.gif"/></li>
<li><img src="<%=basePath%>arclist/67.gif"/></li>
<li><img src="<%=basePath%>arclist/68.gif"/></li>
<li><img src="<%=basePath%>arclist/69.gif"/></li>
<li><img src="<%=basePath%>arclist/70.gif"/></li>
<li><img src="<%=basePath%>arclist/71.gif"/></li>
<li><img src="<%=basePath%>arclist/72.gif"/></li>
<li><img src="<%=basePath%>arclist/73.gif"/></li>
<li><img src="<%=basePath%>arclist/74.gif"/></li>
<li><img src="<%=basePath%>arclist/75.gif"/></li>
</ul>
</div>
<div class="footTop">
<ul>
<li class="ExP"><img src="<%=basePath%>arclist/download-14.jpg"/></li>
<li><img src="<%=basePath%>arclist/download-18.jpg"/></li>
</ul>
</div>
<div class="inputBox">
<textarea id="dope" style="width: 99%;height: 75px; border: none;outline: none;" name="" rows="" cols=""></textarea>
<button class="sendBtn">发送(s)</button>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="<%=basePath%>js/touch-0.2.14.min.js"></script>
<script src="<%=basePath%>js/size.js"></script>
<script src="<%=basePath%>js/jquery.min.js"></script>
<script type="text/javascript" src="<%=basePath%>js/jquery.qqFace.js"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"> </script> <script>
(function(){
if (document.body.clientWidth<=1024){
$(".wrap").css("visibility","none");
$(".qqBox").css("visibility","hidden");
document.writeln("<script type=\"text/javascript\" src=\"../js/cS.js\"><\/script>");
}else {
$(".wrap").css("visibility","hidden");
$(".qqBox").css("visibility","none");
document.writeln("<script type=\"text/javascript\" src=\"../js/qq.js\"><\/script>");
}
})();
</script> </html>

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

  cs.js

  

     var ipt=$(".wrap .downfoot .down input");
var send=$(".wrap .downfoot .down .send");
var serviceCustom=$(".wrap .talk .serviceCustom");
var talk=$(".wrap .talk");
var menu=$(".wrap .menu");
var gif=$(".wrap .gif");
var gifSpan=$(".wrap .gif div span");
var sumTop=0; $(function(){
$('.emotion').qqFace({ id : 'facebox', assign:'saytext', path:'../arclist/' //表情存放的路径 }); ipt[0].oninput = function() {
if (ipt[0].value) {
send.css({
backgroundColor:"#b0070e"
})
}else {
send.css({
backgroundColor:"lightgray"
})
}
}
var websocket = null;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/jhmyManage/websocket/1");
}
else {
alert('当前浏览器 Not support websocket')
} //连接发生错误的回调方法
websocket.onerror = function () {
/*setMessageInnerHTML("WebSocket连接发生错误");*/
}; //连接成功建立的回调方法
websocket.onopen = function () {
/*setMessageInnerHTML("WebSocket连接成功");*/
} //接收到消息的回调方法
websocket.onmessage = function (event) {
setMessageInnerHTML(event.data);
} //连接关闭的回调方法
websocket.onclose = function () {
/*setMessageInnerHTML("WebSocket连接关闭");*/
} //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
closeWebSocket();
} //将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
if(innerHTML.indexOf("jhmyManage")>-1){
$("<div><p class=serviceJiao></p><p class=serviceWord><img src="+innerHTML+" border=0 /></p></div>").appendTo("#APPContent");
}else{
$("<div><p class=serviceJiao></p><p class=serviceWord>"+innerHTML+"</p></div>").appendTo("#APPContent");
}
} //关闭WebSocket连接
function closeWebSocket() {
websocket.close();
}
//发送消息
send.click(function(){
if (ipt[0].value){
var topOne=talk.height();
var str = $("#saytext").val();
var div=document.createElement("div");
// $(div).html(replace_em(str));
div.innerHTML='<p class="customJiao"></p><p class="customWord">'+replace_em(str)+'</p>';
serviceCustom[0].appendChild(div);
ipt[0].value="";
var topTwo=talk.height();
sumTop+=topOne-topTwo;
talk.animate({
top:sumTop+topTwo-topOne
},100);
send.css({
backgroundColor:"lightgray"
});
var openid = document.getElementById("openid").value;
websocket.send(str+","+"kehu"+","+openid);
}
}); }); //查看结果
function replace_em(str){
str = str.replace(/\</g,'&lt;');
str = str.replace(/\>/g,'&gt;');
str = str.replace(/\n/g,'<br/>');
str = str.replace(/\[em_([0-9]*)\]/g,'<img src="../arclist/$1.gif" border="0" />'); return str;
} // 上下滑动屏幕
touch.config.drag=true;
console.log(talk[0].style.top);
//定义初始位置
var disY=0;
//定义偏移量
var y=0;
touch.on(document,'touchstart touchmove',function(event){
event.preventDefault();
});
touch.on(talk,'drag',function(event){
y=disY+event.y;
if (y>menu.height()||$(".wrap").innerHeight()>talk.height()){
y=menu.height();
}else if (y<$(".wrap").innerHeight()-talk.height()){
y=$(".wrap").innerHeight()-talk.height();
} talk[0].style.top=y+'px';
});
touch.on(talk,'dragend',function(){
disY=y;
});

  qq.js文件

  

 var PCindex=0;//默认左侧打开的是第一个窗口
var websocket = null;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/jhmyManage/websocket/2");
}
else {
alerrt('当前浏览器 Not support websocket')
} //连接发生错误的回调方法
websocket.onerror = function () {
/*setMessageInnerHTML("WebSocket连接发生错误");*/
}; //连接成功建立的回调方法
websocket.onopen = function () {
/*setMessageInnerHTML("WebSocket连接成功");*/
} //接收到消息的回调方法
websocket.onmessage = function (event) {
setMessageInnerHTML(event.data);
} //连接关闭的回调方法
websocket.onclose = function () {
/*setMessageInnerHTML("WebSocket连接关闭");*/
} //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
closeWebSocket();
}
var ipt="";
//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
var re = /^[0-9]+.?[0-9]*$/;
var numif="";
var stringNum = innerHTML.split(",");
var intername=$(".qqBox .context .conLeft ul li .liRight .intername");
var ppppp=null;
if(intername.length==0){ if (re.test(stringNum[0])) {
$("<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");
$("<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");
}else{
$("<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");
$("<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");
}
$("<div class=headName>"+stringNum[2]+"</div>").appendTo("#name");
$("#PCContent>div")[0].showNum=1;
$("#liContent li")[0].children[1].children[1].innerHTML=$("#PCContent>div")[0].showNum;
showNum();
$("#PCContent>div").css("display","none");
}else{
for (let i=0;i<intername.length;i++){
if(intername[i].innerHTML==stringNum[2]){
if (re.test(stringNum[0])) {
$("<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]));
}else{
$("<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]));
$("#liContent li")[i].children[1].children[2].innerHTML=$("#PCContent>div")[i].lastChild.children[1].children[1].innerHTML;
}
$("#PCContent>div")[i].showNum+=1;
$("#liContent li")[i].children[1].children[1].innerHTML=$("#PCContent>div")[i].showNum; showNum();
//document.getElementById("contentUpdate").innerHTML=stringNum[0];
numif=1;
}
}
if(numif!=1){
/*$("<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");
$("<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");*/
if (!re.test(stringNum[1])) {
$("<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");
$("<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");
}else{
$("<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");
$("<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");
}
$("#PCContent>div")[$("#PCContent>div").length-1].showNum=1;
$("#liContent li")[$("#PCContent>div").length-1].children[1].children[1].innerHTML=$("#PCContent>div")[$("#PCContent>div").length-1].showNum;
showNum();
$("#PCContent>div").css("display","none");
}
} /*document.getElementById('PCContent').innerHTML += innerHTML + '<br/>';*/ $('.conLeft li').on('click',function(){
$(this).addClass('bg').siblings().removeClass('bg');
var intername=$(this).children('.liRight').children('.intername').text();
$('.headName').text(intername);
ipt=$(this).children('.liRight').children('input').val();
//$('.newsList').html('');
PCindex=$(this).index();
$($("#PCContent>div")[PCindex])[0].showNum=0;
console.log($($("#PCContent>div")[PCindex])[0].showNum);
$($("#PCContent>div")[PCindex]).css("display","block").siblings().css("display","none");
showNum();
$("#liContent li")[PCindex].children[1].children[1].style.display="none";
});
}
function showNum(){
for (let i=0;i<$("#liContent li").length;i++){
if ($($("#PCContent>div")[i])[0].showNum==0){
console.log($($("#PCContent>div")[i])[0].showNum);
$("#liContent li")[i].children[1].children[1].style.display="none";
}else {
console.log($($("#PCContent>div")[i])[0].showNum);
$("#liContent li")[i].children[1].children[1].style.display="block";
}
}
} //关闭WebSocket连接
function closeWebSocket() {
websocket.close();
} /* $('.conLeft li').on('click',function(){
$(this).addClass('bg').siblings().removeClass('bg');
var intername=$(this).children('.liRight').children('.intername').text();
$('.headName').text(intername);
//$('.newsList').html('');
});*/ $('.sendBtn').on('click',function(){
var news=$('#dope').val();
if(!news){
alert('不能为空');
}else{
$('#dope').val('');
var str='';
str+='<li>'+
'<div class="nesHead"><img src="../arclist/logo.png"/></div>'+
'<div class="news"><img class="jiao" src="../arclist/jiao.jpg"><span>'+news+'</span></div>'+
'</li>';
$($('.newsList>div')[PCindex]).append(str);
//setTimeout(answers,1000);
$('.conLeft').find('li.bg').children('.liRight').children('.infor').text(news);
$('.RightCont').scrollTop($('.RightCont')[0].scrollHeight );
longLong();
websocket.send(news+","+ipt);
}
});
var isSend=false;
$(document).keydown(function(event){
if (event.keyCode==13&&isSend){
var news=$('#dope').val();
console.log(news);
if(!news){
alert('不能为空');
}else{
$('#dope').val('');
var str='';
str+='<li>'+
'<div class="nesHead"><img src="../arclist/logo.png"/></div>'+
'<div class="news"><img class="jiao" src="../arclist/jiao.jpg"><span>'+news+'</span></div>'+
'</li>';
$($('.newsList>div')[PCindex]).append(str);
$('.conLeft').find('li.bg').children('.liRight').children('.infor').text(news);
$('.RightCont').scrollTop($('.RightCont')[0].scrollHeight );
longLong();
websocket.send(news+","+ipt);
}
isSend=false;
}
});
$(document).keyup(function(event){
if (event.keyCode==13&&!isSend){
isSend=true;
}
});
/*function answers(){
var arr=["你好"];
var aa=Math.floor((Math.random()*arr.length));
var answer='';
answer+='<li>'+
'<div class="answerHead"><img src="../arclist/tx.png"/></div>'+
'<div class="answers"><img class="jiao" src="../arclist/jiao.jpg">'+arr[aa]+'</div>'+
'</li>';
$('.newsList').append(answer);
$('.RightCont').scrollTop($('.RightCont')[0].scrollHeight );
}*/
$('.ExP').on('mouseenter',function(){
$('.emjon').show();
})
$('.emjon').on('mouseleave',function(){
$('.emjon').hide();
})
$('.emjon li').on('click',function(){
var imgSrc=$(this).children('img').attr('src');
var str="";
str+='<li>'+
'<div class="nesHead"><img src="../arclist/logo.png"/></div>'+
'<div class="news"><img class="jiao" src="../arclist/jiao.jpg"><img class="Expr" src="'+imgSrc+'"></div>'+
'</li>';
/*$('.newsList').append(str);*/
$($('.newsList>div')[PCindex]).append(str);
$('.emjon').hide();
$('.RightCont').scrollTop($('.RightCont')[0].scrollHeight );
longLong();
websocket.send(imgSrc+","+ipt);
});
function longLong(){
var news=document.querySelectorAll(".news");
for (let i=0;i<news.length;i++){
if (news[i].offsetWidth>=490){
news[i].parentNode.style.height=news[i].offsetHeight+"px";
}
}
}

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

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

  

  import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint; import com.bjth.bjthManage.web.customer.entity.customer;
import com.bjth.bjthManage.web.customer.util.customerActionUtil; /**
* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
*/
@ServerEndpoint("/websocket/{relationId}")
public class WebSocketTest {
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
private customerActionUtil customerUtil = new customerActionUtil(); //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
//private static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();
private static final Map<String,Object> webSocketSet = new HashMap<String,Object>();
private static final AtomicInteger connectionIds = new AtomicInteger(0);
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private final String nickname;
private static final String GUEST_PREFIX = "Guest";
public WebSocketTest() {
nickname = GUEST_PREFIX + connectionIds.getAndIncrement();
System.out.println(nickname+"==当前id值是");
}
/**
* 连接建立成功调用的方法
* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(@PathParam("relationId") int relationId,Session session){
this.session = session;
//webSocketSet.add(this); //加入set中
webSocketSet.put(nickname, this);
if(relationId==2){
webSocketSet.put("typeKefu", nickname);
} addOnlineCount(); //在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
} /**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(){
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
} /**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) {
String[] stringNum = message.split(",");
if(stringNum[0].contains("em")&&stringNum[1].equals("kehu")){
try {
String regEx="[^0-9]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(stringNum[0]);
List<customer> customerlist = customerUtil.getCustomerByOpenid(stringNum[2]);//这个是去数据库查找数据的。怎么存储数据等就看你们的性格 了。
String key = (String)webSocketSet.get("typeKefu");
WebSocketTest c = (WebSocketTest)webSocketSet.get(key);
try {
c.session.getBasicRemote().sendText(m.replaceAll("").trim()+","+nickname+","+customerlist.get(0).getMobile());
} catch (IOException e) {
webSocketSet.remove(c);
try {
c.session.close();
} catch (IOException e1) {
// Ignore
}
try {
sendMessage("发送信息失败");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
} catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
}else{
if(stringNum[1].equals("kehu")){
try {
List<customer> customerlist = customerUtil.getCustomerByOpenid(stringNum[2]);
String key = (String)webSocketSet.get("typeKefu");
WebSocketTest c = (WebSocketTest)webSocketSet.get(key);
try {
c.session.getBasicRemote().sendText(stringNum[0]+","+nickname+","+customerlist.get(0).getMobile());
} catch (IOException e) {
webSocketSet.remove(c);
try {
c.session.close();
} catch (IOException e1) {
// Ignore
}
try {
sendMessage("发送信息失败");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
} catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
}else{
WebSocketTest c = (WebSocketTest)webSocketSet.get(stringNum[1]);
try {
c.session.getBasicRemote().sendText(stringNum[0]);
} catch (IOException e) {
webSocketSet.remove(c);
try {
c.session.close();
} catch (IOException e1) {
// Ignore
}
try {
sendMessage("发送信息失败");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
} //群发消息
System.out.println("来自客户端的消息:" + message);
/*for (String key : webSocketSet.keySet()) {
WebSocketTest client = null ;
try {
client = (WebSocketTest) webSocketSet.get(key);
synchronized (client) {
client.session.getBasicRemote().sendText(message);
}
} catch (IOException e) {
webSocketSet.remove(client);
try {
client.session.close();
} catch (IOException e1) {
// Ignore
}
try {
sendMessage("发送信息失败");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
} */
} /**
* 发生错误时调用
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
System.out.println("发生错误");
error.printStackTrace();
} /**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
} public static synchronized int getOnlineCount() {
return onlineCount;
} public static synchronized void addOnlineCount() {
WebSocketTest.onlineCount++;
} public static synchronized void subOnlineCount() {
WebSocketTest.onlineCount--;
}
}

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

  效果图展示。

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

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

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

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