websocket聊天室
本文最后更新于2022.05.14-17:50
,某些文章具有时效性,若有错误或已失效,请在下方留言或联系涛哥。
前言
WebSocket ,HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,其使用简单,应用场景也广泛,不同开发语言都用种类繁多的实现,仅Java体系中,Tomcat,Jetty,Spring等都提供了对WS的API支持。本篇不做理论探究,仅自娱自乐,简单实现网页版的聊天室功能,在实际开发场景中变通使用即可。
代码实现
1,userList.vue
<template>
<div class="user-list">
<ul class="layui-menu" style="margin-top: -1px;">
<li v-for="ul in userList" :key="ul.userId">
<div class="layui-menu-body-title">
{{ul.userName}}
<button type="button" class="layui-btn layui-btn-danger">禁言</button>
</div>
</li>
</ul>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'UserList',
data(){
return{
userList:[]
}
},
mounted () {
//收到用户列表
this.userList=pubsub.subscribe('userList',(nsgNmae,data) => {
this.userList=data;
});
},
beforeDestroy(){//组件摧毁时触发
//摧毁掉消息接收者,提高性能
pubsub.unsubscribe(this.userList);
}
}
</script>
<style scoped>
.user-list{
width: 25%;
height: 100%;
float: left;
/* 垂直滚动条 */
overflow-y: auto;
overflow-x: hidden;
background-color:#A8DADC ;
}
.user-list ul li div{
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
/*滚动条样式*/
.user-list::-webkit-scrollbar {/*滚动条整体样式*/
width: 4px; /*高宽分别对应横竖滚动条的尺寸*/
height: 4px;
}
.user-list::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
border-radius: 5px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.2);
}
.user-list::-webkit-scrollbar-track {/*滚动条里面轨道*/
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,0.1);
}
</style>>
2,Message.vue
<template>
<div>
<div class="msg-title">
{{msgTitle}}({{uNum}}人在线)
</div>
<div class="msg-content">
<p v-if="initMsg">{{initMsg}}</p>
<ul ref="message">
<li v-for="(msg,index) in msgList" :key="index">
<template v-if="msg.code == 1">
<span>{{msg.sName}}</span> <span>时间:{{msg.time}}</span>
<p style="color:green;">{{msg.msg}}</p>
</template>
<template v-if="msg.code== 4">
<span>{{msg.sName}}</span> <span>时间:{{msg.time}}</span>
<p style="color:red;">{{msg.msg}}</p>
</template>
<!-- template 不会显示在页面上 一般搭配if使用 -->
<template v-if="msg.code == 2">
<span>时间:{{msg.time}}</span>
<p>{{msg.sName}}<b>说:</b> <span v-html="msg.msg"></span></p>
</template>
<br>
</li>
</ul>
</div>
<div class="send-msg">
<textarea name="desc" placeholder="请输入内容" class="layui-textarea send-content" v-model="msg" @keydown.enter="sendMsg"></textarea>
<button type="button" class="layui-btn send-btn" @click="sendMsg()" >
<i class="layui-icon"></i>
发 送
</button>
</div>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'Message',
data(){
return{
msgTitle:'websocket聊天室',
msg:'',
initMsg:'',
uNum:0,
msgList:[]
}
},
methods:{
sendMsg(){
console.log(this.msg);
//发给App组件让App组件发给服务器
pubsub.publish('sendMsg',this.msg);
this.msg="";
}
},
mounted(){//所有元素加载完成之后调用
//创建一个消息接收者
this.pub=pubsub.subscribe('init',(nsgNmae,data) => {
this.initMsg=data;
});
//接收新用户信息
this.newUser=pubsub.subscribe('newUser',(nsgNmae,data) => {
this.msgList.push(data);//在数组后面追加一个对象
setTimeout(() => {
this.$refs.message.scrollTop = this.$refs.message.scrollHeight;
}, 1000);
});
//接收总人数
this.userNum=pubsub.subscribe('userNum',(nsgNmae,data) => {
this.uNum=data;
});
},
beforeDestroy(){//组件摧毁时触发
//摧毁掉消息接收者,提高性能
pubsub.unsubscribe(this.pub);
pubsub.unsubscribe(this.newUser);
pubsub.unsubscribe(this.userNum);
}
}
</script>
<style scoped>
img{
width: 100px;
height: 100px;
}
.msg-title{
width: 75%;
height: 50px;
float: left;
text-align: center;
font-size: 25px;
line-height: 50px;
background-color: #E0FBFC;
}
.msg-content{
width: 75%;
height: 650px;
float: left;
/* 强制换行 */
word-wrap: break-word;
background-color: #fff;
}
.msg-content ul{
width: 100%;
height: 630px;
border-top: 1px solid #ccc;
/* 垂直滚动条 */
overflow-y: auto;
}
/*滚动条样式*/
.msg-content ul::-webkit-scrollbar {/*滚动条整体样式*/
width: 4px; /*高宽分别对应横竖滚动条的尺寸*/
height: 4px;
}
.msg-content ul::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
border-radius: 5px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.2);
}
.msg-content ul::-webkit-scrollbar-track {/*滚动条里面轨道*/
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,0.1);
}
.send-msg{
width: 75%;
height: 200px;
float: left;
background-color: #fff;
position: relative;
}
.send-btn{
position: absolute;
right: 15px;
bottom: 15px;;
}
.send-content{
height: 72%;
}
</style>>
3,App.vue
<template>
<div class="wechat">
<UserList/>
<Message/>
</div>
</template>
<script>
//引入组件
import UserList from './components/UserList.vue';
import Message from './components/Message.vue';
import pubsub from 'pubsub-js'
export default {
name: 'App',
components: {//注册组件
UserList,
Message
},
mounted(){
var ws = new WebSocket("ws://localhost:8080/websocket/ChatServer/aaa");
ws.onopen = function(){//通道建立时触发
//通过pubsub 消息订阅插件发给message组件 npm install pubsub-js -s
pubsub.publish('init',"与聊天服务器连接成功");
}
ws.onmessage = function(event){//收到服务器发送的消息时触发
//json字符串转对象
var data=JSON.parse(event.data);
if(data.code == 1){//接收有新人连接上来的信息
pubsub.publish('newUser',data);//把收到的信息发送给message组件
}else if(data.code == 2){//接收聊天消息
pubsub.publish('newUser',data);//把收到的信息发送给message组件
//js去除标签
var temp = data.msg.replace(/<\/?.+?>/g, "");
var result = temp.replace(/ /g, "");//result为得到后的内容
//生成一个随机数,用来控制弹幕的速度
var speedRan = Math.ceil(Math.random()*10);
var item={
img:'static/imgs/1.jpeg', //图片
info:result, //文字
href:'#', //链接
close:true, //显示关闭按钮
speed:speedRan, //延迟,单位秒,默认6
// bottom:70, //距离底部高度,单位px,默认随机
color:'#fff', //颜色,默认白色
old_ie_color:'#000000', //ie低版兼容色,不能与网页背景相同,默认黑色
}
//控制当弹幕量过大的处理
if($(".barrage").length < 30){
$('body').barrager(item);
}
}else if(data.code == 3){//接收聊天室总人数
pubsub.publish('userNum',data.uNumber);
}else if(data.code == 4){//下线通知
pubsub.publish('newUser',data);//把收到的信息发送给message组件
}else if(data.code == 5){//接收用户列表
pubsub.publish('userList',data.userMap);//把收到的信息发送给userlist组件
}
}
ws.onclose = function(){//连接断开时触发
}
ws.onerror = function(){//通道异常时触发
}
//接收消息组件发给App组件
this.sendMsg=pubsub.subscribe('sendMsg',(nsgNmae,data) => {
//页面段websocket发送信息
ws.send(data);
});
//当页面关闭时主动断开连接
window.onbeforeunload = function(){
ws.close();
}
},
beforeDestroy(){//组件摧毁时触发
//摧毁掉消息接收者,提高性能
pubsub.unsubscribe(this.sendMsg);
}
}
</script>
<style>
img{
width: 150px;
height: 150px;
}
body{
background-color: #D8E2DC;
}
.wechat{
width: 65%;
height: 900px;
background-color: #fff;
margin: 0 auto;
}
</style>>
4,layui
<link rel="stylesheet" type="text/css" href="static/layui/css/layui.css"/>
<link rel="stylesheet" href="static/css/barrager.css">
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="static/layui/layui.js" type="text/javascript" charset="utf-8"></script>
<script src="static/js/jquery.barrager.min.js" type="text/javascript" charset="utf-8"></script>
5,在config下的index文件的proxyTable:{}里添加跨域配置
'/websocket':{
target:"ws://192.168.1.188",
changeOrigin:true,
ws:true,//支持websocket
pathRewrite:{'^/websocket':''}
}
阅读剩余
版权声明:
作者:涛哥
链接:https://ltbk.net/front/vue/v2/article/152.html
文章版权归作者所有,未经允许请勿转载。
作者:涛哥
链接:https://ltbk.net/front/vue/v2/article/152.html
文章版权归作者所有,未经允许请勿转载。
THE END