websocket踩坑记

2021/06/16 posted in  服务端
Tags:  #php #网络

基本配置

为了解决知道用户时长,我们采用了websocket作为通讯,php采用了swoole的websocket功能。

主要有三个事件
Open 建立链接的处理
Message 收到客户端的处理
Close 关闭与客户端的处理

前端配置基本和后端一样, http页面能访问ws和wss,但https只能访问wss。

var ws = new WebSocket("wss://xxx/websocket")
ws.onopen = function () { 
    ws.send("hello"); 
}; 
ws.onmessage = function (resp) { 
    document.getElementById('total').innerHTML = resp.data; 
};
ws.onclose = function () {}; 

nginx配置:

upstream websocket {
    server 172.17.0.2:9507; # 如果只有一条可以直接放在proxy_pass里
}
location /websocket {
          proxy_pass http://websocket;
          proxy_read_timeout 60s;
          proxy_send_timeout 60s;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
}

链接的时候可以可以参数放在后面,服务器能从get里获取token参数进行鉴权
wss://test.com/websocket?token=abcdefg

需要注意,如果是启用swoole里面的ssl功能,需将proxy_pass的 http://websocket 改成https://websocket

因为我们默认wss走443端口,而我们443端口已经有配置证书,故直接走http://websocket即可。

心跳

因为我们默认服务器配置是60秒时候,所以前端或后端定时发送数据来维护链接即可。

 proxy_read_timeout 60s;
 proxy_send_timeout 60s;

前端

setInterval(wx.send('1'),100000); 

腾讯云的坑

如果是从CDN走websocket,默认也是支持的,默认根据源站的配置,走80端口。
链接是能链接,但是wss的时候会出现ws.send不了数据。 如果要使用websocket建议使用ECDN(全站加速)

官方说明

cdn是提供网站静态内容的加速分发处理能力,ECDN 为纯动态网站与动静态混合型网站提供高可靠、低延时一站式加速服务。具体您可以了解下对应产品的功能介绍
CDN的应用场景:https://cloud.tencent.com/document/product/228/37846
ECDN的功能介绍:https://cloud.tencent.com/document/product/570/10359

其它

附:
cdn的协议跟随引发的问题
WARNING ssl_accept: bad SSL client[127.0.0.1:35418], reason=156, error_string=http request #4068
这个错误说明有明文 HTTP 请求发送到了 SSL 的 HTTPS 端口。
https://github.com/swoole/swoole-src/issues/4068#event-4585154187