ESFramework 使用技巧 -- 支持 微信小程序 和 加密的 WebSocket (wss)
微信小程序的WebSocket只支持wss,而在很多采用WebSocket的程序中,也经常需要使用SSL进行通信加密,所以,最新的ESFramework的WebSocket引擎增加了对wss的支持,同时也增加了对微信小程序的支持。本文将通过一个示例来介绍在ESFramework中如何使用wss ,本文示例基于 ESFramework Demo -- 入门Demo,简单的即时通讯系统(包含 .NET/Android/iOS/WebSocket/微信小程序/Xamarin 源码) 的示例源码进行改造 。
一. 服务端
1. 服务器启用 TLS 1.2
对于像Windows Server 2008 这样的服务器,TLS 1.2 默认是没有开启的。所以,要先进入服务器设置以开启 TLS 1.2。
开启TLS 1.2 有多种方法,具体可参见:Windows Server 配置 HTTPS TLS1.2
2. 数字证书
为测试方便,我们可以使用 CertificateCreator 制作一个用于本地测试的数字证书。
运行 CertificateCreator.exe, 然后输入Common Name(比如Test)、密码、保存路径(比如D:\server.pfx),我们就可以得到包含私钥的证书server.pfx 。双击server.pfx ,即可安装证书。
正式使用时,可以在阿里云申请正式的SSL证书。
3. 服务端引擎设置
在服务端RapidServerEngine初始化之前,添加如下代码设置其 WssOptions 属性:
WssOptions wssOptions = new WssOptions( new X509Certificate2("D:\\server.pfx", "password") ,SslProtocols.Default ,true); rapidServerEngine.WssOptions = wssOptions;
设置完成后,启动服务端。
4. 微信小程序要求必须使用443端口
如果客户端要支持微信小程序,则微信小程序WebSocket在真机上运行时,要求服务端必须使用443端口。(rapidServerEngine的Initialize方法传入要监听的端口)
注:如果小程序是在模拟器中运行,则可以使用非加密的WebSocket服务端和不使用443端口。
5. 关于iOS端小程序
iOS端小程序要求更多一些,官方文档可参见这里:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/network.html
(1)SslProtocol 要使用 TLS v1.2。
WssOptions wssOptions = new WssOptions( new X509Certificate2("D:\\server.pfx", "password") ,SslProtocols.Tls12,true); rapidServerEngine.WssOptions = wssOptions;
如果要支持TLS v1.2,.NET Framework 版本需要升级到4.6。也就是说,需要使用 .NET 4.6 编译的 ESFramework.dll。
(2)在服务器上使用 IISCrypto 工具进行设置。
按上图设置之后,需要重启服务器生效。
(3)自制证书无法连接成功。可以在阿里云或腾讯云申请证书,并且在目标域名所指的服务器上正式部署服务端,才可正常连接。
二.客户端
1. 信任测试用的数字证书
由于上述生成的数字证书仅仅是用于测试的,而是不被正式认可的,所以,需要在浏览器设置中,将目标数字证书加入到信任列表。
比如,在360浏览器中,可如下设置:
在FireFox中,设置如下:
将服务器的地址(https://127.0.0.1:4530)添加到例外中。
2. WebSocket客户端引擎设置
普通的WebSocket使用的引擎文件是:ESFramework.WebSocket.js
打开入门demo的【ESFramework.EntranceDemo-WebSocket客户端】源码中的index.js文件,找到engine的Initialize方法,将 useWss 参数由false修改为true。
另外,特别注意:当使用 wss 时,WebSocket 连接的服务器地址必须使用域名,而不能使用IP。
然后将Web端的 index.html 文件拖入浏览器中运行即可。
三. 运行效果
登录一个wss客户端,一个ws客户端和一个.NET客户端,服务端的UI显示如下:
四. 特别注意
ESFramework服务端为了支持能使用同一个TCP Port 同时服务于 wss客户端与其它类型的客户端(.NET、android、iOS、Xamarin、ws),采取了如下策略。
(1)由于wss通道必须在TCP连接刚建立时(收发消息前)就要先进行SSL加密,否则,后续的通信将无法正常进行。
(2)基于(1),在没有收发任何消息时,服务端就无法将wss客户端与其它客户端区分开来。
(3)为此采用的办法是:对于任何刚建立的TCP连接,先都不加密它,等收到的第一个消息来判断其消息的头标志。
(4)如果头标志不是ESFramework所规定的标志,则表示这第一个消息是密文,无法被解析,从而说明这个客户端是wss。于是将该客户端的ip放到cache中,并断开该连接。
(5)wss客户端会重新连上来,此时服务端从cache中发现已经存在目标ip,则判定其为wss客户端,于是立即使用SSL加密该通道,之后,该wss客户端就可以正常通信了。
(6)由于wss 客户端 IP在cache中的过期时间是 6秒左右,所以,如果一个客户端IP刚登录了wss客户端,那么在同一个IP上登录第二个客户端(任何客户端类型),就需要相隔6秒之后。
Q Q:168757008