Skip to main content

WebSocket 协议

一、WebSocket 的定义

1、为什么需要 WebSocket

WebSocket 是 HTML5 新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,比如说,服务器可以在任意时刻发送消息给浏览器。

为什么传统的 HTTP 协议不能做到 WebSocket 实现的功能?

这是因为 HTTP 协议是一个请求-响应协议,请求必须先由浏览器发给服务器,服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的。

也有人说,HTTP 协议其实也能实现啊,比如用轮询或者 Comet

  • 轮询是指浏览器通过 JavaScript 启动一个定时器,然后以固定的间隔给服务器发请求,询问服务器有没有新消息。这个机制的缺点一是实时性不够,二是频繁的请求会给服务器带来极大的压力。

  • Comet 本质上也是轮询,但是在没有消息的情况下,服务器先拖一段时间,等到有消息了再回复。这个机制暂时地解决了实时性问题,但是它带来了新的问题:以多线程模式运行的服务器会让大部分线程大部分时间都处于挂起状态,极大地浪费服务器资源。另外,一个 HTTP 连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,而网关是我们不可控的,这就要求 Comet 连接必须定期发一些 ping 数据表示连接“正常工作”。

以上两种机制都治标不治本,所以,HTML5 推出了 WebSocket 标准,让浏览器和服务器之间可以建立无限制的全双工通信,任何一方都可以主动发消息给对方。

轮询、长轮询、长连接和 Flash Socket 的区别?

轮询

客户端定时向服务器发送 AJAX 请求,服务器接到请求后马上返回响应信息并关闭连接。

  • 优点:后端程序编写比较容易。
  • 缺点:请求中有大半是无用,浪费带宽和服务器资源。
  • 实例:适于小型应用。

长轮询

客户端向服务器发送 AJAX 请求,服务器接到请求后 hold 住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。

  • 优点:在无消息的情况下不会频繁的请求,耗费资小。
  • 缺点:服务器 hold 住连接会消耗资源,返回数据顺序无保证,难于管理维护。
  • 实例:WebQQ、 Hi 网页版、 Facebook IM 。

长连接

在页面里嵌入一个隐蔵 iframe,将这个隐蔵 iframe 的 src 属性设为对一个长连接的请求或是采用 xhr 请求,服务器端就能源源不断地往客户端输入数据。

  • 优点:消息即时到达,不发无用请求;管理起来也相对便。
  • 缺点:服务器维护一个长连接会增加开销。
  • 实例:Gmail 聊天

Flash Socket

在页面中内嵌入一个使用了 Socket 类的 Flash 程序 JavaScript 通过调用此 Flash 程序提供的 Socket 接口与服务器端的 Socket 接口进行通信, JavaScript 在收到服务器端传送的信息后控制页面的显示。

  • 优点:实现真正的即时通信,而不是伪即时。
  • 缺点:客户端必须安装 Flash 插件;非 HTTP 协议,无法自动穿越防火墙。
  • 实例:网络互动游戏。

2、什么是 WebSocket

WebSocket 是在单个 TCP 连接上进行全双工通讯的协议,使得客户端和服务器之间的数据交换变得更加简单,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输,允许服务端主动向客户端推送数据。

换句话说,WebSocket 是 HTML5 新增的基于 TCP 的协议,客户端和服务端只需完成一次握手,就可以创建持久性的连接,并进行双向数据传输,不需要使用轮询的方式。

3、WebSocket 的优点

现在很多网站为了实现推送技术,所用的技术都是 AJAX 轮询,浏览器需要不断的向服务器发出请求,然而 HTTP 请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,这样会浪费很多的带宽等资源。

WebSocket 协议则能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

4、WebSocket 与 HTTP 的区别

两者都是基于 TCP 的应用层协议。

HTTP 建立连接需要有三次握手才能发送信息。

WebSocket 是全双工通信,服务器可以随时发送信息给浏览器。

5、WebSocket 与 Socket 的区别

WebScoket 是基于 TCP 的应用层协议。

Socket 是应用层与传输层的一个抽象,将复杂的 TCP/IP 协议隐藏在 Socket 接口之后,只对用户暴露简单的接口。

二、WebSocket 的特点

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

三、WebSocket 的过程

浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

当获取 WebSocket 连接后,可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

另外,由于 WebSocket 是一个协议,服务器具体怎么实现,取决于所用编程语言和框架本身。Node.js 本身支持的协议包括 TCP 协议和 HTTP 协议,要支持 WebSocket 协议,需要对 Node.js 提供的 HTTPServer 做额外的开发。已经有若干基于 Node.js 的稳定可靠的 WebSocket 实现,直接用 npm 安装使用即可。