WebSocket TCP HTTP
实践
proxy_http_version 1.1;
upgrade:websocket: request origin not allowed by Upgrader.CheckOrigin
协议升级机制 - HTTP | MDN https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Protocol_upgrade_mechanism
Protocol upgrade mechanism
协议升级机制
HTTP/1.1 协议提供了一种使用 Upgrade
(en-US) 标头字段的特殊机制,这一机制允许将一个已建立的连接升级成新的、不相容的协议。
这个机制是可选的;它并不能强制协议的更改(通常来说这一机制总是由客户端发起的)。如果它们支持新协议,实现甚至可以不利用 upgrade,在实践中,这种机制主要用于引导 WebSocket 连接。
注意:HTTP/2 明确禁止使用此机制;这个机制只属于 HTTP/1.1。
升级 HTTP/1.1 连接
客户端使用 Upgrade
(en-US) 标头字段请求服务器,以降序优先的顺序切换到其中列出的一个协议。
因为 Upgrade
是一个逐跳(Hop-by-hop)标头,它还需要在 Connection
标头字段中列出。这意味着包含 Upgrade 的典型请求类似于:
HTTP
GET /index.html HTTP/1.1
Host: www.example.com
Connection: upgrade
Upgrade: example/1, foo/2
根据之前的请求的协议,可能需要其他标头信息,例如:从 HTTP/1.1 升级到 WebSocket 允许配置有关 WebSocket 连接的标头详细信息,以及在连接时提供一定程度的安全性。查看升级到 WebSocket 协议的连接获取更多信息。
如果服务器决定升级这次连接,就会返回一个 101 Switching Protocols
响应状态码,和一个要切换到的协议的标头字段 Upgrade。如果服务器没有(或者不能)升级这次连接,它会忽略客户端发送的 Upgrade
标头字段,返回一个常规的响应:例如一个 200 OK
).
在发送 101
状态码之后,服务器可以使用新协议,并根据需要执行任何额外的特定于协议的握手。实际上,一旦这次升级完成了,连接就变成了双向管道。并且可以通过新协议完成启动升级的请求。
升级机制的常用场合
此处将介绍最常用到 Upgrade
(en-US) 标头的场合。
升级到 websocket 协议的连接
至今为止,最经常会需要升级一个 HTTP 连接的场合就是使用 WebSocket,它总是通过升级 HTTP 或 HTTPS 连接来实现。请记住,当你用 WebSocket API 以及其他大部分实现 WebSocket 的库去建立新的连接时,基本上都不用操心升级的过程,因为这些 API 已经实现了这一步。比如,用如下 API 打开一个 WebSocket 连接:
JS
webSocket = new WebSocket("ws://destination.server.ext", "optionalProtocol");
WebSocket()
构造函数已经自动完成了发送初始 HTTP/1.1 连接的所有工作,然后为你处理握手及升级过程。
备注: 你也可以用 "wss://"
URL 方式来打开安全的 WebSocket 连接。
如果想要自己重头实现 WebSocket 连接,就必须要处理握手和升级过程。在创建初始 HTTP/1.1 会话之后,你需要发送另一个 HTTP 标准请求来请求升级,但在标头中要带上 Upgrade
(en-US) 和 Connection
,也就是:
HTTP
Connection: Upgrade
Upgrade: websocket
RFC 6455 - The WebSocket Protocol https://tools.ietf.org/html/rfc6455
1.5. Design Philosophy
_This section is non-normative._
The WebSocket Protocol is designed on the principle that there should
be minimal framing (the only framing that exists is to make the
protocol frame-based instead of stream-based and to support a
distinction between Unicode text and binary frames). It is expected
that metadata would be layered on top of WebSocket by the application
Fette & Melnikov Standards Track [Page 9]
RFC 6455 The WebSocket Protocol December 2011 layer, in the same way that metadata is layered on top of TCP by the application layer (e.g., HTTP). Conceptually, WebSocket is really just a layer on top of TCP that does the following: o adds a web origin-based security model for browsers o adds an addressing and protocol naming mechanism to support multiple services on one port and multiple host names on one IP address o layers a framing mechanism on top of TCP to get back to the IP packet mechanism that TCP is built on, but without length limits o includes an additional closing handshake in-band that is designed to work in the presence of proxies and other intermediaries Other than that, WebSocket adds nothing. Basically it is intended to be as close to just exposing raw TCP to script as possible given the constraints of the Web. It's also designed in such a way that its servers can share a port with HTTP servers, by having its handshake be a valid HTTP Upgrade request. One could conceptually use other protocols to establish client-server messaging, but the intent of WebSockets is to provide a relatively simple protocol that can coexist with HTTP and deployed HTTP infrastructure (such as proxies) and that is as close to TCP as is safe for use with such infrastructure given security considerations, with targeted additions to simplify usage and keep simple things simple (such as the addition of message semantics). The protocol is intended to be extensible; future versions will likely introduce additional concepts such as multiplexing.
https://github.com/HJava/myBlog
【译】WebSocket协议第一章——介绍(Introduction) - 掘金 https://juejin.im/post/5b1a7189e51d45068b496cf0