网络请求之Web Socket

982 阅读3分钟

微信公众号:  [大前端驿站]
关注大前端驿站。问题或建议,欢迎公众号留言。 这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

Web Socket(套接字)的目标是通过一个长时连接实现与服务器全双工、双向的通信。在 JavaScript中创建 Web Socket 时,一个 HTTP 请求会发送到服务器以初始化连接。服务器响应后,连接使用 HTTP的 Upgrade 头部从 HTTP 协议切换到 Web Socket 协议。这意味着 Web Socket 不能通过标准 HTTP 服务器实现,而必须使用支持该协议的专有服务器。Web Socket 得到了所有主流浏览器支持。

因为 Web Socket使用了自定义协议,所以 URL方案(scheme)稍有变化:不能再使用 http:// 或 https:// ,而要使用 ws:// 和 wss:// 。对比HTTP协议,优点在于客户端和服务器之间可以发送非常少的数据,使用更小的数据包让 Web Socket 非常适合带宽和延迟问题比较明显的移动应用。缺点是定义协议的时间比定义JavaScript API 要长

创建

要创建一个新的 Web Socket,就要实例化一个 WebSocket 对象并传入提供连接的 URL:

let socket = new WebSocket("ws://www.example.com/server.php")

注意,必须给 WebSocket 构造函数传入一个绝对 URL。 同源策略不适用于 Web Socket,因此可以打开到任意站点的连接 浏览器会在初始化 WebSocket 对象之后立即创建连接。

发送数据

要向服务器发送数据,使用 send()方法并传入一个字符串、ArrayBuffer 或 Blob:

let socket = new WebSocket("ws://www.example.com/server.php")
let stringData = "Hello world!"
let arrayBufferData = Uint8Array.from(['f', 'o', 'o'])
let blobData = new Blob(['f', 'o', 'o'])
socket.send(stringData)
socket.send(arrayBufferData.buffer)
socket.send(blobData)

接收数据

服务器向客户端发送消息时,WebSocket 对象上会触发 message 事件。这个 message 事件与其他消息协议类似,可以通过 event.data 属性访问到有效载荷:

socket.onmessage = function(event) { 
 let data = event.data
 // 对数据执行某些操作
}

与通过 send()方法发送的数据类似,event.data 返回的数据也可能是 ArrayBuffer 或 Blob。这由 WebSocket 对象的 binaryType 属性决定,该属性可能是"blob"或"arraybuffer"。

发送请求

fetch()只有一个必需的参数 input。多数情况下,这个参数是要获取资源的 URL。这个方法返回一个Promise:

let r = fetch('/bar')
console.log(r); // Promise <pending>

请求完成、资源可用时,期约会解决为一个 Response 对象。这个对象是 API 的封装,可以通过它取得相应资源。获取资源要使用这个对象的属性和方法,掌握响应的情况并将负载转换为有用的形式:

fetch('bar.txt') 
 .then((response) => { 
 console.log(response)
 }); 
// Response { type: "basic", url: ... }

读取响应

读取响应内容的最简单方式是取得纯文本格式的内容,这要用到 text()方法:

fetch('bar.txt') 
 .then((response) => response.text()) 
 .then((data) => console.log(data))

readyState

WebSocket 也有一个readyState 属性表示当前状态。不过,这个值与 XHR 中相应的值不一样:

  • WebSocket.OPENING(0):连接正在建立。
  • WebSocket.OPEN(1):连接已经建立。
  • WebSocket.CLOSING(2):连接正在关闭。
  • WebSocket.CLOSE(3):连接已经关闭。

close()

任何时候都可以调用 close()方法关闭 Web Socket 连接:

socket.close()

调用 close()之后,readyState 立即变为 2(连接正在关闭),并会在关闭后变为 3(连接已经关闭)

事件

WebSocket 对象没有 readystatechange 事件,而是有与上述不同状态对应的其他事件:

  • open:在连接成功建立时触发。
  • error:在发生错误时触发。连接无法存续。
  • close:在连接关闭时触发。
let socket = new WebSocket("ws://www.example.com/server.php")
socket.onopen = function() { 
 alert("Connection established.")
}
socket.onerror = function() { 
 alert("Connection error.")
}
socket.onclose = function() { 
 alert("Connection closed.")
}



~~ 感谢观看

关注下方【大前端驿站】
让我们一起学,一起进步

【分享、点赞、在看】三连吧,让更多的人加入我们