本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net
目录
1、什么是 WebSocket
1、WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。
2、WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
3、在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
示例:WebSocket 是一种双向网络通信协议,与 HTTP 不同,它以 ws:// 或 wss:// 开头。它是一个有状态协议,这意味着客户端和服务器之间的连接将保持活动状态,直到被客户端或服务器中的任何一方关闭连接之后,连接将从两端终止。
WebSocket 使用了 HTTP/1.1 的协议升级特性,一个 WebSocket 请求首先使用非正常的 HTTP 请求以特定的模式访问一个 URL,这个 URL 有两种模式,分别是 ws 和 wss, 对应 HTTP 协议中的 HTTP 和 HTTPS。
①在请求头中有一个 Connection:Upgrade 字段,表示客户端想要对协议进行升级。
②另外还有一个 Upgrade:websocket 字段,表示客户端想要将请求协议升级为 WebSocket 协议。
③这两个字段共同告诉服务器要将连接升级为 WebSocket 这样一种全双工协议。
如果服务端同意协议升级,那么在握手完成之后,文本消息或者其他二进制消息就可以同时在两个方向上进行发送,而不需要关闭和重建连接。此时的客户端和服务端关系是对等的,它们可以互相向对方主动发送消息。
2、为什么需要 WebSocket
初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?
答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起。
举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。
这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用 "轮询",每隔一段时候,就发出一个询问,了解服务器有没有新的信息。轮询的效率低,非常浪费资源。因此,工程师们一直在思考,有没有更好的方法,WebSocket 就是这样发明的。
WebSocket 的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
因为一般的请求都是 HTTP 请求(单向通信),HTTP 是一个短连接(非持久化),且通信只能由客户端发起,HTTP 协议做不到服务器主动向客户端推送消息。举个例子:前后端交互就是前端发送请求,从后端拿到数据后展示到页面,如果前端没有主动请求接口,那后端就不能发送数据给前端。然而,WebSocket 确能很好的解决这个问题,服务端可以主动向客户端推送消息,客户端也可以主动向服务端发送消息,实现了服务端和客户端真正的平等。
轮询
轮询是最简单的一种解决方案,所谓轮询,就是客户端在固定的时间间隔下不停地向服务端发送请求,查看服务端是否有最新的数据,若服务端有最新的数据,则返回给客户端, 若服务端没有,则返回一个空的 JSON 或者 XML 文档。轮询对开发人员而言实现方便,但是弊端也很明显: 客户端每次都要新建 HTTP 请求, 服务端要处理大量的无效请求,在高并发场景下会严重拖慢服务端的运行效率,同时服务端的资源被极大的浪费了,因此这种方式并不可取。
长轮询
长轮询是传统轮询的升级版,当聪明的工程师看到轮询所存在的问题后,就开始解决问题,于是有了长轮询。不同于传统轮询,在长轮询中,服务端不是每次都会立即响应客户端的请求,只有在服务端有最新数据的时候才会立即响应客户端的请求,否则服务端会持有这个请求而不返回,直到有新数据时才返回。这种方式可以在一定程度上节省网络资源和服务器资源,但是也存在一些问题,例如:
如果浏览器在服务器响应之前有新数据要发送,就只能创建 - 一个新的并发请求,或者先尝试断掉当前请求,再创建新的请求。
TCP 和 HTTP 规范中都有连接超时一说,所以所谓的长轮询并不能一直持续, 服务端和客户端的连接需要定期的连接和关闭再连接,这又增大了程序员的工作量,当然也有一些技术能够延长每次连接的时间,但毕竟是非主流解决方案。
3、WebSocket 的特点
和传统的解决方案相比,WebSocket 主要有如下特点:
1、较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有 2 至 10 字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的 4 字节的掩码。相对于 HTTP 请求每次都要携带完整的头部,此项开销显著减少了。
2、更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于 HTTP 请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和 Comet 等类似的长轮询比较,其也能在短时间内更多次地传递数据。
3、保持连接状态。与 HTTP 不同的是,Websocket 需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而 HTTP 请求可能需要在每个请求都携带状态信息(如身份认证等)。
4、更好的二进制支持。Websocket 定义了二进制帧,相对 HTTP,可以更轻松地处理二进制内容。
5、可以支持扩展。Websocket 定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
6、更好的压缩效果。相对于 HTTP 压缩,Websocket 在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。
7、WebSocket 使用时需要先创建连接,这使得 WebSocket 成为一种有状态的协议,在之后的通信过程中可以省略部分状态信息 (例如身份认证等)。
8、WebSocket 连接在端口 80 (ws) 或者 443 (wss) 上创建,与 HTTP 使用的端口相同,这样, 基本上所有的防火墙都不会阻止 WebSocket 连接。
WebSocket 使用 HTTP 协议进行握手,因此它可以自然而然地集成到网络浏览器和 HTTP 服务器中,而不需要额外的成本。
9、心跳消息 (ping 和 pong) 将被反复的发送,进而保持 WebSocket 连接一直处于活跃状态。
使用该协议,当消息启动或者到达的时候,服务端和客户端都可以知道。
10、WebSocket 连接关闭时将发送一个特殊的关闭消息。
11、WebSocket 支持跨域,可以避免 Ajax 的限制。
12、HTTP 规范要求浏览器将并发连接数限制为每个主机名两个连接, 但是当我们使用 WebSocket 的时候,当握手完成之后,该限制就不存在了,因为此时的连接已经不再是 HTTP 连接了。
13、WebSocket 协议支持扩展,用户可以扩展协议,实现部分自定义的子协议。
14、更好的二进制支持以及更好的压缩效果。