前言
H5游戏项目是这个:bhuvan-byte/street-soccer-multi,因为这个项目的作者最近正好在重构整个项目,所以先git clone
到本地然后git reset --hard 395de056fe3aa45b5914a24f329b6229ad81d761
到最后一个重构前的commit
,运行之后访问http://172.21.0.2:8000
(docker
拉了个node
环境起来的)发现一切正常,于是在Nginx上配置了反代,配置文件如下:
#PROXY-START/street-soccer-multi/
location ^~ /street-soccer-multi/
{
proxy_pass http://172.21.0.2:8000/;
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_set_header REMOTE-HOST $remote_addr;
}
#PROXY-END/street-soccer-multi/
然后进http://loaclhost/street-soccer-multi/
之后发现好些资源文件404
了,问题不大,应该是作者代码习惯不好写了一堆绝对路径导致资源瞎飘。
进代码把所有资源文件都改成相对路径后,页面成功加载,但是游戏的Websocket
连接还是连不上,也是一直往根路径ws://loaclhost/socket.io/
请求。
于是改动前端在新建连接时的配置,从原来的sock = io();
改为sock = io({path: window.location.pathname + 'socket.io'})
,此处为了保险应写为'/socket.io'
,但咱们的Ngnix
反代路径就是/street-soccer-multi/
,所以无伤大雅。
再次进游戏,发现可以正常玩了,但是游戏画面疯狂掉帧,不过左上角帧率又完全正常,所以猜测不是性能问题而是代码层面的数据处理问题。
排查
此时重新去访问http://172.21.0.2:8000
发现一切正常,所以可以排除掉刚才爆改资源路径的问题,那么先看一下控制台报错吧,有一个ws://loaclhost/street-soccer-multi/socket.io/
无法连接的报错,但是游戏确确实实是可以玩并且有联机交互的,所以赶紧去看了下网络数据包,发现所有打算Upgrade
的ws
连接都返回了个{"code":3,"message":"Bad request"}
的报错,然后就以HTTP
模拟Websocket
进行连接了(socket.io
库的特色功能,不过感觉大部分时候都是帮倒忙的),于是猜测可能问题出在这,由于没有建立ws
长连接而导致交互缓慢,从而导致画面卡顿。
那么既然是websocket
握手期间发生的问题,那感觉就是Nginx
反打的锅了,于是上网找Nginx proxy socket.io
,发现了好几个同样问题的,根据推荐把反代的配置文件加了一下两行,再次尝试发现websocket
成功建立了。
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
其中connection_upgrade
参数需要在Nginx配置文件中设定map。
map $http_upgrade $connection_upgrade {
'websocket' upgrade;
'' close;
}
既然如此,那么还不如把那个降级的兼容性功能给关掉,于是前端新建连接的配置又加了俩参数。
sock = io({
transports: ['websocket'],
upgrade: false,
path: window.location.pathname + 'socket.io'
});
但是之前用Nginx转发到php
中Workerman
库编写的websocket
后端就没有这个握手问题,所以猜测应该是socket.io
的在处理上过于严谨了,非得Header
参数存在才升级连接,而不是只通过路径判断。
Comments 1 条评论
博主 Yi
跟师傅学到了,nginx默认只代理http协议的