自从HTML5出来之后,使用WebSocket通讯就变得火热起来,基于WebSocket开发的手机APP和手机游戏也愈来愈多。个人一些开发APP的朋友,开始使用WebSocket通讯,后来以为通讯不够安全,想要对通讯进行加密,因而天然而然地就想从ws升级到wss。在升级的过程当中,就会存在旧的ws客户端与新的wss客户端同时链接到同一个服务器的状况。因此,若是同一个服务端,能同时支持ws和wss,那就太方便了。html
一. 实现方案
可是,要服务端同时支持ws与wss并不太容易,其难点主要在于:wss通道必须在TCP链接刚创建时(收发消息前)就要先进行SSL加密,不然,后续的通讯将没法正常进行。如此一来,当同时存在ws和wss客户端时,服务器在还没有通讯以前就没法具体分辨哪一个是ws哪一个是wss。那怎么办了?咱们的解决方案,是采用试探法,该方案已经在 ESFramework 通讯框架中实现。 api
(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秒以后。加密
基于以上方案实现服务端后,咱们接下来基于 ESFramework入门demo 来具体讲解一下如何在实际应用中同时支持ws和wss。spa
二. 服务端实现
1. 数字证书
为测试方便,咱们可使用 CertificateCreator制做一个用于本地测试的数字证书。code
运行 CertificateCreator.exe, 而后输入Common Name(好比Test)、密码、保存路径(好比D:\server.pfx),咱们就能够获得包含私钥的证书server.pfx 。双击server.pfx ,便可安装证书。
2. 服务端引擎设置
在服务端RapidServerEngine初始化以前,添加以下代码设置其 WssOptions 属性:
WssOptions wssOptions = new WssOptions( new X509Certificate2("D:\\server.pfx", "password") ,SslProtocols.Default ,false);
rapidServerEngine.WssOptions = wssOptions;
设置完成后,启动服务端。
三. 客户端实现
1. 信任测试用的数字证书
因为上述生成的数字证书仅仅是用于测试的,而是不被正式承认的,因此,须要在浏览器设置中,将目标数字证书加入到信任列表。
好比,在360浏览器中,可以下设置:
在FireFox中,设置以下:
将服务器的地址(https://127.0.0.1:4530)添加到例外中。
2. 客户端引擎设置
打开入门demo的Web端源码中的index.js文件,找到engine的Initialize方法,将useWss 参数由false修改成true。
而后将Web端的 index.html 文件拖入浏览器中运行便可。
四. 运行效果
登陆一个wss客户端,一个ws客户端和一个.NET客户端,服务端的UI显示以下: