HTML5之WebSocket && https://zhuanlan.zhihu.com/p/23467317
在认识websocket之前,我们必须了解的是websocket有什么用? 他能解决我们遇到的什么问题? 如果没用,那么我们就么有使用它的必要的。
websocket就是建立起全双工协议的,提高了效率,节省了时间。
什么是WebSocket? WebSocket一种在单个 TCP连接上进行全双工通讯的协议。即WebSocket是一个协议。 websocket是基于TCP协议的。
比较通俗的理解,我们可以点击这里。
推荐文章:
https://zhuanlan.zhihu.com/p/23467317 (强烈推荐 --- 这篇文章详尽介绍了websocket的原理以及长轮询、短轮、commet, 通过铺垫告诉我们为什么要使用 websocket。对于基本概念的理解可以看这一篇文章 )
http://www.alloyteam.com/2015/04/qian-duan-qiang-hou-duan-fan-wan-node-js-socket-io-zhi-zuo-jian-yi-liao-tian-shi/ (推荐: 这篇文章是腾讯前端团队的成员所写,只是其中的例子都已经不能用了,但是这篇文章的思路还是非常清晰的,并且分享了自己在做项目中遇到的一些坑。)
http://www.cnblogs.com/Wayou/p/hichat_built_with_nodejs_socket.html (这是讲解文章,非常好。可以参考学习。)
https://github.com/wayou/HiChat/blob/master/www/scripts/hichat.js (这是是github的源代码)
https://hichat.herokuapp.com/ (这个网站是聊天室在PC端的具体实现 。)
https://www.websocket.org/index.html# websocket官网
https://socket.io/demos/chat/ (socket.io提供了聊天室demo) 相关https://socket.io/get-started/chat/教程:
第一部分:WebSocket的特点
- 通过TCP一次握手就可以建立连接。 而HTTP协议需要三次握手。
- HTTP中服务器永远是被动的,即每次只有客户端发出请求,服务器才会响应。 但是WebSocket协议中,服务器是可以主动的向客户端传递数据。这样就避免了轮询的问题。
- WebSocket需要浏览器、服务器同时支持才可以使用,而http协议是普遍支持的。 且WebSocket是一种新的协议,只是目前为了兼容性,必须要建立在http的基础上发起请求,如只用WebSocket协议名将不再是http:而是ws:。
- 同样地,WebSocket也是基于TCP协议的。
websocket 和 http 的区别
首先要知道的时 websocket 和 http是不同的两个协议,最大的区别在于---http协议是被动的,而websocket协议是主动的。 所谓被动就是说只有客户端发起请求服务器端才会给出响应,而websocket显然就是说可以由服务器端来主动给数据,也许你并没有请求。
客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)
服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)
客户端:麻烦你有信息的时候推送给我噢。。
服务端:ok,有的时候会告诉你的。
服务端:balabalabalabala
服务端:balabalabalabala
服务端:哈哈哈哈哈啊哈哈哈哈
服务端:笑死我了哈哈哈哈哈哈哈
作者:Ovear
链接:https://www.zhihu.com/question/20215561/answer/40316953
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。这样, 服务器端就可以在有消息的时候再推送消息,那么客户端就可以减少不必要的ajax轮询了。
注意: 虽然websocket和http协议是两个不同的协议,但是我们每次在使用websocket协议时,首先要建立http协议,通过http协议,我们才能进一步升级(upgrade)为websocket协议。
下面这张图片比较好地解释了websocket的相关原理。
相比于传统 HTTP 的每次“请求-应答”都要 client 与 server 建立连接的模式,WebSocket 是一种长连接的模式。具体什么意思呢?就是一旦 WebSocket 连接建立后,除非 client 或者 server 中有一端主动断开连接,否则每次数据传输之前都不需要 HTTP 那样请求数据。从上面的图可以看出,client 第一次需要与 server 建立连接,当 server 确认连接之后,两者便一直处于连接状态。直到一方断开连接,WebSocket 连接才断开。
第二部分: 基础知识
当我们获取了WebSocket连接之后,我们就可以通过send()方法来向服务器发送数据,并通过onmessage事件来接收服务器返回的数据。下面的api用于创建一个Websocket对象。
var Socket = new WebSocket(url, [protocol]);
其中第一个参数是需要连接的url,后一个参数是可选的,制定可以接受的子协议。
WebSocket相关属性
即我们创建了Socket对象之后,它会有一个readyState属性(这个和xhr的属性同名),取值如下:
0 表示连接尚未建立
1 表示连接已经建立,可以进行通信
2 表示连接正在进行关闭
3 表示连接已经关闭或者连接不能打开
且websocket链接一旦建立,那么就可以双方进行通信了,直到有一方主动提出终止链接为止。,
WebSocket方法
WebSocket中只有两个方法,一个是使用连接发送数据,即Socket.send(),另一个就是关闭连接,即Socket.close()。
注意:在xhr中是没有close相关方法的,因为一次请求一次响应的方式使得其无需close。
WebSocket 事件
第三部分:WebSocket实例
在建立一个WebSocket连接的时候,客户端浏览器首先向服务器发送一个http请求,这个请求和普通的http请求不同,因为在首部字段中包含了Upgrade: WebSocket; 这表明这是一个申请升级为WebSocket协议的http请求, 服务器解析这些附加的头信息然后产生了应答信息返回给客户端,客户端和服务端的WebSocket连接就建立起来了,双方就可以使用这个连接进行自由的传递信息,并且这个连接会持续存在到客户端或者服务器端的某一方主动的关闭连接。
客户端的HTML和JavaScript
下面是菜鸟教程上的例子:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</title> <script type="text/javascript"> function WebSocketTest() { if ("WebSocket" in window) { alert("您的浏览器支持 WebSocket!"); // 打开一个 web socket var ws = new WebSocket("ws://localhost:9998/echo"); ws.onopen = function() { // Web Socket 已连接上,使用 send() 方法发送数据 ws.send("发送数据"); alert("数据发送中..."); }; ws.onmessage = function (evt) { var received_msg = evt.data; alert("数据已接收..."); }; ws.onclose = function() { // 关闭 websocket alert("连接已关闭..."); }; } else { // 浏览器不支持 WebSocket alert("您的浏览器不支持 WebSocket!"); } } </script> </head> <body> <div id="sse"> <a href="javascript:WebSocketTest()">运行 WebSocket</a> </div> </body> </html>
但是如果要使用,我们必须安装 pywebsocket, 安装过程如下:
https://looly.gitbooks.io/python-basic/100/101.html 这里有python环境的安装教程。
http://www.runoob.com/html/html5-websocket.html 这里是pywebsocket的安装过程。
第四部分: http与websocket在报文方面的差异
这里从报文层面谈一下两者的差异。
首先,client 发起 WebSocket 连接,报文类似于 HTTP,但主要有几点不一样的地方:
-
"Upgrade: websocket": 表明这是一个 WebSocket 类型请求,意在告诉 server 需要将通信协议切换到 WebSocket
-
"Sec-WebSocket-Key: *": 是 client 发送的一个 base64 编码的密文,要求 server 必须返回一个对应加密的 "Sec-WebSocket-Accept" 应答,否则 client 会抛出 "Error during WebSocket handshake" 错误,并关闭连接
server 收到报文后,如果支持 WebSocket 协议,那么就会将自己的通信协议切换到 WebSocket,返回以下信息:
-
"HTTP/1.1 101 WebSocket Protocol Handshake":返回的状态码为 101,表示同意 client 的协议转换请求
-
"Upgrade: websocket"
-
"Connection: Upgrade"
-
"Sec-WebSocket-Accept: *"
-
...
以上都是利用 HTTP 协议完成的。这样,经过“请求-相应”的过程, server 与 client 的 WebSocket 连接握手成功,后续便可以进行 TCP 通讯了,也就没有 HTTP 什么事了。可以查阅WebSocket 协议栈了解 WebSocket 的 client 与 server 更详细的交互数据格式。
第五部分: websocket 与 socket的区别
什么是socket?
网络应用中,两个应用程序同时需要向对方发送消息的能力(即全双工通信),所利用到的技术就是 socket,其能够提供端对端的通信。对于程序员而言,其需要在 A 端创建一个 socket 实例,并为这个实例提供其所要连接的 B 端的 IP 地址和端口号,而在 B 端创建另一个 socket 实例,并且绑定本地端口号来进行监听。当 A 和 B 建立连接后,双方就建立了一个端对端的 TCP 连接,从而可以进行双向通信。
进一步解释: 可以知道socket并不是仅仅针对于网络的,而是对于任何的双方之间可以进行全双工通信,我们就认为这是socket。 而不是说必须是客户端和服务器端。
WebSocekt 是 HTML5 规范中的一部分,其借鉴了 socket 的思想,为 client 和 server 之间提供了类似的双向通信机制。同时,WebSocket 又是一种新的应用层协议,包含一套标准的 API;而 socket 并不是一个协议,而是一组接口,其主要方便大家直接使用更底层的协议(比如 TCP 或 UDP)。
即 websocket是协议,而socket是技术。
第五部分: websocket与socket.io的区别
https://socket.io/
Socket.IO 是一个封装了 Websocket、基于 Node 的 JavaScript 框架,包含 client 的 JavaScript 和 server 的 Node。其屏蔽了所有底层细节,让顶层调用非常简单。
另外,Socket.IO 还有一个非常重要的好处。其不仅支持 WebSocket,还支持许多种轮询机制以及其他实时通信方式,并封装了通用的接口。这些方式包含 Adobe Flash Socket、Ajax 长轮询、Ajax multipart streaming 、持久 Iframe、JSONP 轮询等。换句话说,当 Socket.IO 检测到当前环境不支持 WebSocket 时,能够自动地选择最佳的方式来实现网络的实时通信。e
也就是说,通过socket.io,我们可以更方便的调用websocket。 比如,对于ajax的封装就会大大提高我们的效率,而不需要自己创建,考虑兼容性问题等。
不难理解,socket.io这个库是结合了node更方便我们调用socket的方法的库,更狭隘的说,socket.io是一个websocket库, 他和express不同,因为express是node的库,所以两者是相互独立的,为了开发的高效性,我们也可以同时使用express和socket.io两个库。
完