Websocket

WebSocket是什么

websocket是用来实现客户端和服务器之间数据通信的一种手段;即浏览器和服务器只需要建议一次连接,两者之间就可以实现双向数据传输

问题:已经有了HTTP协议,为什么还需要WebSocket?
HTTP协议的缺陷: 通信只能是客户端发起, 不具备服务器推送功能,也就是说服务器不能主动向客户端推送消息.
这种单向通信方式,需要使用[轮询]查询方式,每隔一段时间就发出一次询问,了解服务器有没有新的消息.这种方式效率很低,浪费资源。

WebSocket使用

  1. 建立连接
  • 使用WebSocket,通过构造函数实例化
// 构造一个 webSocket 对象
const socket = new WebSocket('ws://localhost:8080');
// const socket = new WebSocket('wss://localhost:8080');

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
};  
  • 实例化对象包含的属性


    image.png

每个属性的含义:

  • binaryType:使用二进制的数据类型连接;
  • bufferedAmount(只读):未发送至服务器的字节数;
  • extensions(只读):服务器选择的扩展;
  • onclose:用于指定连接关闭后的回调函数;
  • onerror:用于指定连接失败后的回调函数;
  • onmessage:用于指定当从服务器接受到信息时的回调函数;
  • onopen:用于指定连接成功后的回调函数;
  • protocol(只读):用于返回服务器端选中的子协议的名字;
  • readyState(只读):返回当前 WebSocket 的连接状态,共有 4 种状态:
       CONNECTING — 正在连接中,对应的值为 0;
       OPEN — 已经连接并且可以通讯,对应的值为 1;
       CLOSING — 连接正在关闭,对应的值为 2;
       CLOSED — 连接已关闭或者没有连接成功,对应的值为 3;
  • url(只读):返回值为当构造函数创建 WebSocket 实例对象时 URL 的绝对路径;

WebSocket方法
    send(data):通过 WebSocket 连接传输至服务器的数据队列,并根据所需要传输的数据的大小来增加 bufferedAmount 的值;
    close():关闭 WebSocket 连接,如果连接已经关闭,则此方法不执行任何操作;
WebSocket事件:    close:当一个 WebSocket 连接被关闭时触发,也可以通过 onclose 属性来设置;
    error:当一个 WebSocket 连接因错误而关闭时触发,也可以通过 onerror 属性来设置;
    message:当通过 WebSocket 收到数据时触发,也可以通过 onmessage 属性来设置;
    open:当一个 WebSocket 连接成功时触发,也可以通过 onopen 属性来设置;

  1. 项目中使用WebSocket
<script>
export default {
  data() {
    return {  
      socket: null,
      aliveTime: new Date().getTime(),
      checkTimer: null
    }
  },
  
  computed: {
    token() {
      return this.$store.getters.token
    }
  },
  
  beforeDestroy() {
    clearInterval(this.checkTimer)
    this.socket && this.socket.close()
  },
  
  mounted() {
   if (this.socket && this.socket.readyState === 1) {
    clearInterval(this.checkTimer)
    this.socket.close()
   }
   
   if (this.socket && this.socket.readyState === 3) {
      this.initWebSocket()
   }
   
   this.getData()
  },
  
  methods: {
    getData() {
      // ......
      this.initWebSocket()
    },
    
    initWebSocket() {
      if (typeof WebSocket === 'undefined') {
        this.$message({ message: '您的浏览器不支持WebSocket' })
        return false
      }
      
      this.checkTimer && clearInterval(this.checkTimer)
      this.socket && this.socket.close()
      this.aliveTime = new Date().getTime()
      const token = this.token.split('Bearer ')[1]
      
      const wsurl = `wss://${process.env.VUE_APP_DOMAIN}/ws?token=${token}`
      this.socket = new WebSocket(wsurl)
      this.socket.onmessage = this.websocketonmessage
      this.socket.onerror = this.websocketonerror
      
      this.checkTimer = setInterval(this.checkWebsocketAlive, 5 * 1000)
    },
    
    websocketonmessage(e) {
      const response = JSON.parse(e.data)
      if (response.message === 'success') {
        const data = response.data
        // 处理 data
      }
      // 这里的场景是服务端主动推数据,接收到消息说明连接正常
      if (response.message === 'connection alive') {
        this.aliveTime = new Date().getTime()
      }
    },
    
    websocketonerror() {
      clearInterval(this.checkTimer)
      this.socket.close()
    },
    checkWebsocketAlive() {
      const now = new Date().getTime()
      if (now - this.aliveTime > 60 * 1000) {
        this.aliveTime = now
        this.initWebSocket()
      }
    },
  }
}
</script>
  1. 应用场景
  • 即时聊天通信
  • 多玩家游戏
  • 在线协同编辑/编辑
  • 实时数据流的拉取与推送
  • 体育/游戏实况
  • 实时地图位置

解释:

即时Web应用程序:即时Web应用程序使用一个Web套接字在客户端显示数据,这些数据由后端服务器连续发送。在WebSocket中,数据被连续推送/传输到已经打开的同一连接中,这就是为什么WebSocket更快并提高了应用程序性能的原因。 例如在交易网站或比特币交易中,这是最不稳定的事情,它用于显示价格波动,数据被后端服务器使用Web套接字通道连续推送到客户端。

游戏应用程序:在游戏应用程序中,你可能会注意到,服务器会持续接收数据,而不会刷新用户界面。屏幕上的用户界面会自动刷新,而且不需要建立新的连接,因此在WebSocket游戏应用程序中非常有帮助。

聊天应用程序:聊天应用程序仅使用WebSocket建立一次连接,便能在订阅户之间交换,发布和广播消息。它重复使用相同的WebSocket连接,用于发送和接收消息以及一对一的消息传输。

参考
作者:你听得到11
链接:https://juejin.cn/post/7283311024978427961

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容