什么是websocketjavascript
WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间创建一个不受限的双向通讯的通道,使服务器和客户端能够实时高效的通讯。同时服务器能够在任意时刻主动发送消息给客户端-浏览器。java
为何会出现 websoket?node
为何传统的HTTP协议不能作到WebSocket实现的功能?web
咱们都知道HTTP 协议,在 HTTP1.0
中,一次req 请求对应一个 res,而后此次HTTP请求就结束了。npm
在HTTP1.1中进行了改进,增长了keep-alive,能够对一个请求能够进行重用,能够进行屡次Request和Response。可是HTTP协议中永远是一个request对应一个response。并且这个response也是被动的,不能主动发起。编程
这样一来,要在浏览器中搞一个实时聊天,在线炒股(不鼓励),或者在线多人游戏的话就无法实现了,只能借助Flash插件,轮询,长链接。api
轮询是指浏览器经过JavaScript启动一个定时器,而后以固定的间隔给服务器发请求,询问服务器有没有新消息。这个机制的缺点一是实时性不够,二是频繁的请求会给服务器带来极大的压力。浏览器
Comet本质上也是轮询,可是在没有消息的状况下,服务器先拖一段时间,等到有消息了再回复。这个机制暂时地解决了实时性问题,可是它带来了新的问题:以多线程模式运行的服务器会让大部分线程大部分时间都处于挂起状态,极大地浪费服务器资源。另外,一个HTTP链接在长时间没有数据传输的状况下,链路上的任何一个网关均可能关闭这个链接,而网关是咱们不可控的,这就要求Comet链接必须按期发一些ping数据表示链接“正常工做”。安全
以上两种机制都治标不治本,因此,HTML5推出了WebSocket标准,让浏览器和服务器之间能够创建无限制的全双工通讯,任何一方均可以主动发消息给对方。服务器
在说下 HTTP是应用层协议,是创建在TCP协议之上的,TCP协议属于传输层协议,自己就是可靠的,全双工通讯协议,HTTP协议的请求-应答机制限制了全双工通讯。当WebSocket链接创建之后,其实只是简单规定了一下:说哥们,接下来,我们通讯就不使用HTTP那套了,我们尽可能保持连接,随便互相发数据吧。
握手机制:
WebSocket并非全新的协议,而是利用了HTTP协议来创建链接。
浏览器和服务器只须要作一次握手的动做,而后,浏览器和服务器之间就造成了一条快速通道。二者之间就直接能够数据互相传送。
具体的握手过程就不说了,会涉及到代码,没办法说明。有兴趣的能够看下 mdn 上 了解下。
咱们来看看WebSocket链接是如何建立的。
首先,WebSocket链接必须由浏览器发起,由于请求协议是一个标准的HTTP请求,格式以下:
GET ws://localhost:3000/ws/chat HTTP/1.1 Host: localhost Upgrade: websocket Connection: Upgrade Origin: http://localhost:3000 Sec-WebSocket-Key: client-random-string Sec-WebSocket-Version: 13
该请求和普通的HTTP请求有几点不一样:
/path/
,而是以ws://
开头的地址;Upgrade: websocket
和Connection: Upgrade
表示这个链接将要被转换为WebSocket链接;Sec-WebSocket-Key
是用于标识这个链接,并不是用于加密数据;Sec-WebSocket-Version
指定了WebSocket的协议版本。随后,服务器若是接受该请求,就会返回以下响应:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: server-random-string
该响应代码101
表示本次链接的HTTP协议即将被更改,更改后的协议就是Upgrade: websocket
指定的WebSocket协议。
版本号和子协议规定了双方能理解的数据格式,以及是否支持压缩等等。若是仅使用WebSocket的API,就不须要关心这些。
如今,一个WebSocket链接就创建成功,浏览器和服务器就能够随时主动发送消息给对方。消息有两种,一种是文本,一种是二进制数据。一般,咱们能够发送JSON格式的文本,这样,在浏览器处理起来就十分容易。
为何WebSocket链接能够实现全双工通讯而HTTP链接不行呢?实际上 dddd 安全的WebSocket链接机制和HTTPS相似。首先,浏览器用wss://xxx
建立WebSocket链接时,会先经过HTTPS建立安全的链接,而后,该HTTPS链接升级为WebSocket链接,底层通讯走的仍然是安全的SSL/TLS协议。
浏览器支持状况
很显然,要支持WebSocket通讯,浏览器得支持这个协议,这样才能发出ws://xxx
的请求。目前,支持WebSocket的主流浏览器以下:
服务器:
因为WebSocket是一个协议,服务器具体怎么实现,取决于所用编程语言和框架自己。Node.js自己支持的协议包括TCP协议和HTTP协议,要支持WebSocket协议,须要对Node.js提供的HTTPServer作额外的开发。已经有若干基于Node.js的稳定可靠的WebSocket实现,咱们直接用npm安装使用便可。
node 里 好比 有 ws,socket.io 模块,npm 装就能够.
使用相关
Websocket 使用 ws 或 wss 的统一资源标志符,相似于 HTTPS,其中 wss 表示在 TLS 之上的 Websocket。如:
ws://example.com/wsapi wss://secure.example.com/
Websocket 使用和 HTTP 相同的 TCP 端口,能够绕过大多数防火墙的限制。默认状况下,Websocket 协议使用 80 端口;运行在 TLS 之上时,默认使用 443 端口。
如何使用
能够参考 mdn 的 api 文档便可
总结:
websocket 就是一个基于 http 的一个加强的协议,既然是协议 浏览器和服务器都须要支持了这个协议才能提供咱们使用。在这个基础上咱们只须要使用已提供的 api 便可实现咱们的需求。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,容许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只须要完成一次握手,二者之间就直接能够建立持久性的链接,并进行双向数据传输。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,而且可以更实时地进行通信。
参考资料 https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096
我写的 demo:
使用 websocket 作了一个热更新 demo,有兴趣能够看下