【注】:使用的是LayUI作为前端框架,实现网页聊天功能,部分包可能出现版本更迭无法使用
前端页面
<%--
Created by IntelliJ IDEA.
User: ZhuDi
Date: 2021/07/07
Time: 15:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<title>博客</title>
<link rel="stylesheet" href="../../res/layui/css/layui.css">
<script src="../../res/layui/layui.js"></script>
<script src="../../res/js/jquery.min.js"></script>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap v3.3.7 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- Font Awesome v4.7.0 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- Ionicons v2.0.0 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/ionicons/2.0.0/css/ionicons.min.css">
<!-- Theme style v2.4.2 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/admin-lte/2.4.2/css/AdminLTE.min.css">
<!-- DataTables v1.10.16 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/datatables/1.10.16/css/dataTables.bootstrap.min.css">
<!-- AdminLTE Skins.v2.4.2 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/admin-lte/2.4.2/css/skins/skin-blue.css">
<!-- jQuery UI CSS v1.12.1 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/jqueryui/1.12.1/jquery-ui.min.css">
<link rel="stylesheet" href="../../res/hk/css/blogdefault.css"/>
<!-- 百度地图 API -->
<script type="text/javascript"
src="http://api.map.baidu.com/getscript?v=2.0&ak=gh4PjU5UsCxml6vxPDmshSDaIWl63Vz8"></script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Google Font -->
<!--添加中科大CDN-->
<link rel="stylesheet"
href="https://fonts.lug.ustc.edu.cn/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
<style type="text/css">
/* Chart.js */
@-webkit-keyframes chartjs-render-animation {
from {
opacity: 0.99
}
to {
opacity: 1
}
}
@keyframes chartjs-render-animation {
from {
opacity: 0.99
}
to {
opacity: 1
}
}
.chartjs-render-monitor {
-webkit-animation: chartjs-render-animation 0.001s;
animation: chartjs-render-animation 0.001s;
}
*{
margin: 0;
padding: 0;
font-family: Arial, Helvetica,"Microsoft Yahei", sans-serif;
}
a{
text-decoration: none;
color: black;
}
input{
outline: none;
}
li{
list-style-type: none;
}
.hidden{
display: none;
}
.noRead{
color: green;
}
.Read{
color: gray;
}
.container{
border-radius: 4px;
border: 0.5px solid #e0e0e0;
background-color: #f5f5f5;
display: flex;
flex-flow: column;
overflow: hidden;
}
.content{
width: calc(100% - 5px);
padding: 20px;
overflow-y: scroll;
flex: 1;
}
.content:hover::-webkit-scrollbar-thumb{
background:rgba(0,0,0,0.1);
}
.bubble{
max-width: 400px;
padding: 10px;
border-radius: 5px;
position: relative;
color: #000;
word-wrap:break-word;
word-break:normal;
}
.item-left .bubble{
margin-left: 15px;
background-color: #fff;
}
.item-left .bubble:before{
content: "";
position: absolute;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-top: 10px solid transparent;
border-right: 10px solid #fff;
border-bottom: 10px solid transparent;
left: -20px;
}
.item-right .bubble{
margin-right: 15px;
background-color: #9eea6a;
}
.item-right .bubble:before{
content: "";
position: absolute;
width: 0;
height: 0;
border-left: 10px solid #9eea6a;
border-top: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
right: -20px;
}
.item{
margin-top: 15px;
display: flex;
}
.item.item-right{
justify-content: flex-end;
}
.item.item-center{
justify-content: center;
}
.item.item-center span{
font-size: 12px;
padding: 2px 4px;
color: #fff;
background-color: #dadada;
border-radius: 3px;
-moz-user-select:none; /*火狐*/
-webkit-user-select:none; /*webkit浏览器*/
-ms-user-select:none; /*IE10*/
-khtml-user-select:none; /*早期浏览器*/
user-select:none;
}
.avatar img{
width: 42px;
height: 42px;
border-radius: 50%;
}
.input-area{
border-top:0.5px solid #e0e0e0;
height: 150px;
display: flex;
flex-flow: column;
background-color: #fff;
}
textarea{
flex: 1;
padding: 5px;
font-size: 14px;
border: none;
cursor: pointer;
overflow-y: auto;
overflow-x: hidden;
outline:none;
resize:none;
}
.button-area{
display: flex;
height: 40px;
margin-right: 10px;
line-height: 40px;
padding: 5px;
justify-content: flex-end;
}
.button-area button{
width: 80px;
border: none;
outline: none;
border-radius: 4px;
float: right;
cursor: pointer;
}
/* 设置滚动条的样式 */
::-webkit-scrollbar {
width:10px;
}
/* 滚动槽 */
::-webkit-scrollbar-track {
-webkit-box-shadow:inset006pxrgba(0,0,0,0.3);
border-radius:8px;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
border-radius:10px;
background:rgba(0,0,0,0);
-webkit-box-shadow:inset006pxrgba(0,0,0,0.5);
}
</style>
</head>
<body onload="load()" style="background-color:whitesmoke;overflow-y: scroll">
<jsp:include page="../common/nav.jsp"></jsp:include>
<div style="margin: -25px auto;position:relative;height: 85%;width: 65%;background-color: white;border-radius: 10px;box-shadow: -1px 1px 10px #999999;">
<%-- 左侧开始--%>
<div id="leftpart" style="background-color: #2e2e2e;float: left;width: 30%;height: 100%;border-radius: 10px 0 0 10px">
<div id="uchat" style="position: absolute;height: 72px;width: 65%;line-height: 72px;">
<img src="${sessionScope.UserInfo.UImg}" style="height: 48px;width: 48px;border-radius: 48px;margin-left: 15px" alt="">
<text style="margin-left: 18px;color: white">${sessionScope.UserInfo.UNickName}</text>
</div>
<hr style="margin-top: 80px;border-bottom: rgba(255,255,255,0.5)"/>
<div id="chaters">
<div id="chat" style="height: 80px;line-height: 80px" onclick="showChat()">
<img id="chaterimg" src="" style="height: 40px;width: 40px;border-radius: 40px;margin-left: 20px" alt="">
<div style="position:relative;">
<text id="chaternickname" style="margin-left: 5px;color: white;position: absolute;top: -70px;left: 80px;">${sessionScope.UserInfo.UName}</text>
<%-- 存放聊天信息--%>
<text id="chatnew" class="Read" style="position: absolute;top: -50px;left: 85px;font-size: 12px">暂无最新消息</text>
<text id="lastchattime" style="color: gray;position: absolute;top: -60px;left: 230px;font-size: 12px"></text>
</div>
<hr style="color: rgba(0,0,0,0.3);"/>
</div>
</div>
</div>
<%-- 左侧结束--%>
<%-- 右侧开始--%>
<div id="rightmenu" style="position: relative;background-color: white;float: right;width: 70%;height: 100%;border-radius: 0 10px 10px 0">
<div id="chatpage" class="container hidden" style="width: 100%;height: 100%;">
<div class="content">
<chatcontent id="chatcontent"></chatcontent>
</div>
<div class="input-area">
<textarea name="sendContent" id="sendContent"></textarea>
<div class="button-area">
<button id="send-btn" onclick="sendMsg()">发 送</button>
</div>
</div>
</div>
</div>
<%-- 右侧结束--%>
</div>
</body>
WebSocket业务处理
<script>
layui.use('element', function(){
var element = layui.element;
});
// websocket开始
var ws;
window.onload=function(){
ws = new WebSocket("ws://localhost:8080/WebSocket/"+${sessionScope.UserInfo.UId});
ws.onopen = function(){
console.log("===============WebSocket IS OPEN NOW===============");
var txt = "{'type':'上线了'}"
sendMsg(txt);//获取未读消息
};
}
document.onkeydown=function(event){
var e = event || window.event || arguments.callee.caller.arguments[0];
if (e && e.keyCode == 13) {
sendMsg();
}
};
function sendMsg(unread){
var msg = $('#sendContent').val(),
content;
console.log(msg)
/**
* 发送消息
*/
if(msg.length>0){
content = "{'msg':'"+msg+"',"+"'type':'send',"+"'receiverOpenId':'8'}";
ws.send(content);
var html = $('#chatcontent').html()+"<div class='item item-right'><div class='bubble bubble-right'>"+msg+"</div><div class='avatar'><img src='${sessionScope.UserInfo.UImg}' /></div></div>";
$('#chatcontent').html(html);
}else if(unread.length>0){
ws.send(unread);
}else{
alert("请输入文字");
}
/**
* 接收返回的消息
*/
ws.onmessage = function (res)
{
var ret = JSON.parse(res.data);
if(ret.code == '20000'){
$('#chaterimg').attr('src',ret.unReadMsg[0].sender.uImg);
$('#chaternickname').text(ret.unReadMsg[0].sender.uNickName);
$('#lastchattime').text(ret.unReadMsg[0].cIUpdatedTime.split(" ")[0]);
$('#chatnew').text("您有未读消息");
$('#chatnew').removeClass("Read");
$('#chatnew').addClass("noRead");
sessionStorage.setItem("UnRead",JSON.stringify(ret.unReadMsg));
}
};
}
window.onclose = function (){
close();
}
function close(){
/**
* 关闭连接
*/
ws.onclose = function(){
console.log("===============WebSocket IS CLOSED===============");
};
}
function showChat(){
$('#chatpage').removeClass('hidden');
// "<div class='item item-center'><span>你已添加了凡繁烦,现在可以开始聊天了。</span></div>"
var unread = JSON.parse(sessionStorage.getItem("UnRead"));
console.log(unread)
var html = "";
for(var i = 0;i<unread.length;i++){
html += "<div class='item item-center'><span>"+unread[i].cICreatedTime.split(".")[0]+"</span></div>"
+ "<div class='item item-left'><div class='avatar'><img src='"+unread[i].sender.uImg+"' /></div><div class='bubble bubble-left'>"+unread[i].cIContent+"</div></div>"
}
$('#chatcontent').html(html);
$('#chatnew').text("暂无最新消息");
$('#chatnew').removeClass("noRead");
$('#chatnew').addClass("Read");
}
</script>