通过nginx进行wss和ws协议转换(wss协议)
项目场景:
一个im项目在测试准备上线的时候,发现微信小程序在正式阶段只支持wss协议
问题描述:
提示:发现微信小程序在正式阶段只支持wss协议,由于通信采用https,所以ws协议无法直接使用,测试开发阶段可以采用ws协议进行
原因分析:
原因在于https和http不能混合使用,wss和ws也是对应的,https下无法使用http和ws协议
解决方案:
于是想到采用nginx代理的方式进行协议转换,解决通信问题,这样既不用修改服务端代码,也不需要修改客户端代码,一举多得。
话不多说,上nginx配置:
刨根问底HTTP和WebSocket协议(二)
上篇介绍了HTTP1.1协议的基本内容,这篇文章将继续分析WebSocket协议,然后对这两个进行简单的比较。
WebSocket协议还很年轻,RFC文档相比HTTP的发布时间也很短,它的诞生是为了创建一种「 双向通信 」的协议,来作为HTTP协议的一个替代者。那么首先看一下它和HTTP(或者HTTP的长连接)的区别。
上一篇中提到WebSocket的目的就是解决网络传输中的双向通信的问题,HTTP1.1默认使用持久连接(persistent connection),在一个TCP连接上也可以传输多个Request/Response消息对,但是HTTP的基本模型还是一个Request对应一个Response。这在双向通信(客户端要向服务器传送数据,同时服务器也需要实时的向客户端传送信息,一个聊天系统就是典型的双向通信)时一般会使用这样几种解决方案:
WebSocket的目的是取代HTTP在双向通信场景下的使用,而且它的实现方式有些也是基于HTTP的(WS的默认端口是 80 和 443 )。现有的网络环境(客户端、服务器、网络中间人、代理等)对HTTP都有很好的支持,所以这样做可以充分利用现有的HTTP的基础设施,有点向下兼容的意味。
简单来讲,WS协议有两部分组成:握手和数据传输。
出于兼容性的考虑,WS的握手使用HTTP来实现(此文档中提到未来有可能会使用专用的端口和方法来实现握手),客户端的握手消息就是一个「普通的,带有Upgrade头的,HTTP Request消息」。所以这一个小节到内容大部分都来自于RFC2616,这里只是它的一种应用形式,下面是RFC6455文档中给出的一个客户端握手消息示例:
可以看到,前两行跟HTTP的Request的起始行一模一样,而真正在WS的握手过程中起到作用的是下面几个header域。
如果服务器接受了这个请求,可能会发送如下这样的返回信息,这是一个标准的HTTP的Response消息。 101 表示服务器收到了客户端切换协议的请求,并且同意切换到此协议。RFC2616规定只有切换到的协议「比HTTP1.1更好」的时候才能同意切换。
ws协议默认使用 80 端口,wss协议默认使用 443 端口。
在握手之前,客户端首先要先建立连接,一个客户端对于一个相同的目标地址(通常是域名或者IP地址,不是资源地址)同一时刻只能有一个处于CONNECTING状态(就是正在建立连接)的连接。从建立连接到发送握手消息这个过程大致是这样的:
如果客户端没有处于代理环境中,它就要首先建立一个到达目标地址的直接的TCP连接。
服务端指的是所有参与处理WebSocket消息的基础设施,比如如果某服务器使用Nginx(A)来处理WebSocket,然后把处理后的消息传给响应的服务器(B),那么A和B都是这里要讨论的服务端的范畴。
如果请求是HTTPS,则首先要使用TLS进行握手,如果失败,则关闭连接,如果成功,则之后的数据都通过此通道进行发送。
之后服务端可以进行一些客户端验证步骤(包括对客户端header域的验证),如果需要,则按照RFC2616来进行错误码的返回。
如果一切都成功,则返回成功的Response握手消息。
此握手消息是一个标准的HTTP Response消息,同时它包含了以下几个部分:
一旦这个握手发出去,服务端就认为此WebSocket连接已经建立成功,处于OPEN状态。它就可以开始发送数据了。
Sec-WebSocket-Version可以被通信双方用来支持更多的协议的扩展,RFC6455中定义的值为 13 ,WebSocket的客户端和服务端可能回自定义更多的版本号来支持更多的功能。其使用方法如上文所述。
WebSocket中所有发送的数据使用帧的形式发送。客户端发送的数据帧都要经过掩码处理,服务端发送的所有数据帧都不能经过掩码处理。否则对方需要发送关闭帧。
一个帧包含一个帧类型的标识码,一个负载长度,和负载。负载包括扩展内容和应用内容。
帧类型是由一个4位长的叫Opcode的值表示,任何WebSocket的通信方收到一个位置的帧类型,都要以连接失败的方式断开此连接。
RFC6455中定义的帧类型如下所示:
具体的每一项代表什么意思在这里就不做详细的阐述了。
同样作为应用层的协议,WebSocket在现代的软件开发中被越来越多的实践,和HTTP有很多相似的地方,这里将它们简单的做一个纯个人、非权威的比较:
这一篇简单地将WebSocket协议介绍了一遍,篇幅有点长了,数据帧也没有来得及详述。下篇会继续深扒WebSocket帧传输,另外将通过实例探讨一些WebSocket协议实际使用中的问题。
刨根问底HTTP和WebSocket协议(一)
WebSocket和Socket的区别(WebSocket外传)
刨根问底HTTP和WebSocket协议(三)
ws和wss的区别
WS协议和WSS协议两个均是WebSocket协议的SCHEM
WebSocket 协议是 html5的 一种通信协议,可以使客户端和服务端双向数据传输更加简单快捷,并且在 TCP连接 进行一次握手后,就可以 持久性 连接,同时允许服务端对客户端 推送 数据。
类似于HTTP协议和HTTPS协议的差别
SSL(Secure Socket Layer,安全套接层) 用来保障网络中数据传输的安全性,主要是运用数据加密技术避免数据在传输过程被不被窃取或者监听,旨在确保 Internet 通信中的隐私、身份验证和数据完整性
在高防防护过程中,80和433端口的网站是需要备案才可以接入国内的
http协议下使用ws,在https协议下使用wss
WebSocket协议的特点:
1. 建立在 TCP 协议之上,服务端实现容易;
2. 与 HTTP 协议有良好的兼容性,握手时不容易被屏蔽,可以通过各种 HTTP 代理服务器;
3. 数据轻量,实时通讯;
4. 可以发送文本和二进制数据。
5. 不限制同源,客户端可以与任意服务器端进行通讯。
Nginx配置之WSS
关于 WebSocket ,维基百科是这样介绍的:
WebSocket 协议在2008年诞生,2011年成为国际标准,现在几乎所有浏览器都已经支持了。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
简单来说, WebSocket 减少了客户端与服务器端建立连接的次数,减轻了服务器资源的开销,只需要完成一次 HTTP 握手。整个通讯过程是建立在一次连接/状态中,也就避免了 HTTP 的非状态性,服务端会一直与客户端保持连接,直到双方发起关闭请求,同时由原本的客户端主动询问,转换为服务器有信息的时候推送。所以,它能做实时通信(聊天室、直播间等),其他特点还包括:
现象描述: 在 https 协议下访问网站时,客户端浏览器控制面板异常信息:
这种情况,毫无疑问我们就需要使用 wss:// 安全协议了,需要将客户端浏览器获取的页面中 webscoket 的形式由 ws:// 改为 wss://
WebSocket 可以使用 ws 或 wss 来作为 统一资源标志符 ,类似于 HTTP 或 HTTPS 。其中 , wss 表示在 TLS 之上的 WebSocket ,相当于 HTTPS 。默认情况下, WebSocket 的 ws 协议基于 Http 的 80 端口;当运行在 TLS 之上时, wss 协议默认是基于 Http 的 443 端口。说白了, wss 就是 ws 基于 SSL 的安全传输,与 HTTPS 一样样的道理。所以,如果你的网站是 HTTPS 协议的,那你就不能使用 ws:// 了,浏览器会 block 掉连接,和 HTTPS 下不允许 HTTP 请求一样。
WS转WSS协议
在微信小程序的直播室里实现即时聊天功能,通过简单的websocket实现实时通讯,一开始使用的协议是ws://。后来因为微信小程序只支持wss协议,所以需要转为wss协议实现websocket连接。
要完成转wss协议,需要的步骤:1、申请一个域名;2、一台公网服务;3、域名绑定;4、为域名申请SSL证书;5、配置Nginx代理。
前面的三步已经完成。
例如:
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
cp objs/nginx /usr/local/nginx/sbin/nginx
WS和WSS区别
WebSocket (WS)是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,能更好地节省服务器资源和带宽并达到实时通讯。WebSocket建立在TCP之上,同HTTP一样通过TCP来传输数据,但是它和HTTP最大不同是:
WebSocket是一种双向通信协议,在建立连接后,WebSocket服务器和Browser/Client Agent都能主动的向对方发送或接收数据,就像Socket一样;WebSocket需要类似TCP的客户端和服务器端通过握手连接,连接成功后才能相互通信。
WSS(Web Socket Secure)是WebSocket的加密版本。