webcocket是一种在单个TCP链接上进行全双工通信的协议,标准为RFC 6455
在WebSocket建立连接时,HTTP仅用于初始握手,这依赖于内置于HTTP中的机制来请求协议升级(或在这种情况下为协议开关),如果服务器同意,它可以使用HTTP状态101对其进行响应 (切换协议)。 假设握手成功,HTTP升级请求后其底层的TCP套接字保持打开,这样客户端和服务器都可以使用这个套接字来相互发送消息。
websocket是一个持久化协议,相对于http来说的话,http的生命周期就是一个Request一个Response,在http1.0请求就结束了。
在http1.1中进行了改进,增加了keep-alive,也就是说在一个http中可以发送多个Request接受多个Response,但是一个Request只能有一个Response,而且Response是被动的,不能主动发起
websocket是基于HTTP协议的,是借助于HTTP协议来完成一部分握手(借鉴自Wikipedia):
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
相对于HTTP多了几条:
Upgrade:websocket
Connection:Upgrade
这两条是告诉Apache、Nginx等服务器发起的是WebSocket协议
Sec-WebSocket-Key是一个encode的值,是浏览器随即生成的,告诉浏览器验证websocket助理
Sec-WebSocket-Protocol是一个用户定义的字符串,用来区分URL下,不同服务所需要的协议。
Sec-WebSocket-Version是告诉服务器所使用WebSocket Draft(协议版本)
服务器会返回下列东西,表示已经接收到请求,成功建立了WebSocket
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
这个过程里相当于client先向server打招呼,发送了一个加密的密匙(key)过去,然后server看到client打招呼,传递回去一条消息,告诉client我看到了这个打招呼信息。
AJAX轮询:是通过让浏览器没隔几秒就发送一条消息询问服务器是否有新消息实现的
客户端:有新消息吗(Request)
服务端:没有(Response)
客户端:有新消息吗(Request)
服务端:没有(Response)
。。。
long poll:和ajax相似都是采用了轮询的方式,采用阻塞模型,客户端发起链接后,如果没有新消息就不返回Response,直到有消息时返回,返回后再次建立连接。
上面两种方式都是通过http实现的,可以发现http具有被动性,即不能主动向客户端发起消息,都是先由客户端发起被动回复。
不难想象,AJAX会对处理速度以及资源有要求,long poll则会需要更多的“场地”
websocket:只需要进行一次http链接就可以不断地进行信息的传递,即有信息的时候再通知,而不用每次都去询问。websocket其实是经过了两层代理的,即http在Nginx等服务器上进行解析,然后分发给Handler来处理,
websocket解决了同步迟缓和过多消耗资源的问题。
参考文章:https://www.zhihu.com/question/20215561