WebSocket TCP HTTP

 

实践

'upgrade' token not found in 'Connection' header

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade

 

upgrade:websocket: request origin not allowed by Upgrader.CheckOrigin

 

var upgrader = websocket.Upgrader{
    // 解决跨域问题
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

 

func WsHandler(w ghttp.ResponseWriter, r *ghttp.Request) {
    println("IN WsHandler")
    c, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Print("upgrade:", err)
        return
    }
 
在handler中分别处理http、ws。
 
    srv := http.NewServer(opts...)
    r := srv.Route("/")
 
 
    ws_router := mux.NewRouter()
    ws_router.HandleFunc("/ws", WsHandler)
    srv.HandlePrefix("/ws", ws_router)
 
    r.GET("debug", func(ctx http.Context) error {
        return ctx.String(200, "ok")
    })
 
 
 
 
 

协议升级机制 - 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

 

posted @ 2020-05-21 12:46  papering  阅读(282)  评论(0编辑  收藏  举报