Find number of active sessions created from a given client IP

前端 未结 3 1268
星月不相逢
星月不相逢 2020-12-03 00:29

Is there a way to determine the number of active sessions created from a given client IP address?

3条回答
  •  执笔经年
    2020-12-03 00:49

    The standard Servlet API doesn't offer facilities for that. Best what you can do is to maintain a Map yourself (where the String is the IP address) with and check on every ServletRequest if the HttpSession#isNew() and add it to the Map along with ServletRequest#getRemoteAddr(). Then you can get the amount of IP addresses with an active session using Collections#frequency() on Map#values(). You only need to ensure that you remove the HttpSession from the Map during HttpSessionListener#sessionDestroyed().

    This all can be done in a single Listener implementing the ServletContextListener, HttpSessionListener and ServletRequestListener.

    Here's a kickoff example:

    public class SessionCounter implements ServletContextListener, HttpSessionListener, ServletRequestListener {
    
        private static final String ATTRIBUTE_NAME = "com.example.SessionCounter";
        private Map sessions = new ConcurrentHashMap();
    
        @Override
        public void contextInitialized(ServletContextEvent event) {
            event.getServletContext().setAttribute(ATTRIBUTE_NAME, this);
        }
    
        @Override
        public void requestInitialized(ServletRequestEvent event) {
            HttpServletRequest request = (HttpServletRequest) event.getServletRequest();
            HttpSession session = request.getSession();
            if (session.isNew()) {
                sessions.put(session, request.getRemoteAddr());
            }
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent event) {
            sessions.remove(event.getSession());
        }
    
        @Override
        public void sessionCreated(HttpSessionEvent event) {
            // NOOP. Useless since we can't obtain IP here.
        }
    
        @Override
        public void requestDestroyed(ServletRequestEvent event) {
            // NOOP. No logic needed.
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent event) {
            // NOOP. No logic needed. Maybe some future cleanup?
        }
    
        public static SessionCounter getInstance(ServletContext context) {
            return (SessionCounter) context.getAttribute(ATTRIBUTE_NAME);
        }
    
        public int getCount(String remoteAddr) {
            return Collections.frequency(sessions.values(), remoteAddr);
        }
    
    }
    

    Define it in web.xml like follows:

    
        com.example.SessionCounter
    
    

    You can use it in any servlet like follows:

    SessionCounter counter = SessionCounter.getInstance(getServletContext());
    int count = counter.getCount("127.0.0.1");
    

提交回复
热议问题