• ws:Websocket
  • wss:Websocket Secure
  • http: The Hypertext Transfer Protocol
  • https: The Hypertext Transfer Protocol

在建立websocket链接时,代码如下:

1
2
3
4
5
if ( 'https:' === document.location.protocol ) {
sock = new WebSocket("wss://" + location.host + NEMO_CONST.ctx +"/websocket/message");
} else {
sock = new WebSocket("ws://" + location.host + NEMO_CONST.ctx +"/websocket/message");
}

在工作中有涉及到websocket连接的地方使用的是websocket连接来进行通信,发现在有一个公司的网络环境下无法建立连接。已知host是http,建立的ws连接,考虑到该用户可能使用的是网络代理,不能识别ws握手时发送的upgrade,所以websocket连接没能成功建立起来。需要换成wss连接。

那么问题来了,上述代码为什么要通过http和https来区分使用ws或者wss来建立websocket连接呢?

通过查阅资料RFC,并未看到有规定在http协议下不能进行wss连接。
其中提到了Websocket与http的关系:

1.7. Relationship to TCP and HTTP

This section is non-normative.

The WebSocket Protocol is an independent TCP-based protocol. Its
only relationship to HTTP is that its handshake is interpreted by
HTTP servers as an Upgrade request.

By default, the WebSocket Protocol uses port 80 for regular WebSocket
connections and port 443 for WebSocket connections tunneled over
Transport Layer Security (TLS) [RFC2818].

翻译过来的意思是:

Websocket协议是一个独立的基于TCP的协议,它和http之间唯一的关系在于它的握手会被http服务器看成一个升级后的协议。
Websocket默认使用的是80端口建立链接,443端口建立安全链接。

那么问题来了,为什么上面的代码那么流行呢?个人猜测可能那段代码是想通过host的http和https来判断服务器是能够建立起wss连接,如果host连接是https,那么则可以建立ws安全连接,即wss连接。

但可以看到,是有在http请求的页面里面发起wss请求的需求的。
issue

总结

ws和http之间没有必然的联系,http请求的页面里也可以发起wss请求,建立wss连接。