前端知识梳理(三)websocket

Posted by southrock on 2019-12-06

前言

由于后端大作业的要求,做一个前端聊天室,项目需求要用到websocket,想想自己听了这么久的websocket,却很少实际的使用到它,这次乘着这次机会,复习一波websocket的知识。

为什么

每次接触到个东西,在学习如何使用之前先问自己一个问题,为什么用它?就像之前工作室举行的hackweek比赛,许多大一的新生在自己的产品里用到了前端框架,看到他们在没有对JavaScript开发做一定了解的情况下,用着框架却仍然在繁琐地操作着dom,把函数暴露在全局作用域着,非常想让他们思考一个问题,为什么用框架。

当然,抛开题外话。我们已经有了HTTP协议,为什么又要在web引入一个websocket这么一个协议。

首先,我们知道,HTTP是基于TCP的,应用层上,通过请求和响应来传输数据,无状态的一种为C/S模型的通信协议。

虽然TCP是全双工的协议,但是HTTP为了简化模型设计,没有使用到TCP的全双工特性,请求和相应交替在连接上传输。然后,HTTP是没有状态的,服务端要识别客户端需要依赖cookie、session等辨识用户。

上述两点,虽然不算HTTP的缺点(这里吐槽后端的期中考试,在回答HTTP协议的缺点的时候答案竟然有无状态)只算是HTTP的特点,在当时历史环境下,只需要个简单可靠易用的协议,没有考虑到未来web端的应用越来越复杂,HTTP还是非常好的完成了其历史任务的。

HTTP的这几个特点,虽然不影响其是个优秀的协议,但的确对于我们这个产品的需求带来了真真切切的麻烦。如何解决服务器不能主动给我们发送新的聊天信息,使用HTTP的话就只能采取轮询的办法,这不但效率低下,还消耗着服务器的资源。

这也是websocket所补足的地方。接下来就让我们梳理一下websocket这个协议。

websocket

WebSocket协议在2008年诞生,2011年成为国际标准。其最大的特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,满足了我们这个项目的要求。

其他特点包括:

  1. 建立在 TCP 协议之上,服务器端的实现比较容易。
  1. 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
  1. 数据格式比较轻量,性能开销小,通信高效。
  1. 可以发送文本,也可以发送二进制数据。
  1. 没有同源限制,客户端可以与任意服务器通信。
  1. 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

对于服务器与客户端的双向通行,websocket相比HTTP有着非常大的优势。

api

构造函数

WebSocket(url[, protocols])

返回一个 WebSocket 对象

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
WebSocket.onclose //用于指定连接关闭后的回调函数

WebSocket.onerror // 用于指定连接失败后的回调函数

WebSocket.onmessage // 用于指定当从服务器接受到信息时的回调函数

WebSocket.onopen // 用于指定连接成功后的回调函数

WebSocket.protocol // 服务器选择的下属协议

WebSocket.readyState // 当前的链接状态

WebSocket.url // WebSocket 的绝对路径

方法

1
2
3
WebSocket.close([code[, reason]]) // 关闭当前链接

WebSocket.send(data) // 向服务器发送数据

示例

1
2
3
4
5
6
7
8
9
10
11
12
// 新建一个websocket链接
var socket = new WebSocket('ws://localhost:8080');

// 监听连接事件
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});

// 监听收到信息事件
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});

实践

To be continue