最近在做一个小游戏项目,准备上线的时候,却发现移动网络居然连接不了mqtt ,后来客户端把ws 换成wss就解决连接的问题了,但是随之而来的还有另一个问题,服务器无法获取到真实IP了。大致数据是这样的
猜测方向,应该是由于使用了证书文件有关
Nginx简单配置如下
upstream mqttServer {
server 127.0.0.1:3088 weight=1;
}
server {
listen 80;
listen 443 ssl;
server_name www.*****.com;
ssl_certificate cert/*****.pem;
ssl_certificate_key cert/********.key;
ssl_session_timeout 5m;
ssl_ciphers ******************************;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
index index.htm index.html index.php;
}
location /mqtt {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://mqttServer/mqtt;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
因为本质上还是用了反向代理,所以直接从Remote Address中获取的ip是就是服务器的IP,只能转发到Header 头获取
目前使用的是mqant的框架,我们在ws_server.go 里面打印用户建立ws连接前的http请求头
可以看出,这一步是能拿到客户端IP
走到这里,
我们要考虑的问题是在升级成ws之后,把这个真实IP注入到会话conn.RemoteAddr当中,
可惜的是,mqant当前并没有提供SetRemoteAddr方法
因此,我们的思路主要有两个
1. 在这里用一个映射关系,把SessionID与真实IP绑定,在断开连接是在释放资源
2.业务层处理,每次建立WS连接之前都请求一个http请求,把用户的IP保存在持久化数据中(Redis),wss的协议请求中默许最近保存的IP就是当前IP
目前由于业务不复杂,出于稳定性和不埋坑的角度,我这里选择的是第二个方案。
以上就此这次处理wss 获取真实IP的解决思路
来源:oschina
链接:https://my.oschina.net/u/2007165/blog/4906605