SpringBoot获取WebSocket IP地址

0

SpringBoot中通过RequestContextHolder.getRequestAttributes()获取不到WebSocketrequest请求,所以获取客户端真实IP地址需要通过下面这种方法:

/**
 * WebSocket配置器
 * 
 * @author acgist
 */
@Slf4j
public class WebSocketConfigurator extends ServerEndpointConfig.Configurator {

    public static final String CLIENT_IP = "CLIENT_IP";

    @Override
    public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
    	String clientIP = null;
    	List<String> list = null;
    	final Map<String, List<String>> headers = request.getHeaders();
    	log.debug("WebSocket头部:{}", headers);
    	if(CollectionUtils.isNotEmpty((list = headers.get("x-real-ip")))) {
    		clientIP = list.get(0);
    	} else if(CollectionUtils.isNotEmpty((list = headers.get("forwarded")))) {
//    		[proto=http;host="192.168.8.187:9999";for="192.168.8.216:56671"]
    		final String forwarded = list.get(0);
    		final Pattern compile = Pattern.compile(".*for=\"(?<ip>.*):.*");
        	final Matcher matcher = compile.matcher(forwarded);
        	if(matcher.matches()) {
        		clientIP = matcher.group("ip");
        	}
    	} else if(CollectionUtils.isNotEmpty((list = headers.get("x-forwarded-for")))) {
    		clientIP = list.get(0);
    	}
        final Map<String, Object> properties = config.getUserProperties();
        if(properties != null && clientIP != null) {
        	properties.put(WebSocketConfigurator.CLIENT_IP, clientIP);
        }
    }
    
}

@ServerEndpoint(value = "/admin/websocket", configurator = WebSocketConfigurator.class)

@OnOpen
public void open(Session session) {
	log.info("WebSocket打开:{}", session.getId());
	// IP授权
	synchronized (session) {
		final Map<String, Object> properties = session.getUserProperties();
		if(properties != null) {
			final String clientIP = (String) properties.get(WebSocketConfigurator.CLIENT_IP);
		}
	}
}