WebSocket入门

171 阅读2分钟

一、为什么需要WebSocket

因为HTTP协议有一个缺陷:通信只能由客户端发起,HTTP协议做不到服务器主动向客户端推送消息,只能是客户端向服务器发出请求,服务器返回查询结果。

如果服务器有连续的状态变化,客户端想要获知,我们只能通过轮询(每隔一段时间发出一个请求,了解服务器有没有新的信息),但轮询的效率低浪费资源(需要不停建立连接或者HTTP连接始终打开,且HTTP请求可能包含较长的头部,但其中真正有效的数据可能只是很小的一部分),由此出现了WebSocket。

二、简介

WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。
浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

特点:

  1. 服务器和客户端间可以进行双向平等的对话
  2. 建立在TCP协议之上,服务器端的实现比较容易
  3. 与HTTP协议有良好的兼容性。
  4. 数据格式比较轻量,性能开销小,通信高效。
  5. 可以发送文本、二进制数据。
  6. 没有同源限制,客户端可以与任意服务器通信。
  7. 协议标识符是ws,如果加密则为wss,服务器网址是URL。

三、API

具体API参照MDN

1.WebSocket构造函数

<!--新建WebSocket实例,执行后客户端就会与服务器进行连接-->
var ws = new WebSocket('ws://localhost:8080')

2.ws.readyState

readyState属性返回实例对象的当前状态

  • CONNECTING:0, 表示正在连接
  • OPEN:1,表示连接成功,可以进行通信
  • CLOSING:2,表示连接正在关闭
  • CLOSED:3,表示连接已经关闭,或者打开连接失败

在不同的状态可以进行你的一些处理

3.事件

事件回调函数描述
openws.onopen连接建立时触发
messagews.onmessage客户端接收服务端数据时触发
errorws.onerror通信发生错误时触发
closews.onclose连接关闭时触发

4.方法

方法描述
ws.send()使用连接发送数据
ws.close()关闭连接

四、应用

以下是WebSocket在Vue中应用的例子

<script>
data () {
  return {
    lockReconnect: false,
    socketUrl: 'ws://yours url:80/something others',
    websocket: ''
  }
},
created () {
  this.initWebSocket()
},
destoryed () {
  this.websocketOnclose()
}
methods: {
  initWebSocket () {
  	<!-- 初始化WebSocket连接 -->
    this.websocket = new WebSocket(url)
    this.websocket.onopen = this.websocketOnopen
    this.websocket.onerror = this.websocketOnmessage
    this.websocket.onclose = this.websocketOnclose
  },
  websocketOnopen () {
    <!--WebSocket 已连接上,使用 send() 方法发送数据-->
    this.websocket.send("发送数据...")
  },
  websocketOnerror () {
    <!--连接出错-->
    this.reconnect()
  },
  websocketOnclose () {
    <!--关闭 websocket-->
    console.log("连接已关闭...");
    this.reconnect()
  },
  websocketOnmessage (evt) {
    let received_msg = JSON.parse(evt.data)
    console.log("数据已接收...")
  },
  reconnect () {
    const _this = this
    if (_this.lockReconnect) {
    return
   }
    _this.lockReconnect = true
    <!--没连接上会一直重连,设置延迟避免请求过多。-->
    setTimeout(() => {
      _this.initWebSocket()
      _this.lockReconnect = false
    }, 5000)
  },
  isJSON(str) {
  <!--判断是否为JSON格式-->
    if (typeof str === "string") {
      try {
        const obj = JSON.parse(str)
        if (typeof obj === "object" && obj) {
          return true
        } else {
          return false
        }
      } catch (e) {
        return false
      }
    }
  }
}
</script>