Web Socket的实现和应用

1,377 阅读2分钟

这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战

什么是WebSocket?

WebSocket 是HTML5 中的协议,支持持久连续,http 协议不支持持久性连接。Http1.0 和HTTP1.1 都不支持持久性的链接,HTTP1.1 中的keep-alive,将多个http 请求合并为 1 个

WebSocket 是什么样的协议,具体有什么优点?

HTTP 的生命周期通过Request 来界定,也就是Request 一个Response,那么在Http1.0 协议中,这次Http 请求就结束了。在Http1.1 中进行了改进,是的有一个connection: Keep-alive,也就是说,在一个Http 连接中,可以发送多个Request,接收多个Response。 但是必须记住,在Http 中一个Request 只能对应有一个Response,而且这个Response 是被动的,不能主动发起。 WebSocket 是基于Http 协议的,或者说借用了Http 协议来完成一部分握手,在握手阶段 与Http 是相同的。我们来看一个websocket 握手协议的实现,基本是2 个属性,upgrade, connection。

基本请求如下:
  • GET /chat HTTP/1.1
  • Host: server.example.com
  • Upgrade: websocket
  • Connection: Upgrade
  • Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
  • Sec-WebSocket-Protocol: chat, superchat
  • Sec-WebSocket-Version: 13
  • Origin: example.com
告诉服务器发送的是websocket
  1. 1.Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
  2. 2.Sec-WebSocket-Protocol: chat, superchat
  3. 3.Sec-WebSocket-Version: 13
其他特点包括:

(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源限制,客户端可以与任意服务器通信。

(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

应用(vue+WebSocket创建实现实时通讯)

创建websocket(构造函数)
let wsuri = this.$api.teaback.createWSChatListenUrl(tokenRet.listen_token);
websock = new WebSocket(wsuri);
websock.onopen

实例对象的onopen属性,用于指定连接成功后的回调函数

websock.onopen = this.websocketonopen;

async websocketonopen() {
      console.log("WebSocket连接成功");
      this.imgStatus = true;
      this.callKeepAlive();
},
websock.onclose

实例对象的onclose属性,用于指定连接关闭后的回调函数。

//关闭连接
    async websocketclose(e) {
      console.log("断开连接", e);
      websock = null;
      this.imgStatus = false;
      setTimeout(this.initWebSocket, restart_time);
      this.killKeepAlive();
    },
websock.onmessage

实例对象的onmessage属性,用于指定收到服务器数据后的回调函数。

//接收后端返回的数据
    async websocketonmessage(e) {
      let data = e.data;
    },
websock.send()

实例对象的send()方法用于向服务器发送数据。

callKeepAlive() {
      this.killKeepAlive();
      keepalive_id = setInterval(function () {
        if (websock) websock.send("keepalive");
      }, 9000);
      if (websock) websock.send("keepalive");
    },
websock.onerror

实例对象的onerror属性,用于指定报错时的回调函数

//连接建立失败重连
    async websocketonerror(e) {
      console.log(`连接失败的信息:`, e);
      //this.initWebSocket() // 连接失败后尝试重新连接
      this.imgStatus = false;
      websock = null;
      this.killKeepAlive();
      if (!exitFlag) setTimeout(this.initWebSocket, restart_time);
    },