赞
踩
很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。
在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
使用 WebSocket,还可以实现浏览器内多个标签页之间的通信,通信的标签页连接同一个服务器,发送消息到服务器后,服务器推送消息给所有连接的客户端。
sessionStorage.setItem('user', this.form.username)
<template> <div align="center"> <el-row style="width: 50%;"> <!-- 用户列表--> <el-col :span="6"> <el-card style="width: 100%;height: 800px"> <div style="text-align: center;font-size: 28px;margin-bottom: 10px">当前聊天室成员</div> <div style="height: 700px;overflow-y:auto;border:1px solid #000000;border-radius: 5px"> <div v-for="(item,index) in userList" :key="index" style="padding: 10px;margin-top: 10px;font-size: 20px"> {{item}} </div> </div> </el-card> </el-col> <!-- 聊天室--> <el-col :span="18"> <div style="width: 100%;"> <el-card style="width: 100%;height: 800px"> <div style="text-align: center;font-size: 28px;margin-bottom: 10px">一起聊天吧</div> <div style="width: 100%;height: 550px;border:1px solid #000000;border-radius: 5px;overflow-y:auto;margin-bottom: 10px"> <div v-for="(item,index) in msgList" :key="index"> <!-- {{item.from}}{{item.msg}}{{item.time}}--> <div align="right" v-if="item.from===user" style="color: dodgerblue">{{item.time}} {{item.msg}}<el-tag size="mini">{{item.from}}</el-tag></div> <div align="left" v-else style="color: coral"><el-tag size="mini" type="danger">{{item.from}}</el-tag>{{item.msg}} {{item.time}}</div> </div> </div> <el-input @keyup.enter.native="send" type="textarea" v-model="message.msg" :autosize="{ minRows: 2, maxRows: 4}" placeholder="请输入聊天内容"></el-input> <div align="right"> <el-button type="primary" style="margin-top: 10px" @click="send">发送</el-button> </div> </el-card> </div> </el-col> </el-row> </div> </template> <script> let wx; export default { name: 'chat', data() { return { // 登录用户 user: '', // 消息记录列表 msgList: [], // 发送的消息 message: { time:null,//时间 to: '',//发给谁 from: '', msg: '' }, // 在线用户列表 userList: [] } }, methods: { init() { // 如果sessionStorage中没有用户信息,则跳转登录页面 this.user = sessionStorage.getItem('user') if (!this.user) { this.$router.push('/') } let that = this; if (typeof (WebSocket) == "undefined") { console.log("您的浏览器不支持WebSocket"); } else { console.log("您的浏览器支持WebSocket"); //服务器地址 let socketUrl = "ws://localhost:8888/socket/" + this.user; if (ws != null) { ws.close();//关闭连接 ws = null; } // 开启一个websocket服务 ws = new WebSocket(socketUrl); //打开事件 ws.onopen = function () {//服务器连接成功 console.log("websocket已打开"); }; // 浏览器端收消息,获得从服务端发送过来的文本消息 ws.onmessage = function (msg) {//解析信息 console.log("收到数据====" + msg.data) let data = JSON.parse(msg.data) if (data.userNames) { // userNames存在则是有人登录,获取在线人员信息 that.userList = data.userNames } else { // userNames不存在则是有人发消息 that.msgList.push(data) } }; //关闭事件 ws.onclose = function () {//服务器连接关闭 console.log("websocket已关闭"); }; //发生了错误事件 ws.onerror = function () {//服务器连接出错 console.log("websocket发生了错误"); } } }, //点击发送事件 send() { if (!this.message.msg) { this.$message({ message: '大兄弟,请输入聊天消息!', type: 'warning' }); } else { if (typeof (WebSocket) == "undefined") { console.log("您的浏览器不支持WebSocket"); } else { console.log("您的浏览器支持WebSocket"); this.message.from=this.user; this.message.time=new Date().toLocaleTimeString(); ws.send(JSON.stringify(this.message));//发送请求 this.message.msg = ''; } } } }, mounted() { this.init() } } </script>
ws.readyState
// 0 正在链接中
// 1 已经链接并且可以通讯
// 2 连接正在关闭
// 3 连接已关闭或者没有链接成功
ws.url
// 是一个只读属性
//返回构造函数创建WebSocket实例对象时URL的绝对路径。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。