当前位置: 首页 > news >正文

websocket获取客服端真实ip

在websocket建立连接时,获取访问客户端的真实ip

1. websocket建立连接过程
在这里插入图片描述
2. pom依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

3. 添加配置,握手过程中,设置真实客户端ip


import javax.servlet.http.HttpServletRequest;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import java.lang.reflect.Field;

public class WebSocketIpConfigurator extends ServerEndpointConfig.Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        try {
            // 通过反射获取底层 ServletRequest
            Field requestField = request.getClass().getDeclaredField("request");
            requestField.setAccessible(true);
            HttpServletRequest httpRequest = (HttpServletRequest) requestField.get(request);

            // 解析真实 IP
            String clientIp = IpUtils.getClientIp(httpRequest);
            sec.getUserProperties().put("clientIp", clientIp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class IpUtils {
    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        // 处理多级代理(取第一个 IP)
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        return ip;
    }
}

4. websocket建立连接时,加载配置,设置ip
在这里插入图片描述
5. 获取真实ip调用

在这里插入图片描述

http://www.dtcms.com/a/102029.html

相关文章:

  • Linux | I.MX6ULL 终结者底板原理图讲解(5)
  • 最新万能场馆预约系统源码 基于ThinkPHP+UniApp 含图文搭建部署教程
  • Python+新版DeepSeek V3轻松开发Agent
  • Unity跨平台输入系统
  • Doris Streamloader安装教程
  • LeetCode 78.子集
  • 字符函数,日期函数笔记
  • QinQ-端口安全
  • 【54】结构体:结构体指针的内存与通信
  • Qt信号槽
  • 3D设计在UI中的应用:2025年的设计新潮流!
  • OpenMCU(五):STM32F103时钟树初始化分析
  • 黑帽SEO之搜索引擎劫持-域名劫持原理分析
  • 银发浪潮下的智能护理革命:全球老龄化社会护理机器人发展研究
  • AI时代新坐标!火石会:应时而生,聚势而为
  • AI推理胜过人脑?思维模型!【34】长线思考思维模型
  • 普冉单片机PY32F002BF,使用adc内部参考电压VREFINT检测。
  • uniapp 微信小程序项目中 地图 map组件 滑动面板
  • 2025 年广东水利水电安全员考试:理论与实践融合攻略​
  • 通过redis缓存获取菜品数据
  • Docker学习--容器操作相关命令--docker events 命令
  • 【mapreduce】工作原理
  • livekit ICE连接失败的一些总结
  • 鬼泣:升龙系统
  • Linux-线程概念与线程控制的常用操作
  • 通过动态获取项目的上下文路径来确保请求的 URL 兼容两种启动方式(IDEA 启动和 Tomcat 部署)下都能正确解析
  • 深度解析算法之滑动窗口
  • 清晰易懂的Rust安装与配置教程
  • 【区块链安全 | 第十五篇】类型之值类型(二)
  • 在 RK3588 多线程推理 YOLO 时,同时开启硬件解码和 RGA 加速的性能分析