websocket实现弹幕以及聊天

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">&#xe609;</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 ">&#xe612;</i> &nbsp; <a href="#"> {{ul.userName}}</a></li>
		<!-- <li><i class="layui-icon ">&#xe66f;</i> &nbsp; <a href="#">腊继强</a></li>
		<li><i class="layui-icon ">&#xe66f;</i> &nbsp; <a href="#">马任</a></li>
		<li><i class="layui-icon ">&#xe770;</i> &nbsp; <a href="#">邓亚洲</a></li>
		<li><i class="layui-icon ">&#xe66f;</i> &nbsp; <a href="#">牟正琪</a></li>-->
		<li><i class="layui-icon ">&#xe60a;</i> &nbsp; <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>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebSocket技术可以用来实现实时弹幕功能。以下是一个简单的WebSocket弹幕示例: 1. 前端代码 ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Websocket弹幕</title> <style> #barrage { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; pointer-events: none; } .barrage-item { position: absolute; top: 0; white-space: nowrap; font-size: 20px; color: white; text-shadow: 1px 1px 2px black; } </style> </head> <body> <canvas id="barrage"></canvas> <script> const canvas = document.getElementById('barrage'); const ctx = canvas.getContext('2d'); const width = canvas.width = window.innerWidth; const height = canvas.height = window.innerHeight; let barrageList = []; // 连接websocket服务器 const ws = new WebSocket('ws://localhost:8080'); ws.onmessage = (event) => { const data = JSON.parse(event.data); barrageList.push({ text: data.text, x: width, y: Math.random() * height, color: data.color }); }; function draw() { ctx.clearRect(0, 0, width, height); for (let i = 0; i < barrageList.length; i++) { const item = barrageList[i]; ctx.fillStyle = item.color; ctx.fillText(item.text, item.x, item.y); item.x -= 3; } barrageList = barrageList.filter(item => item.x > -ctx.measureText(item.text).width); requestAnimationFrame(draw); } draw(); </script> </body> </html> ``` 2. 后端代码 ```javascript const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', (ws) => { console.log('connected'); ws.on('message', (message) => { console.log(`received: ${message}`); wss.clients.forEach(client => { if (client.readyState === WebSocket.OPEN) { client.send(message); } }); }); }); ``` 3. 使用方法 用户在前端页面上输入文本和颜色,点击发送按钮后,将文本和颜色发送给后端WebSocket服务器,服务器接收到消息后将消息广播给所有连接的客户端,客户端接收到消息后将消息添加到弹幕列表中,并在画布上绘制弹幕。 这是一个最基本的弹幕实现,实际中还需要考虑弹幕的速度、字体大小、弹幕屏蔽等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值