WebSocket协议概述(原生)

一、产生背景

在Web开发中,我们经常和HTTP协议打交道,它是一个请求-响应的通信方式。但是除了HTTP 2.0版本以外,服务器端是无法主动发送消息的,它只支持单向数据通信的方式。

如果要去实现一个以双向通信方式的简易聊天室,浏览器需要以一种轮询的方式去不停地发送AJAX请求更新数据,这样做会造成资源高消耗和低性能。于是WebSocket协议就这么诞生了,虽然它诞生的时间比HTTP协议晚,但它实现的功能比HTTP更加成熟和可靠。

WebSocket最初在HTML5规范中被引用为TCPConnection,作为基于TCP的套接字API的占位符。2008年6月,Michael Carter进行了一系列讨论,最终形成了称为WebSocket的协议。

二、特点

WebSocket是一种网络传输协议,可在单个TCP连接上进行全双工通信,位于OSI模型的应用层。

补充一个小知识:TCP上的连接通信分为半双工通信全双工通信单向通信三种方式。

目前大部分浏览器均已支持WebSocket,可以放心使用。

它主要特点如下:

  • 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小,而HTTP协议每次请求需要携带完整的头部。
  • 更强的实时性。支持全双工通信,低消耗,高性能。
  • 可以保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
  • 更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
  • 支持跨域。(这个太强了!)
  • 与 HTTP 协议有着良好的兼容性。默认端口也是80(ws)和443(wss),并且握手阶段采用 HTTP 协议中的Upgrade头来升级协议,支持HTTP代理和中介。
  • 可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
  • 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。

思考:从上面的特点可以看出,同样是应用层上的协议,WebSocket协议要比HTTP协议要优秀很多。所以,数据传输都用WebSocket协议它不香吗?(没得标准答案,我自己也要思考。我没有歧视HTTP协议的意思啊…😝)

三、客户端API介绍

WebSocket提供了用于创建和管理 WebSocket 连接以及可以通过该连接发送和接收数据的 API。

我们可以通过创建一个实例对象ws建立与本地服务器(localhost:8080)的WebSocket连接:

let ws = new WebSocket('ws://localhost:8080')

下面的案例和知识都会围绕这个实例对象来展开讲述。

3.1 常量

下表是WebSocket构造函数的原型中存在的一些常量介绍:

Constant Value
WebSocket.CONNECTING(正在连接中) 0
WebSocket.OPEN(连接已打开,可以通信) 1
WebSocket.CLOSING (连接正在关闭) 2
WebSocket.CLOSED (表示连接已经关闭,或者打开连接失败。) 3

WebSocketXMLHttpRequest对象很相似,它们都可以通过readyState属性来判断当前连接状态(XMLHttpRequest对象有5个状态)。

if (ws.readyState === WebSocket.OPEN) {
   
	// 连接建立后做点啥...
}

3.2 常见属性

  • WebSocket.bufferedAmount:是一个只读属性,用于返回已经被send方法放入队列中但还没有被发送到网络中的数据的字节数。一旦队列中的所有数据被发送至网络,则该属性值将被重置为0。但是,若在发送过程中连接被关闭,则属性值不会重置为0。它可以用来判断二进制数据发送是否结束
  • WebSocket.onclose:用于指定连接关闭后的回调函数。
  • WebSocket.onerror:用于指定连接失败后的回调函数。
  • WebSocket.onmessage:用于指定当从服务器接受到信息时的回调函数。
  • WebSocket.onopen:用于指定连接成功后的回调函数。
  • WebSocket.readyState: 只读属性,表示当前的连接状态。

3.3 方法

  • WebSocket.send:发送数据。数据类型只能是utf-8编码的字符串和二进制数据(BlobArrayBuffer)这两种。
  • WebSocket.close:关闭连接。

这里补充一个小知识:Blob对象和ArrayBuffer对象的区别在于前者用于操作二进制文件,而后者用于操作内存(模拟内存)。如果大家对这个小知识感兴趣可以去看这篇文章

结合上述提及的WebSocket的属性和方法,我给出一个浏览器端简单使用WebSocket的例子:

demo.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <input type="file" name="filename" />
    <button>关闭连接</button>

    <script>
      let ws = new WebSocket("ws://localhost:8080");
      let buffer = new ArrayBuffer(8
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值