如何让服务端同时支持WebSocket和SSL加密的WebSocket(即同时支持ws和wss)?
2017-11-17 10:40
549 查看
自从HTML5出来以后,使用WebSocket通信就变得火热起来,基于WebSocket开发的手机APP和手机游戏也越来越多。我的一些开发APP的朋友,开始使用WebSocket通信,后来觉得通信不够安全,想要对通信进行加密,于是自然而然地就想从ws升级到wss。在升级的过程中,就会存在旧的ws客户端与新的wss客户端同时连接到同一个服务器的情况。所以,如果同一个服务端,能同时支持ws和wss,那就太方便了。
(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。
运行 CertificateCreator.exe, 然后输入Common Name(比如Test)、密码、保存路径(比如D:\server.pfx),我们就可以得到包含私钥的证书server.pfx 。双击server.pfx ,即可安装证书。
设置完成后,启动服务端。
比如,在360浏览器中,可如下设置:
在FireFox中,设置如下:
将服务器的地址(https://127.0.0.1:4530)添加到例外中。
然后将Web端的 index.html 文件拖入浏览器中运行即可。
下载 Demo源码 。
一. 实现方案
但是,要服务端同时支持ws与wss并不太容易,其难点主要在于:wss通道必须在TCP连接刚建立时(收发消息前)就要先进行SSL加密,否则,后续的通信将无法正常进行。如此一来,当同时存在ws和wss客户端时,服务器在尚未通信之前就无法具体分辨哪个是ws哪个是wss。那怎么办了?我们的解决方案,是采用试探法,该方案已经在 ESFramework 通信框架中实现。(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。
二. 服务端实现
1. 数字证书
为测试方便,我们可以使用 CertificateCreator 制作一个用于本地测试的数字证书。运行 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显示如下:下载 Demo源码 。
相关文章推荐
- 如何让服务端同时支持WebSocket和SSL加密的WebSocket(即同时支持ws和wss)?
- 如何解决实际错误:配置IIS使其支持SSL加密的HTTPS,并且要求浏览器客户端证书
- mqtt+ssl服务搭建以及ws+wss支持
- Mina 在 Spring 中配置同时支持 SSL 加密连接和非 SSL 连接
- 如何解决实际错误:配置IIS使其支持SSL加密的HTTPS,并且要求浏览器客户端证书
- 阿里云负载不支持 WebSocket 协议与 WSS 和 Nginx 配置问题
- swoole websocket 支持ssl
- LCD扩展:高通平台如何同时支持多款LCD
- 即时通信系统中如何实现:支持PC端和移动端同时在线(即支持同帐号多设备同时登录)?
- node如何让一个端口同时支持https与http
- Websocket SSL加密之android端(带重连)
- 如何通过HTTPS(SSL加密)方式访问webservice
- Delphi纯代码连SQLite数据库,同时支持数据库的加密解密
- 测试PHP服务端是否支持SSL
- 图文并茂为您详解如何配置Domino CA以支持SSL
- 如何设置POP3/SMTP的SSL加密方式?
- Vsftpd完全攻略(四)搭建支持SSL加密传输的vftpd
- android开发如何定制状态栏的颜色,同时支持4.4(KIKAT,api19)和19以上系统。
- wifidog 编译https通信、支持ssl加密、https通信
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获