关于WebSocket,维基百科是这样介绍的:

在我的项目中,有个学习动态的模块,因为本身维护+开发,项目刚上没多久,初期也比较冷清。所以想弄个实时的学习动态,所有在线用户操作,都会进行广播。后台在某些场景下推送一些消息。不过因为冷清和网页美观方面(不知道放在哪个位置好看等因素),所以没有做。

不过在浏览一个前端大神的博客中,发现他的网站做的特别好 —传送门— ,一个是页面切换。一个是实时在线人数。所以把广播改成后台实时在线人员监控。

原理:用websocket 进行长链接。

故事

最开始是在本地测试完毕。然后上线后出了问题

好家伙,这种情况,毫无疑问我们就需要使用 wss:// 安全协议了,于是立即修改前端代码,把连接服务端webscoket的形式由ws:// 改为 wss:// 。本以为这样就解决了,没想到一段时间后下一个问题又来了。

扩展:关于 ws 和 wss


前端改成wss连接后,测试发现还是无法正常游戏。无奈,再次打开浏览器面板,果然,又看到一个新的问题。

浏览器控制面板异常信息

之前在Http的情况下,客户端一直是用ip+port的形式来连接服务端,当然了也不会出现什么问题。很明显,在更改成Https后,若还是以这种方式连接服务端,浏览器就会报 SSL 协议错误,这很明显就是证书的问题。如果这时候还用 IP + 端口号 的方式连接 WebSocket ,是根本就没有证书存在的(即使我们在Nginx配置了SSL证书,但这种方式其实是不会走Nginx代理的),所以在生成环境下,更推荐大家用域名的方式来连接。于是,立刻又联系前端,再一次做更改,修改为 wss://{域名}/ 进行连接。我以为这样就真的解决了,没想到还是too young too simple,没一会下个问题又来了,测试反馈的结果还是不可以,第三次打开浏览器控制面板,果然又是一个新的错误信息。

浏览器控制面板异常信息

看到这个错误信息后,确定这是服务端返回的400响应。既然可以请求到服务端,就说明客户端这边是没有问题的,那么问题最可能出在客户端和服务端之间。由于中间层使用了Nginx做转发,所以导致服务端无法知道这是一个合法的WebSocket请求。于是立刻查找了网上资料,在Nginx配置文件加入了以下配置,成功解决了这个问题。

   server {
    listen       443 ssl;
        server_name  wss.wkcto.com ;
        ssl_certificate   cert/wss.wkcto.com/cert-1542100842869_wss.wkcto.com.crt;
        ssl_certificate_key  cert/wss.wkcto.com/cert-1542100842869_wss.wkcto.com.key;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
       # root  /usr/share/nginx/html/wss;
       location /websocket{
                proxy_pass http://localhost:1990;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
      }
    }

接着,连忙拿域名进行再次连接测试,终于看到了101 Switching Protocols的响应Status Code。就这样,也算是终于解决完在 HTTPS 下以 wss://{域名}/websocket 的方式连接 WebSocket的一系列问题。

参考文章:https://blog.csdn.net/qq_28804275/article/details/80891921

Last modification:January 30, 2020
如果觉得我的文章对你有用,请随意赞赏