在 Websocket 通过 Nginx 转发用户 IP

我正在使用这个 Websocket 库和这里的示例来创建基于 websockets 的多个服务。


接收请求的主服务器是 Nginx 服务器,它根据请求的来源(基于域)转发请求,因此我可以确定收到的请求是针对 websocket 的。


然而问题出在这里:


public void onOpen(WebSocket ws, ClientHandshake handshake) {

    System.out.println("-------------------------------");

    System.out.println(ws.getRemoteSocketAddress());

    System.out.println("-------------------------------");

}

getRemoteSocketAddress将始终返回 nginx 服务器 IP,类似于/192.168.1.100:43556


我的nginx配置是:


server{

    listen 80;

    server_name we.mydomain.com;

    access_log /var/log/nginx/access-ws-debug.log;

    error_log /var/log/nginx/error-ws-debug.log;


    set_real_ip_from  192.168.1.0/24;

    real_ip_header X-Real-IP;

    real_ip_recursive on;


    location / {

       proxy_pass http://192.168.1.101:54321;


       proxy_http_version 1.1;

       proxy_set_header X-Real-IP $remote_addr;

       proxy_set_header Host $http_host; #host

       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

       proxy_set_header Y-Real-IP $realip_remote_addr;


       proxy_set_header Upgrade $http_upgrade;

       proxy_set_header Connection "Upgrade";


       proxy_connect_timeout 1d;

       proxy_send_timeout 1d;

       proxy_read_timeout 1d;

    }

}

nxing的配置有问题吗?或者有没有其他方法可以获取websocket背后用户的IP?


感谢马克的回答解决了。以下代码与提到的库无关。它是jsp 中没有任何库的“经典”Web 实现。


我将握手修改为如下所示:


@Override

public void modifyHandshake(

        ServerEndpointConfig config,

        HandshakeRequest request,

        HandshakeResponse response

) {

    HttpSession httpSession = (HttpSession) request.getHttpSession();

    config.getUserProperties().put(HttpSession.class.getName(), httpSession);

    config.getUserProperties().put("Headers",request.getHeaders());

}

要获取标题,只需在 OnOpen 中调用它:


@OnOpen

public void onOpen(final Session session, EndpointConfig config){ //This happens when javascript opens socket session

    Object list = config.getUserProperties().get("Headers");

    System.out.println("-------------------------------------");

    System.out.println(list);

    System.out.println("-------------------------------------");

}



慕田峪9158850
浏览 270回答 1
1回答

慕工程0101907

这不是一项微不足道的任务,但您的配置看起来不错,您只需要从您设置的标头中获取原始 IP ( X-Real-IP)。import javax.websocket.*;import javax.websocket.server.HandshakeRequest;import javax.websocket.server.ServerEndpoint;import javax.websocket.server.ServerEndpointConfig;@ServerEndpoint(value = "/test", configurator = Test.TestConfiguratior.class)public class Test extends Endpoint {    @Override    public void onOpen(Session session, EndpointConfig endpointConfig) {        Object o = endpointConfig.getUserProperties().get(TestConfiguratior.HEADER_NAME);        //o should be the string object you are looking for    }    @OnMessage    public void onMessage(Session session, String msg) {        //do what u want    }    public static class TestConfiguratior extends ServerEndpointConfig.Configurator {        static String HEADER_NAME = "X-Real-IP";        @Override        public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {            String firstFoundHeader = request.getHeaders().get(HEADER_NAME.toLowerCase()).get(0);            sec.getUserProperties().put(HEADER_NAME, firstFoundHeader);        }    }}TL.DR.:您可以使用javax.websocket.EndpointConfig#getUserProperties地图将数据放入其中并稍后检索。最初我认为这在使用这个确切的代码时会导致一些并发问题,但我无法重现它。甚至文档也建议这样做:https : //javaee.github.io/tutorial/websocket010.html更新:这是一个JSR 356示例,并非特定于上述框架。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java