Найти количество активных сессий, созданных с заданного IP-адреса клиента - PullRequest
10 голосов
/ 09 сентября 2010

Есть ли способ определить количество активных сеансов, созданных с данного IP-адреса клиента?

Ответы [ 3 ]

13 голосов
/ 09 сентября 2010

Стандартный Servlet API не предоставляет возможности для этого.Лучшее, что вы можете сделать, - это сохранить Map<HttpSession, String> самостоятельно (где String - IP-адрес) и проверять каждый ServletRequest, если HttpSession#isNew() и добавьте его к Map вместе с ServletRequest#getRemoteAddr().Затем вы можете получить количество IP-адресов с активным сеансом, используя Collections#frequency() на Map#values().Вам нужно только убедиться, что вы удалили HttpSession из Map во время HttpSessionListener#sessionDestroyed().

Все это можно сделать за один Listener, реализующий ServletContextListener, HttpSessionListener и ServletRequestListener.

Вот пример запуска:

public class SessionCounter implements ServletContextListener, HttpSessionListener, ServletRequestListener {

    private static final String ATTRIBUTE_NAME = "com.example.SessionCounter";
    private Map<HttpSession, String> sessions = new ConcurrentHashMap<HttpSession, String>();

    @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);
    }

}

Определите его вweb.xml как показано ниже:

<listener>
    <listener-class>com.example.SessionCounter</listener-class>
</listener>

Вы можете использовать его в любом сервлете следующим образом:

SessionCounter counter = SessionCounter.getInstance(getServletContext());
int count = counter.getCount("127.0.0.1");
1 голос
/ 22 июля 2015

Мне нужно было быстро получить эту информацию без новых развертываний.Это можно сделать, изменив JSP и добавив следующий фрагмент.(Только сеансы с активностью получат установленное значение):

<%
 // Set user agent and ip in session
 session.setAttribute("agent", request.getHeader("user-agent") + "@" + request.getRemoteAddr());
%>

Затем создайте скрипт groovy для запроса jmx:

import javax.management.remote.*
import javax.management.*
import groovy.jmx.builder.*

// Setup JMX connection.
def connection = new JmxBuilder().client(port: 4934, host: '192.168.10.6')
connection.connect()

// Get the MBeanServer.
def mbeans = connection.MBeanServerConnection

def mbean = new GroovyMBean(mbeans, 'Catalina:type=Manager,host=localhost,context=/')
println "Active sessions: " + mbean['activeSessions']

def sessions = mbean.listSessionIds().tokenize(' ');

def ips = [:];
def agents = [:];

sessions.each
{
    def agentString = mbean.getSessionAttribute(it, "agent");
    if(agentString != null)
    {
        agent = agentString.tokenize('@');
    }
    else
    {   
        agent = ['unknown', 'unknown'];
    }

    if(agents[agent[0]] == null)
    {
        agents[agent[0]] = [];
    }
    agents[agent[0]] += [it];

    if(ips[agent[1]] == null)
    {
        ips[agent[1]] = [];
    }
    ips[agent[1]] += it;


};

println "Ips"
ips = ips.sort { -it.value.size }
ips.each
{
    ip, list ->
    println "${ip}\t${list.value.size}";
    //println list;
    //println "";
}

println ""
println "Agents"
agents = agents.sort { -it.value.size }
agents.each
{
    agent, list ->
    println "${agent}\t${agents[agent].size}";
    //println list;
    //println "";
}

Результат

Active sessions: 729
Ips
unknown 102
68.180.230.118  11
80.213.88.107   11
157.55.39.127   9
81.191.247.166  2
...

Agents
Mozilla/5.0 (compatible; MJ12bot/v1.4.5; http://www.majestic12.co.uk/bot.php?+) 117
unknown 102
Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) 55
Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp) 29
...
0 голосов
/ 08 ноября 2011

Очень хороший пример Balus C. Мы решили эту проблему, используя Observer Listener. Вот хороший пример / учебник для того же.

http://www.big -oh.net / BigOhSoftwareWeb / содержание / учебники / requestObserverListener.jsp

Просто подумал, что это будет полезно для других посетителей. :)

Редактировать: *** апрель 2017 **

Похоже, что сайт http://www.big -oh.net / , содержащий указанный выше источник, мертв. Здесь является источником от web.archive.org. Также добавленный файл ссылается на веб-страницу в github gist. Gist source и его html preview

...