39

golang Sec-WebSocket-Protocol问题记录

 4 years ago
source link: https://www.tuicool.com/articles/Eza6R3F
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

环境

golang 1.9

websocket包采用的是 github.com/gorilla/websocket

在小程序H5页面与websocket联调的时候出现了如下错误, Sec-Websocket-Protocol 参数应该是小程序中自己添加进去的,后端要做一些处理。

问题

fA7NZbf.png!web

image

Error during Websocket handshake: Sent non-empty 'Sec-Websocket-Protocol'header but no response was received

处理

一般而言,websocket出现这种问题只要获取请求头的 Sec-Websocket-Protocol 参数,随后将参数添加到 response 的请求头中即可。但我在尝试之后,问题并没有解决。

在部门大佬的指导下,去看了 github.com/gorilla/websocket 包的源代码,发现包里对于这个参数已经做了处理

//源码
    // Subprotocols specifies the server's supported protocols in order of
    // preference. If this field is not nil, then the Upgrade method negotiates a
    // subprotocol by selecting the first match in this list with a protocol
    // requested by the client. If there's no match, then no protocol is
    // negotiated (the Sec-Websocket-Protocol header is not included in the
    // handshake response).
    Subprotocols []string
    
    
    func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {
    if u.Subprotocols != nil {
        clientProtocols := Subprotocols(r)
        for _, serverProtocol := range u.Subprotocols {
            for _, clientProtocol := range clientProtocols {
                if clientProtocol == serverProtocol {
                    return clientProtocol
                }
            }
        }
    } else if responseHeader != nil {
        return responseHeader.Get("Sec-Websocket-Protocol")
    }
    return ""
}

所以我们只需要将获取的参数放进 Subprotocols 即可

var upgrade = websocket.Upgrader{
        // cross origin domain
        CheckOrigin: func(r *http.Request) bool {   //这个是解决跨域问题
            return true
        },
        Subprotocols:[]string{s.Ctx.Input.Header("Sec-WebSocket-Protocol")},  
        //将获取的参数放进这个数组,问题解决
    }

在引用第三方包的时候,遇到问题,多读源码


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK