Vue中使用WebSocket实现简单的聊天室

WebSocket

很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每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}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{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}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{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的绝对路径。

你可能感兴趣的:(前端,websocket,vue.js,javascript)