websocket实现弹幕以及聊天
Message.vue
<template>
<div>
<div class="Mes-titie">
<b>憨 憨 家 族({{uNumber-1}}人在线)</b>
</div>
<div class="Mes-center" ref="message">
<p v-if="initMsg">{{initMsg}}</p>
<ul>
<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="Mes-buttom">
<textarea placeholder="请输入要发送的信息..." class="layui-textarea Mes-text" v-model="message" @keydown.enter="sendMsg"></textarea>
<button type="button" class="layui-btn Mes-send" @click="sendMsg">
<i class="layui-icon"></i>发送(S)
</button>
</div>
</div>
</template>
<script>
import pubsub from 'pubsub-js';
export default {
name:'Message',
data (){
return{
message:"",
initMsg:"",
msgList:[],
uNumber:0
}
},
methods:{
sendMsg(){
if(this.message === ""){
alert("发送消息不能为空");
}
else{
//发给APP组件,让APP组件发给服务器
pubsub.publish('sendMsg',this.message);
this.message = "";//清空消息
}
}
},
mounted(){//所有元素加载完成之后调用
//创建一个消息接收者
this.pub = pubsub.subscribe('init',(nsgName,data) => {
this.initMsg = data;
});
//接收信息
this.newUser = pubsub.subscribe('newUser',(nsgName,data) => {
//在数组后面追加对象
this.msgList.push(data);
setTimeout(() => {
//滚动条在最底部 设置滚动条的当前高度为最大高度
this.$refs.message.scrollTop = this.$refs.message.scrollHeight;
}, 500);
});
//接收总人数
this.userNumber = pubsub.subscribe('userNumber',(nsgName,data)=>{
this.uNumber=data;
});
},
beforeDestroy(){//组件摧毁时触发
//摧毁掉消息接收者,提高性能
pubsub.unsubscribe(this.pub);
pubsub.unsubscribe(this.newUser);
pubsub.unsubscribe(this.userNumber);
}
}
</script>
<style>
.Mes-titie{
width: 700px;
height: 50px;
float: left;
background-color: #bdbebd;
font-size: 25px;
text-align: center;
line-height: 50px;
color: #383a39;
}
.Mes-center{
width: 700px;
height: 650px;
float: left;
background-color: #DEDEDE;
overflow-y: auto;
/* 强制换行 */
word-wrap: break-word;
}
.Mes-buttom{
width: 700px;
height: 200px;
float: left;
background-color: rgb(255, 253, 253);
}
.Mes-send{
position: relative;
left:590px;
}
.Mes-text{
width: 694.5px;
height: 154px;
border: none;
}
</style>
UserList.vue
<template>
<div>
<div class="list-img"></div>
<div class="User-list"><br>
<ul>
<li v-for="ul in userList" :key="ul.userId"><i class="layui-icon "></i> <a href="#"> {{ul.userName}}</a></li>
<!-- <li><i class="layui-icon "></i> <a href="#">腊继强</a></li>
<li><i class="layui-icon "></i> <a href="#">马任</a></li>
<li><i class="layui-icon "></i> <a href="#">邓亚洲</a></li>
<li><i class="layui-icon "></i> <a href="#">牟正琪</a></li>-->
<li><i class="layui-icon "></i> <a href="#">文件助手</a></li>
</ul>
</div>
</div>
</template>
<script>
import pubsub from 'pubsub-js';
export default {
name:'UserList',
data(){
return{
userList:[]
}
},
mounted(){
//收到用户列表
this.userList = pubsub.subscribe('userList',(nsgName,data) => {
this.userList = data;
});
},
beforeDestroy(){//组件摧毁时触发
//摧毁掉消息接收者,提高性能
pubsub.unsubscribe(this.userList);
}
}
</script>
<style>
.list-img{
width: 80px;
height: 900px;
background-image: url("../assets/images/2.png");
background-size: 100% 100%;
float: left;
}
.User-list{
width: 220px;
height: 900px;
background-color:#e6e9e9;
float: left;
overflow-y: auto;
/* 强制换行 */
word-wrap: break-word;
}
.User-list ul li{
text-decoration: none;
list-style: none;
font-size: 20px;
color: rgb(70, 71, 71);
line-height: 35px;
margin-left: 10px;
margin-top: 8px;
}
/*滚动条样式*/
::-webkit-scrollbar {/*滚动条整体样式*/
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
height: 4px;
}
::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
border-radius: 5px;
background: rgba(0,0,0,0.2);
}
::-webkit-scrollbar-track {/*滚动条里面轨道*/
border-radius: 0;
background: rgba(0,0,0,0.1);
}
</style>
App.vue
<template>
<div id="app" class="box">
<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(){//当所有DOM元素渲染完成之后会调用
// ws:// ip地址 / 接口名称
var ws = new WebSocket("ws://10.22.10.206/ChatServer/淑芬");
ws.onopen = function(){//通道建立时触发
//通过pubsub 消息订阅插件发给mseeage组件 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组件。code来自接口定义
}else if(data.code == 2){//收到聊天信息
pubsub.publish('newUser',data);
//js去除标签
var temp = data.msg.replace(/<\/?.+?>/g, "");
var result = temp.replace(/ /g, "");//result为得到后的内容
//生成一个随机数,用来控制弹幕的速度
var speedRan = Math.ceil(Math.random()*10);
var item={
img:'static/title.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('userNumber',data.uNumber);
}else if(data.code == 4){//下线通知
pubsub.publish('newUser',data);
}else if(data.code == 5){//收到了用户列表
console.log(data.userMap);
pubsub.publish('userList',data.userMap);
}
}
ws.onclose = function(){//连接断开时触发
}
ws.onerror = function(){//通道异常时触发
}
window.onbeforeunload=function(){//关闭窗口连接下线
ws.close();
}
//接收消息组件发送给App组件
this.sendMsg = pubsub.subscribe('sendMsg',(nsgName,data) => {
//页面端websocket发送消息
ws.send(data);
});
},
beforeDestroy(){//组件摧毁时触发
//摧毁掉消息接收者,提高性能
pubsub.unsubscribe(this.sendMsg);
}
}
</script>
<style>
body{
background-color: #555555;
margin: 0px;
padding: 0px;
}
.box{
width: 1000px;
height: 900px;
background-color:antiquewhite;
margin: auto;
}
</style>
index.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>hellovue</title>
<link rel="stylesheet" href="static/layui/css/layui.css">
<script src="static/layui/layui.js"></script>
<!-- 弹幕插件 -->
<link rel="stylesheet" href="static/css/barrager.css">
<script src="http://libs.baidu.com/jquery/2.0.3/jquery.min.js"></script>
<script src="https://yaseng.org/jquery.barrager.js/dist/js/jquery.barrager.js"></script>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
|