import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class SimpleCORSFilter implements Filter {<!-- --> @Override public void init(FilterConfig filterConfig) throws ServletException {<!-- --> } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {<!-- --> HttpServletRequest req= (HttpServletRequest) request; req.getSession().setAttribute("ipAddr",req.getRemoteHost()); HttpServletResponse res = (HttpServletResponse)response; res.setHeader("Access-Control-Allow-Origin", "*"); res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); res.setHeader("Access-Control-Max-Age", "3600"); res.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content- Type, X-E4M-With,userId,token,timestamp"); chain.doFilter(request, response); } @Override public void destroy() {<!-- --> } }
import com.neo.websocket.WebSocketConfig; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; @Component @ServerEndpoint(value = "/wsTask/{userId}/{tId}", configurator = WebSocketConfig.class) //Interface path ws://localhost:8087/webSocket/userId/111; public class TaskWebSocket {<!-- --> private static AsynSendMsg asyncSendMsg; @Autowired public void setAsynSendMsg(AsynSendMsg asyncSendMsg) {<!-- --> TaskWebSocket.asyncSendMsg = asyncSendMsg; } public Logger log = LogManager.getLogger(getClass()); //The connection session with a client needs to be used to send data to the client private Session session; /** *User ID */ private String userId; //The thread-safe Set of the concurrent package is used to store the MyWebSocket object corresponding to each client. //Although @Component is singleton mode by default, springboot will still initialize a bean for each websocket connection, so it can be saved with a static set. // Note: WebSocket below is the current class name private static CopyOnWriteArraySet<TaskWebSocket> webSockets =new CopyOnWriteArraySet<>(); // Used to store user information for line connection private static ConcurrentHashMap<String,Session> sessionPool = new ConcurrentHashMap<String,Session>(); public Session getSession() {<!-- --> return session; } public String getUserId() {<!-- --> return userId; } public static CopyOnWriteArraySet<TaskWebSocket> getWebSockets() {<!-- --> return webSockets; } public static ConcurrentHashMap<String, Session> getSessionPool() {<!-- --> return sessionPool; } /** * Method called successfully by link */ @OnOpen public void onOpen(Session session, @PathParam(value="userId")String userId, @PathParam(value="tId")String tId) {<!-- --> try {<!-- --> this.session = session; this.userId = userId; webSockets.add(this); sessionPool.put(userId, session); log.info("[websocket message] There are new connections, the total number is:" + webSockets.size()); asyncSendMsg.sendOneMessage(userId,tId,session); } catch (Exception e) {<!-- --> } } /** * Method called by link closing */ @OnClose public void onClose() {<!-- --> try {<!-- --> webSockets.remove(this); sessionPool.remove(this.userId); log.info("[websocket message] The connection is disconnected, the total number is:" + webSockets.size()); } catch (Exception e) {<!-- --> } } /** * Method called after receiving client message * * @param message */ @OnMessage public void onMessage(String message) throws InterruptedException {<!-- --> log.info("[websocket message] Received client message:" + message); } /** Handling when sending errors * @param session * @param error */ @OnError public void onError(Session session, Throwable error) {<!-- --> log.error("User error, reason:" + error.getMessage()); error.printStackTrace(); } // This is a broadcast message public void sendAllMessage(String message) {<!-- --> log.info("[websocket message] broadcast message:" + message); for(TaskWebSocket webSocket : webSockets) {<!-- --> try {<!-- --> if(webSocket.session.isOpen()) {<!-- --> webSocket.session.getAsyncRemote().sendText(message); } } catch (Exception e) {<!-- --> e.printStackTrace(); } } } // This is a single point message public void sendOneMessage(String userId,String message,Session session) throws InterruptedException {<!-- --> while (sessionPool.get(userId)!= null & amp; & amp;sessionPool.get(userId).isOpen()) {<!-- --> try {<!-- --> log.info("[websocket message] Single point message:" + message); session.getAsyncRemote().sendText(message); } catch (Exception e) {<!-- --> e.printStackTrace(); } Thread.sleep(2000); } } // This is a single point message (multiple people) public void sendMoreMessage(String[] userIds, String message) {<!-- --> for(String userId:userIds) {<!-- --> Session session = sessionPool.get(userId); if (session != null & amp; & amp;session.isOpen()) {<!-- --> try {<!-- --> log.info("[websocket message] Single point message:" + message); session.getAsyncRemote().sendText(message); } catch (Exception e) {<!-- --> e.printStackTrace(); } } } } }
import com.alibaba.fastjson.JSONObject; import com.neo.dao.UserInfoDao; import com.neo.utils.IpUtils; import com.neo.utils.JwtUtils; import com.neo.utils.SpringUtils; import io.jsonwebtoken.ExpiredJwtException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import org.springframework.web.socket.server.standard.ServerEndpointExporter; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.websocket.HandshakeResponse; import javax.websocket.server.HandshakeRequest; import javax.websocket.server.ServerEndpointConfig; import java.util.List; //When packaging and deploying to tomcat, annotations are required @Component @Configuration @WebListener public class WebSocketConfig extends ServerEndpointConfig.Configurator {<!-- --> public Logger logger = LoggerFactory.getLogger(getClass()); @Bean public ServerEndpointExporter serverEndpointExporter() {<!-- --> return new ServerEndpointExporter(); } @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {<!-- --> //Get request headers List<String> list = request.getHeaders().get("Sec-WebSocket-Protocol"); //When the Sec-WebSocket-Protocol request header is not empty, the same response needs to be returned to the front end response.getHeaders().put("Sec-WebSocket-Protocol",list); if(list == null ||list.size()==0) {<!-- --> throw new RuntimeException("No token parameter"); }else {<!-- --> for (String token : list) {<!-- --> Boolean verfy = JwtUtils.verfy(token); if(!verfy) {<!-- --> logger.info("token is invalid"); throw new RuntimeException("token is invalid"); }else {<!-- --> try {<!-- --> HttpSession session = (HttpSession) request.getHttpSession(); String addr = ""; if (session != null) {<!-- --> addr = session.getAttribute("ipAddr").toString(); } String subject = JwtUtils.parseJwt(token).getSubject(); JSONObject jsonObject = JSONObject.parseObject(subject); String ip = jsonObject.getString("ip"); String fingerprintToken = jsonObject.getString("fingerprint"); String userAgent = request.getHeaders().get("User-Agent").get(0); String fingerprint = userAgent; if (!ip.equals(addr) || !fingerprintToken.contains(fingerprint)) {<!-- --> logger.info("The network environment has changed, please log in again!"); throw new RuntimeException("The network environment has changed, please log in again!"); } else {<!-- --> UserInfoDao userInfoDao = SpringUtils.getBean("userInfoDao", UserInfoDao.class); int i = userInfoDao.countToken(token); if (i > 0) {<!-- --> super.modifyHandshake(sec, request, response); } else {<!-- --> logger.info("Token has expired, please log in again!"); throw new RuntimeException("Token has expired, please log in again!"); } } } catch (ExpiredJwtException e) {<!-- --> logger.info("token has expired"); throw new RuntimeException("token has expired"); } catch (Exception e) {<!-- --> logger.info("token has expired"); e.printStackTrace(); throw new RuntimeException("token has expired"); } } } } } }