新建监听ServletRequest事件,发生在创建WebSocket的session之前
import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; public class WebServletRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { } @Override public void requestInitialized(ServletRequestEvent sre) { HttpServletRequest request=(HttpServletRequest) sre.getServletRequest(); HttpSession session=request.getSession(); //把HttpServletRequest中的IP地址放入HttpSession中,关键字可任取,此处为ClientIP session.setAttribute("client-ip", sre.getServletRequest().getRemoteAddr()); } }
2. 创建 ServerEndpoint 配置类
import javax.servlet.http.HttpSession; import javax.websocket.HandshakeResponse; import javax.websocket.server.HandshakeRequest; import javax.websocket.server.ServerEndpointConfig; import javax.websocket.server.ServerEndpointConfig.Configurator; public class GetHttpSessionConfigurator extends Configurator { @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { // TODO Auto-generated method stub HttpSession httpSession = (HttpSession) request.getHttpSession(); sec.getUserProperties().put(HttpSession.class.getName(), httpSession); //把HttpSession中保存的ClientIP放到ServerEndpointConfig中,关键字可以跟之前不同 sec.getUserProperties().put("client-ip", httpSession.getAttribute("client-ip")); } }
3. 创建 WebSocket 主类
import cn.hutool.core.date.DateUtil; import com.*.*.core.config.GetHttpSessionConfigurator; import plus.jfinal.entitys.Result; import javax.servlet.http.HttpSession; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * /websocket.ws/{id} = /websocket.ws/{登录用户编号} */ @ServerEndpoint(value ="/websocket.ws/{id}",configurator= GetHttpSessionConfigurator.class) public class MainWebSocket { private static final Map<String, MainWebSocket> WEBSOCKET = new ConcurrentHashMap<String, MainWebSocket>(); private Session session; private String host; private HttpSession httpSession; /** * 用户登录账号 */ private String id; @OnOpen public void onOpen( Session session,EndpointConfig config,@PathParam("id") String id) { this.id = id; this.session = session; // 这里就获得到IP咯 System.out.println("客户端请求IP:"+session.getUserProperties().get("client-ip")); // .... } @OnClose public void onClose() { if (WEBSOCKET != null && WEBSOCKET.containsKey(id)){ MainWebSocket webSocket = WEBSOCKET.get(id); if(webSocket.session.getId().equals(session.getId())){ WEBSOCKET.remove(id); } } System.out.println("有一连接关闭!当前在线人数为" + WEBSOCKET.size()); } @OnMessage public void onMessage(String message, Session session) { /* 不接收前端发送的消息 */ } @OnError public void onError(Session session, Throwable error) { error.printStackTrace(); } protected void sendMessage(String message) { try { this.session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } /** * 广播 * * @param message */ public static void broadcast(String message) { for (Map.Entry<String, MainWebSocket> entry : WEBSOCKET.entrySet()) { entry.getValue().sendMessage(message); } } /** * 发送消息 * @param id * @param message */ public static void sendMessage(String id,String message){ WEBSOCKET.get(id).sendMessage(message); } }
4. 配置启动类(任意位置)
public static void main(String[] args) { /** * 启动前先删除掉之前的进程 */ closeProccess(args); /** * */ UndertowServer.create(ApplicationConfig.class, "config/undertow.txt").configWeb(builder -> { builder.addListener("com.*.*.core.listener.WebServletRequestListener"); builder.addWebSocketEndpoint("com.*.*.websocket.MainWebSocket"); }).addHotSwapClassPrefix("com.*").addHotSwapClassPrefix("plus.jfinal").start(); }