WebSocket介绍
WebSocket协议,RFC 6455,提供了一种标准化的方法,通过单个TCP连接在客户端和服务器之间建立一个全双工双向通信通道,它是一种不同于HTTP的TCP协议,但被设计用于HTTP之上,使用端口80和443并允许重用现有的防火墙规则。
WebSocket交互从HTTP请求开始,HTTP请求使用HTTP Upgrade
header进行upgrade,或者在本例中切换到WebSocket协议,下面的示例展示了这种交互:
GET /spring-websocket-portfolio/portfolio HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080
-
Upgrade: websocket
=>Upgrade
header。 -
Connection: Upgrade
=> 使用Upgrade
连接。
支持WebSocket的服务器返回的输出与下面类似,而不是通常的200
状态代码:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp
-
HTTP/1.1 101 Switching Protocols
=> 协议转换。
在成功握手之后,在HTTP upgrade请求基础上的TCP socket仍然是开放的,以便客户端和服务器继续发送和接收消息。
关于WebSockets如何工作的完整介绍超出了本文的范围,参见RFC 6455,HTML5的WebSocket章节,或者Web上许多介绍和教程中的任何一个。
注意,如果WebSocket服务器运行在web服务器(例如nginx)之后,你可能需要将它配置为将WebSocket upgrade请求传递到WebSocket服务器,同样,如果应用程序在云环境中运行,请检查与WebSocket支持相关的云提供商的说明。
HTTP与WebSocket
尽管WebSocket被设计为与HTTP兼容并从HTTP请求开始,但重要的是要理解这两个协议导致了非常不同的体系结构和应用程序编程模型。
在HTTP和REST中,应用程序被建模为多个URL,为了与应用程序交互,客户端访问那些URL,请求-响应样式,服务器根据HTTP URL、方法和headers将请求路由到适当的处理程序。
相比之下,在WebSockets中,通常初始连接只有一个URL,随后,所有应用程序消息都在同一个TCP连接上流动,这指向了一个完全不同的异步、事件驱动的消息传递体系结构。
WebSocket也是一种低级别的传输协议,与HTTP不同的是,它没有对消息的内容规定任何语义,这意味着,除非客户端和服务器在消息语义上达成一致,否则无法路由或处理消息。
通过HTTP握手请求上的Sec-WebSocket-Protocol
header,WebSocket客户端和服务器可以协商使用更高级别的消息传递协议(例如STOMP),在没有这些的情况下,他们需要制定自己的约定。
何时使用WebSockets
WebSockets可以使一个web页面成为动态的和交互式的,然而,在许多情况下,Ajax和HTTP流或长轮询的组合可以提供简单而有效的解决方案。
例如,新闻、邮件和社交提要需要动态更新,但每隔几分钟更新一次可能完全没有问题,另一方面,协作、游戏和金融应用程序需要更接近实时。
延迟本身并不是决定性因素,如果消息量相对较低(例如,监视网络故障),HTTP流或轮询可以提供有效的解决方案,正是低延迟、高频率和高容量的组合,使WebSocket的使用成为最好的例子。
还要记住,在Internet上,超出你控制范围的限制性代理可能会妨碍WebSocket交互,要么是因为它们没有配置为传递Upgrade
header,要么是因为它们关闭了看起来空闲的长连接,这意味着对于防火墙内的内部应用程序使用WebSocket比面向公共的应用程序更直接。