Java Websocket 获取客户端 IP 地址
Java WebSocket IP About 4,868 words方法一:反射
如果WebSocket
前端有负债均衡,则此方法获取到的都是负载均衡机器的IP
地址。
public class WebsocketUtil {
public static InetSocketAddress getRemoteAddress(Session session) {
if (session == null) {
return null;
}
Async async = session.getAsyncRemote();
//在Tomcat 8.0.x版本有效
// InetSocketAddress addr = (InetSocketAddress) getFieldInstance(async,"base#sos#socketWrapper#socket#sc#remoteAddress");
//在Tomcat 8.5以上版本有效
InetSocketAddress addr = (InetSocketAddress) getFieldInstance(async,"base#socketWrapper#socket#sc#remoteAddress");
return addr;
}
private static Object getFieldInstance(Object obj, String fieldPath) {
String fields[] = fieldPath.split("#");
for (String field : fields) {
obj = getField(obj, obj.getClass(), field);
if (obj == null) {
return null;
}
}
return obj;
}
private static Object getField(Object obj, Class<?> clazz, String fieldName) {
for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
try {
Field field;
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(obj);
} catch (Exception ignore) {
}
}
return null;
}
}
方法二:HttpSession
前一篇文章 讲过WebSocket
关联HttpSession
,那我们可以在初始化请求时将ServletRequest
中的RemoteAddr
(即IP
地址)存到HttpSession
中,然后再在WebSocket
握手阶段获取到的HttpSession
并放入到WebSocketSession
的UserProperties
用户属性这个Map
中。这样就可以在WebSocket
整个生命周期都能获得连接的客户端IP
地址。
单点部署情况
@WebListener
public class MyServletListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
HttpSession session = request.getSession();
System.out.println("requestInitialized session = " + session);
session.setAttribute("ClientIP", request.getRemoteAddr());//把HttpServletRequest中的IP地址放入HttpSession中,关键字可任取,此处为ClientIP
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("requestDestroyed sre = " + sre);
}
}
public class WebSocketServerConfigurator extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
System.out.println("modifyHandshake");
HttpSession httpSession = (HttpSession) request.getHttpSession();
if (httpSession != null) {
Map<String, Object> userProperties = sec.getUserProperties();
userProperties.put(HttpSession.class.getName(), httpSession);
}
}
}
@ServerEndpoint(value = "/test/ws/{username}", configurator = WebSocketServerConfigurator.class)
public class WebSocketServer {
@OnOpen
public void onOpen(@PathParam("username") String username, Session session) {
HttpSession httpSession = (HttpSession) session.getUserProperties().get(HttpSession.class.getName());
System.out.println("onOpen#" + httpSession.getAttribute("ClientIP"));
// 最大超时时间 60 秒
session.setMaxIdleTimeout(TimeUnit.MINUTES.toMillis(5));
session.setMaxBinaryMessageBufferSize(8192 * 1024); // 8KB
session.setMaxTextMessageBufferSize(8192 * 1024); // 字符数
session.getAsyncRemote().sendText("123");
}
// ... 省略了其他事件
}
负载均衡情况
根据负载机器设置的Header
,取出相应的IP
地址。
@WebListener
public class MyServletListener implements ServletRequestListener {
public MyServletListener() {
System.out.println("MyServletListener 构造方法 加载了, thread name#" + Thread.currentThread().getName() + ", thread id#" + Thread.currentThread().getId());
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
HttpSession session = request.getSession();
System.out.println("requestInitialized session = " + session + ", getRequestURL#" + request.getRequestURL().toString() + ", getRemoteHost#" + request.getRemoteHost() + ", getRemoteAddr#" + request.getRemoteAddr());
String host = request.getHeader("Host");
String xRealIP = request.getHeader("X-Real-IP");
String xForwardedFor = request.getHeader("X-Forwarded-For");
System.out.println("host#" + host + ", X-Real-IP#" + xRealIP + ", X-Forwarded-For#" + xForwardedFor);
session.setAttribute("ClientIP", xForwardedFor);
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("requestDestroyed sre = " + sre);
}
}
参考
Views: 9,802 · Posted: 2021-04-22
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...