Java统计用户在线人数,这样做才优雅

统计用户在线人数

在统计用户在人数的时候,我们用到了监听器,监听器大致分为以下三种:

  1. ServletRequestListener:用于监听请求的监听接口
  2. HttpSessionListener:用于监听会话的监听接口
  3. ServletContextListener:用于监听应用的回话接口

错误的统计办法

监听Request域

这种统计办法是错误的认为每次刷新页面后进行进行一次的count++运算

import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;

@WebListener()
public class MyRequestListener implements ServletRequestListener{
    private ServletContext sc;
    private Integer count;
    @Override
    //请求被初始化 Request
    public void requestInitialized(ServletRequestEvent sre) {
        //获取全局域
        sc = sre.getServletContext();
        //将count从全局域中获取出来
        count = (Integer) sc.getAttribute("count");
        System.out.println(count);
        count++;
        System.out.println(count);
        sc.setAttribute("count",count);
    }
}
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;

@WebListener()
public class MyServletContextListener implements ServletContextListener{
    private ServletContext sc;
    @Override
    //Application被初始化的时候创建
    public void contextInitialized(ServletContextEvent sce) {
        Integer count = 0;
        //获取全局域
        sc = sce.getServletContext();
        //将count放入到全局域中
        sc.setAttribute("count",count);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

  
    $Titlelt;/title>
  </head>
  <body>
  <center><h1>You are the ${applicationScope.count} customer to visit. </h1></center>
  </body>
</html>
</code></pre><p style="text-align: left;" data-track="12"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">这种错误地做法导致的是每刷新一次页面 就会导致count进行累加操作,最终产生错误的在线人数,所以此时想到不应该监听Request域,而应该监听Session域。</span></p><h1 class="pgc-h-arrow-right" data-track="13">监听Session域</h1><p style="text-align: left;" data-track="14"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">在第二次监听Session域之后,发现每次刷新页面后不改变count但是在启动不同的浏览器后</span><span style="color: #EF7060; --tt-darkmode-color: #EF7060;">count++</span>会实现,但是,这样做并不是我们要统计的在线人数,所以此种做法错误。由于代码只是将原来写在Request监听器中的代码转移到Session监听器中,所以其他没变的代码将不重复。</p><pre><code>import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;

@WebListener()
public class MySessionListener implements HttpSessionListener{

    private ServletContext sc;
    private Integer count;

    @Override
    //当对话产生时激活此方法
    public void sessionCreated(HttpSessionEvent se) {
        sc = se.getSession().getServletContext();
        count = (Integer) sc.getAttribute("count");
        count++;
        sc.setAttribute("count",count);
    }
}
</code></pre><p style="text-align: left;" data-track="16"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">这时我们发现对于在线人数的统计,不是网页访问的次数,也不是浏览器打开的个数,对需求的理解的错误理解。所以正确的做法是统计其IP的数量,这样的话,不管你在一台电脑上开启多少客户端,都会只有一个。</span></p><h1 class="pgc-h-arrow-right" data-track="17">正确的统计方法</h1><p style="text-align: left;" data-track="18"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">统计其IP的数量,将IP的数量作为当前的在线人数,那么如何统计IP的数量呢?这样将会导出以下问题:</span></p><ul><li data-track="19"><span style="color: #010101; --tt-darkmode-color: #A3A3A3;">如何获取用户的IP?</span></li><li data-track="20"><span style="color: #010101; --tt-darkmode-color: #A3A3A3;">IP将如何存储?</span></li><li data-track="21"><span style="color: #010101; --tt-darkmode-color: #A3A3A3;">如何判断IP之前已经存在?</span></li></ul><p style="text-align: left;" data-track="22"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">现在来解决这些问题:</span></p><ul><li data-track="23"><span style="color: #010101; --tt-darkmode-color: #A3A3A3;">只能从请求中获取</span></li><li data-track="24"><span style="color: #010101; --tt-darkmode-color: #A3A3A3;">通过2、3问题,我们想到了集合(List),因为集合不仅可以存储任何字符串,还可以通过遍历来判断之前是否有重复的IP出现。</span></li></ul><p style="text-align: left;" data-track="25"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">到了这里又冒出来一个问题集合(List)放到哪个域里呢?</span></p><p style="text-align: left;" data-track="26"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">ServletContext域</span></p><pre><code>import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;
import java.util.ArrayList;
import java.util.List;

@WebListener()
public class MyServletContextListener implements ServletContextListener{
    private ServletContext sc;

    @Override
    //Application被初始化的时候创建
    public void contextInitialized(ServletContextEvent sce) {
        //创建一个链表来存储IP
        List<String> ips = new ArrayList<>();
        sc = sce.getServletContext();
        //将创建好的链表对象,放到Application域中
        sc.setAttribute("ips",ips);
    }
}
</code></pre><p style="text-align: left;" data-track="28"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">由于IP只能在Request域中获取,所以遍历判断在Request域中进行。</span></p><pre><code>import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
import java.util.List;

@WebListener()
public class MyRequestListener implements ServletRequestListener{

    private HttpServletRequest sr;
    private String clientIp;
    private ServletContext sc;
    private List<String> ips;
    private HttpSession session;

    @Override
    //请求被初始化 Request
    public void requestInitialized(ServletRequestEvent sre) {
        //从请求域中获取IP
        sr = (HttpServletRequest) sre.getServletRequest();
        clientIp = sr.getRemoteAddr();
        session = sr.getSession();
        session.setAttribute("clientIp",clientIp);

        //测试
        // System.out.println("clientIp = "+ clientIp);
        //获取Application域中的List
        sc = sre.getServletContext();
        ips = (List<String>) sc.getAttribute("ips");
        //遍历ips
        for (String ip :
                ips) {
            if (clientIp.equals(ip))
                return;
        }
        ips.add(clientIp);
        sc.setAttribute("ips",ips);
    }
}</code></pre><p style="text-align: left;" data-track="30"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">因为要统计在线人数,所以要设置退出按钮,点击退出按钮之后,因为要从List域中移除,所以使用Session域监听器来判断session回话的关闭</span></p><pre><code>import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
import java.util.List;

@WebListener()
public class MySessionListener implements HttpSessionListener{

    private ServletContext sc;
    private List<String> ips;
    private HttpSession session;
    private Object clientIp;

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        sc = se.getSession().getServletContext();
        ips = (List<String>) sc.getAttribute("ips");
        session = se.getSession();
        clientIp = session.getAttribute("clientIp");
        //删除ip,如何获取IP,但是不可以从session获取到IP
        //因为Session获取不到Request
        //一个Session包含多个Request
        //一个Request只对应一个Session 所以获取不到,这时只能先从Request域中获取到的ips,放置到Session域
        //然后从Session 域中读取
        ips.remove(clientIp);
        // session一失效就马上将此IP从链表中移除是错误的
        //应该看此IP是否有另外的回话存在,如果有的话不能删除
    }
}
</code></pre><p style="text-align: left;" data-track="32"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">此处代码是页面点击关闭后,激活的退出方法</span></p><pre><code>import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet(name = "LogoutServlet",urlPatterns = "/logoutServlet")
public class LogoutServlet extends HttpServlet {

    private HttpSession session;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //从域中获取一个session,设置为false 如果域中存在一个session,则直接获取,如果不存在,则返回一个空的session
        session = request.getSession(false);
        if (session != null){
            //使session失效
            session.invalidate();
            //失效后,需要进行的操作,List链表中需要减去,用到了Session域监听器
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
</code></pre><p style="text-align: left;" data-track="34"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">在jsp页面进行读取的时候,因为ips是以List链表的形式存在的,所以要想判断当前在线人数,所以必须要判断链表的长度,所以是</span><span style="color: #EF7060; --tt-darkmode-color: #EF7060;">applicationScope.ips.size()</span></p><pre><code><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Titlelt;/title>
  </head>
  <body>
  <center><h1>You are the ${applicationScope.ips.size()} customer to visit. </h1><br>
    <h3>
      安全退出
    </h3>
  </center>
  </body>
</html>
</code></pre><p style="text-align: left;" data-track="36"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">好了?,这时候,程序写完了,如何判断呢?</span></p><p style="text-align: left;" data-track="37"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">此时,我们的程序是部署在本地的Tomcat上的,对于本台电脑,只有一个IP,如何实现多个IP呢?其实啊我们的电脑可以有三个IP,在访问服务器的时候,服务器的IP多写几个,相当于本机的IP多出来几个。是哪三个IP呢?</span></p><p style="text-align: left;" data-track="38"><strong><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">1、默认clientIp : 0:0:0:0:0:0:0:1</span></strong></p><img src="/a2020/img/data-img.jpg" data-src="//img02.bs178.com/bj/uh/148e8461d2fcc68f.jpg" img_width="1080" img_height="608" image_type="1" mime_type="image/png" web_uri="tos-cn-i-qvj2lq49k0/0ffe4dae1c5e451fbc656f2e85d1f1ec"><p class="pgc-img-caption"></p><p style="text-align: left;" data-track="39"><strong><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">2、127.0.0.1</span></strong></p><p style="text-align: left;" data-track="40"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">这时大家可能会问127.0.0.1和localhost有什么区别呢,其实在这里要区分三个概念:</span></p><p style="text-align: left;" data-track="41"><strong><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">localhost、127.0.0.1 和 本机IP之间的区别:</span></strong></p><ul><li data-track="42"><span style="color: #010101; --tt-darkmode-color: #A3A3A3;">localhost等于127.0.0.1,不过localhost是域名,127.0.0.1是IP地址。</span></li><li data-track="43"><span style="color: #010101; --tt-darkmode-color: #A3A3A3;">localhost和127.0.0.1不需要联网,都是本机访问。</span></li><li data-track="44"><span style="color: #010101; --tt-darkmode-color: #A3A3A3;">本机IP需要联网,本机IP是本机或外部访问, 本机 IP 就是本机对外放开访问的IP地址,这个网址就 是与物理网卡绑定的IP地址。</span></li></ul><img src="/a2020/img/data-img.jpg" data-src="//img02.bs178.com/bj/uh/9190f8ae13396a13.jpg" img_width="1080" img_height="429" image_type="1" mime_type="image/png" web_uri="tos-cn-i-qvj2lq49k0/d813ed2a167e4283b0d3529ff4b240d8"><p class="pgc-img-caption"></p><p style="text-align: left;" data-track="45"><strong><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">3、IPv4地址:192.168.1.110</span></strong></p><img src="/a2020/img/data-img.jpg" data-src="//img02.bs178.com/bj/uh/14dde20648b99a2d.jpg" img_width="939" img_height="750" image_type="1" mime_type="image/png" web_uri="tos-cn-i-qvj2lq49k0/80e9f18be23b46f8b883cff86f2d48a1"><p class="pgc-img-caption"></p><p style="text-align: left;" data-track="46"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">这样就很完美的实现了本地三个IP的测试。</span></p><img src="/a2020/img/data-img.jpg" data-src="//img02.bs178.com/bj/uh/c3477e88688ef215.jpg" img_width="1080" img_height="675" image_type="1" mime_type="image/png" web_uri="tos-cn-i-qvj2lq49k0/edb1755fcbe64f90bd41434846aa69c2"><p class="pgc-img-caption"></p><p style="text-align: left;" data-track="47"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">写到这里,似乎已经可以简单的测试当前在线人数,也许仔细的人会发现在Session域被销毁的方法中的注释中发现一些猫腻。大家可以仔细想想,如果客户端用不同的浏览器,相同的IP去访问呢?点击退出后,会不会出现错误情况呢?答案是会的。演示结果如下图</span></p><img src="/a2020/img/data-img.jpg" data-src="//img02.bs178.com/bj/uh/fbd80a87ebe64b6f.jpg" img_width="1080" img_height="675" image_type="1" mime_type="image/png" web_uri="tos-cn-i-qvj2lq49k0/1c866ed02f89480cbf58445a3118c90b"><p class="pgc-img-caption"></p><h1 class="pgc-h-arrow-right" data-track="48">最完美的代码</h1><p style="text-align: left;" data-track="49"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">所以在点击退出登录的按钮之后,不可以直接将IP移除,要判断有没有另外的回话存在,如果有另外的回话存在,此IP是不可以删掉的,问题由此变的复杂了,因为还要统计此IP所发出的会话有多少。</span></p><p style="text-align: left;" data-track="50"><strong><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">整体思路:</span></strong></p><p style="text-align: left;" data-track="51"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">在全局域中,将不是直接将iP存放在List的链表中,而是以一个Map的形式存在,Map的键为String类型,Key为List类型,List中存放的是当前IP所激发的会话对象,这样就可以统计,一个IP触发的sessions有多少个。</span></p><p style="text-align: left;" data-track="52"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">通过调用Map的get方法,将当前IP最为参数,将可以获取到他所激发的会话集合。但是,此集合可能为空,因为有可能当前IP一次也没有访问此页面,所以在List为空的时候好要创建一个ArrayList来存放sessions,然后将变化后的List重新写回到Map,再将变化后的Map写回到全局域中 。这样创建过程基本完成。</span></p><p style="text-align: left;" data-track="53"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">然后考虑销毁过程,IP还需方法放到Session域中,当session被销毁的时候,应该把当前Session从List 中删除,但是Map中此sessions对应的IP可是不能直接删,要判断List中的sessions的个数(Entry对象),个数为1的时候才可以删除,不然就不可以删除。</span></p><p style="text-align: left;" data-track="54"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">所以,要将当前IP通过Request域存放到当前Session域中,</span></p><p style="text-align: left;" data-track="55"><strong><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">然后,要考虑的问题是,每次刷新页面后sessions的个数会增加,这是错误的,原因是什么?</span></strong></p><p style="text-align: left;" data-track="56"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">答案是,因为在存放sessions的时候,创建数组直接进行的添加,这样的话,每次一刷新页面,就会导致sessions的添加,所以在此之前应该判断,sessions中是否有此session,有的话直接跳出。</span></p><p style="text-align: left;" data-track="57"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">这样添加就没问题了</span></p><h1 class="pgc-h-arrow-right" data-track="58">Servlet域中添加Map</h1><p style="text-align: left;" data-track="59"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">在Map中,需要使用键值对的方式,Key为IP,Value为List,那么List中存放什么呢?存放的是此IP发出的所有回话的HttpSession的对象,所以List的泛型是HttpSession。</span></p><p style="text-align: left;" data-track="60"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">请求,在请求中,因为将当前Session 对象存放到List中, List在Map中,Map在全局域中,所以首先得从全局域获取到Map,然后,从Map中获取由当前IP所发出的所有Session的组成的List,判断当前的List是否为NULL,若为NULL,则创建List,否则,将当前SessioncurrentSession放入List中。</span></p><pre><code>import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WebListener()
public class MyRequestListener implements ServletRequestListener{

    private HttpServletRequest sr;
    private String clientIp;
    private ServletContext sc;
    private List<String> ips;
    private HttpSession currentSession;
    private Map<String,List<HttpSession>> map;
    private List<HttpSession> sessions;


    @Override
    //请求被初始化 Request
    public void requestInitialized(ServletRequestEvent sre) {
        //从请求域中获取IP
        sr = (HttpServletRequest) sre.getServletRequest();
        clientIp = sr.getRemoteAddr();
        currentSession  = sr.getSession();
        //将当前Session 对象存放到List中, List在Map中,Map在全局域中,
        sc = sre.getServletContext();
        map = (Map<String, List<HttpSession>>) sc.getAttribute("map");
        //从Map中获取由当前IP所发出的所有Session的组成的List
        sessions = map.get(clientIp);
        //判断当前的List是否为NULL,若为NULL,则创建List,否则,将当前Session放入List
        if (sessions == null){
            sessions = new ArrayList<>();
        }
//        遍历List的session 对象,若有则不添加,若没有则添加
        for (HttpSession session :
                sessions) {
            if (session == currentSession)
                return;
        }
        sessions.add(currentSession);


        //将变化过的List重新写回到Map
        map.put(clientIp,sessions);
        //再将变化的Map写回到全局域中
        sc.setAttribute("map",map);

        //将当前IP放入到当前Session
        currentSession.setAttribute("clientIp",clientIp);
    }

}
</code></pre><h1 class="pgc-h-arrow-right" data-track="62">ServletContext</h1><p style="text-align: left;" data-track="63"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">这里将不使用ips了,所以将其删除</span></p><pre><code>import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WebListener()
public class MyServletContextListener implements ServletContextListener{
    private ServletContext sc;
    @Override
    //Application被初始化的时候创建
    public void contextInitialized(ServletContextEvent sce) {
        //创建一个Map,key为IP,value为该IP上所发出的会话的对象
        Map<String,List<HttpSession>> map = new HashMap<>();
        sc = sce.getServletContext();
        //将map放到全局域中
        sc.setAttribute("map",map);
    }
}
</code></pre><h1 class="pgc-h-arrow-right" data-track="65">Session监听器</h1><p style="text-align: left;" data-track="66"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">接下来剖析Session的删除工作,获取当前Session对象,这里有之前传递过来的IP,在进行删除操作的时候,要注意此处,删除的是List中的sessions,删除之后,还要判断其IP的是否要删除,如果List中没有该元素,则说明当前IP所发出的会话全部关闭,就可以从map中将当前IP对应的Entry对象删除,否则,当前IP所发出的会话任存在,那么使用put方法将变化过的List写回到map。</span></p><pre><code>import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
import java.util.List;
import java.util.Map;

@WebListener()
public class MySessionListener implements HttpSessionListener{

    private ServletContext sc;
    private List<String> ips;
    private HttpSession currentSession;
    private String clientIp;
    private Map<String,List<HttpSession>> map;
    private List<HttpSession> sessions;

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        sc = se.getSession().getServletContext();

        currentSession = se.getSession();
        clientIp = (String) currentSession.getAttribute("clientIp");
        map = (Map<String, List<HttpSession>>) sc.getAttribute("map");
        //从Map中获取List
        sessions = map.get(clientIp);
        //从List中删除当前Session对象
        sessions.remove(currentSession);
        //如果List中没有该元素,则说明当前IP所发出的会话全部关闭,就可以从map中
        //将当前IP对应的Entry对象删除
        //若List中仍有元素,当前IP所发出的会话任存在,那么将变化过的List写回到map
         if (sessions.size() == 0){
             map.remove(clientIp);
         }else {
             map.put(clientIp,sessions);
         }
         sc.setAttribute("map",map);
    }
}
</code></pre><p style="text-align: left;" data-track="68"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">因为处理的退出的页面</span><span style="color: #EF7060; --tt-darkmode-color: #EF7060;">/logoutServlet</span>不需要做任何不同的处理,所以这里将不再重复。</p><p style="text-align: left;" data-track="69"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">因为在jsp用到了JSP标准库,所以到导两个包。</span></p><pre><code><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
  <head>
    <title>$Titlelt;/title>
  </head>
  <body>
  <center><h1>You are the ${applicationScope.map.size()} customer to visit. </h1><br>
    <h3>
      安全退出
    <br></h3>
    <h2>
      <c:forEach items="${map}" var="entry">
        ${entry.key }=${entry.value.size()}<br>
      </c:forEach>
    </h2>
  </center>
  </body>
</html>
</code></pre><img src="/a2020/img/data-img.jpg" data-src="//img02.bs178.com/bj/uh/d57991bfa2264d7f.jpg" img_width="1080" img_height="675" image_type="1" mime_type="image/png" web_uri="tos-cn-i-qvj2lq49k0/3bb4646a5c97491fa4ff674605fa5ef1"><p class="pgc-img-caption"></p><p style="text-align: left;" data-track="71"><span style="color: #000000; --tt-darkmode-color: #A3A3A3;">最后 测试成功,这就是一个完美的统计当前用户的在线人数。</span></p><blockquote class="pgc-blockquote-abstract"><p>来源:https://mp.weixin.qq.com/s/gM-lyh_9FeFKRRAJlPY83g</p></blockquote>
</div>
<div class="readall_box" >
<div class="read_more_mask"></div>
<a class="read_more_btn" target="_self">展开阅读全文</a>
</div>
<p class="info">页面更新:2024-05-09</p>
<p class="tags">
标签:<a href="/tt/3009-0.html" target="_blank">在线</a>   <a href="/tt/23825-0.html" target="_blank">人数</a>   <a href="/tt/79611-0.html" target="_blank">监听器</a>   <a href="/tt/56613-0.html" target="_blank">遍历</a>   <a href="/tt/39722-0.html" target="_blank">回话</a>   <a href="/tt/65389-0.html" target="_blank">初始化</a>   <a href="/tt/7975-0.html" target="_blank">优雅</a>   <a href="/tt/7378-0.html" target="_blank">对象</a>   <a href="/tt/1178-0.html" target="_blank">错误</a>   <a href="/tt/24029-0.html" target="_blank">页面</a>   <a href="/tt/311-0.html" target="_blank">方法</a>   <a href="/tt/3014-0.html" target="_blank">用户</a></p>
<p class="pageLink"></p>
<p class="pagelink1">
<a href="/tuijian/1666328992815944.html">1</a>
<a href="/tuijian/1666328991815943.html"><b>2</b></a>
<a href="/tuijian/1666328989815942.html">3</a>
<a href="/tuijian/1666328987815941.html">4</a>
<a href="/tuijian/1666328986815940.html">5</a>
</p>
<div class="a_b_js2">
<script type="text/javascript" src="/a_b_js/m_2.php"></script>
</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328912815938.html" target="_blank"><img data-src="" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328912815938.html" target="_blank">英媒:实施对华芯片禁令,美国像是恍然发现新的多极世界后惶恐应对</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328912815938.html" target="_blank">来源:环球时报 英国UnHerd网站10月18日文章,原题:美国企图制裁中国但未能得逞 美国最近开始严格限制向中国出口先进半导体。乍一看,美国实施此类出口禁令似乎很奇怪。首先,中国是美国第二大半导体出口市场,几乎占其出口总额</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328910815937.html" target="_blank"><img data-src="//img02.bs178.com/small/bj/uh/b0506e0bb6060249.jpg" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328910815937.html" target="_blank">哪些国债有风险?斯里兰卡为什么会破产?</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328910815937.html" target="_blank">债券又分为国债、金融债、企业债、次级债很多品种。其中,安全性最高的是国债,被称为金边债券。但是,如果我问一个问题,国债为什么安全性最高?不存在违约的风险?许多人可能回答不出来。其实,最关键的原因是:国债的最大买家是各</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328909815936.html" target="_blank"><img data-src="//img02.bs178.com/small/bj/uh/cba6f3396860247b.jpg" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328909815936.html" target="_blank">今日油价|2022年10月20日最新92、95汽油,柴油价格,油价上涨中</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328909815936.html" target="_blank">今天的油价将在下周的10月24日晚调整,目前10个工作日的统计周期,已经进行了8个工作日的统计,当前原油变化率2.47%,预计上调油价180元/吨(0.14元/升-0.16元/升),各位车友相互提醒下,下周油价要上涨了。今日油价(10月20日)请</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328908815935.html" target="_blank"><img data-src="" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328908815935.html" target="_blank">为什么货币没有使用期限?</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328908815935.html" target="_blank"> 生活中大多东西都是有使用期限或使用寿命的,入口的食品、药品有严格的有效期限;日常生活用品少则几年的使用寿命;就算是家具家电汽车房屋等耐用消费品,也就是几十年的使用寿命而已;包括万物之灵的人类,最长也就是百来年的</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328906815934.html" target="_blank"><img data-src="" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328906815934.html" target="_blank">国家发改委与部分大型养殖企业研究做好生猪市场保供稳价工作</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328906815934.html" target="_blank">【国家发改委与部分大型养殖企业研究做好生猪市场保供稳价工作】财联社10月20日电,针对近期生猪价格持续高位运行的情况,国家发展改革委价格司加强与部分大型生猪养殖企业沟通协调,研究共同做好生猪市场保供稳价工作。</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328904815933.html" target="_blank"><img data-src="//img02.bs178.com/small/bj/uh/0ef2026f2cce2578.jpg" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328904815933.html" target="_blank">山东省取暖补贴和养老金迎来新动态,许多人收入要涨,看看有你吗</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328904815933.html" target="_blank">10月下旬到了,山东省取暖补贴和养老金都迎来新变化,许多人收入要涨了,看看其中有你吗?时间走到10月下旬,山东省的各位退休人员要注意了,很多人最近收到了一笔钱1700元,是因为企业退休职工的冬季取暖补贴开始发放了、最新的动</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328902815932.html" target="_blank"><img data-src="//img02.bs178.com/small/bj/uh/c84b0a3b28603e34.jpg" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328902815932.html" target="_blank">适当下调充电服务费 利好了车主却压垮了运营商?</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328902815932.html" target="_blank">7月7日,商务部等17部门发布《关于搞活汽车流通 扩大汽车消费若干措施的通知》《通知》指出,积极支持充电设施建设,加快推进居住社区、停车场、加油站、高速公路服务区、客货运枢纽等充电设施建设,引导充电桩运营企业适当</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328901815931.html" target="_blank"><img data-src="" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328901815931.html" target="_blank">苹果三星供应商悲观预计:智能手机需求今明两年将持续下滑</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328901815931.html" target="_blank">财联社10月20日讯(编辑 刘蕊)苹果、三星等公司的智能手机关键供货商、日本电子元件制造商村田制作所最新预计,全球智能手机销量今年将持续下滑,并且这一趋势将持续到2023年。手机销量未来一年没有回升希望据村田制作所估</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328900815930.html" target="_blank"><img data-src="//img02.bs178.com/small/bj/uh/49e0f9a58b06972e.jpg" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328900815930.html" target="_blank">社保又一“坏消息”,最低15年缴费年限要上调?3类人要麻烦了</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328900815930.html" target="_blank">随着人口结构发生转变,社保也将作出一些调整,比如为了应对养老金缺口问题,延迟退休已经是板上钉钉,同时延长最低缴费年限也是势在必行,不管是从目前的人均寿命还是经济条件,15年的缴费年限已经不合时宜,一般有工作单位的人,社</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328898815929.html" target="_blank"><img data-src="" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328898815929.html" target="_blank">晶圆代工、AR/VR等行业未来走向如何?2023年集邦拓墣科技产业大预测发布</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328898815929.html" target="_blank">智通财经APP获悉,TrendForce集邦咨询公告“2023年集邦拓墣科技产业大预测”。其中,TrendForce集邦咨询预估,2023年全球晶圆代工8吋年均产能增幅约3%、12吋约年增8%,与2022年相较呈现大幅收敛。在全球总体经济能见度低迷,电</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328895815928.html" target="_blank"><img data-src="//img02.bs178.com/small/bj/uh/1962f4f706f186b0.jpg" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328895815928.html" target="_blank">13家百年企业上榜2022中国企业500强</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328895815928.html" target="_blank">2022中国企业500强新闻发布会9月6日,中国企业联合会发布2022中国企业500强榜单。13家百年企业上榜2022中国企业500强榜单,占500强的2.6%,约占中国百年企业数量(截止2022年数据)的10%强;营业收入总计4.1767万亿,占500强总营收</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328894815927.html" target="_blank"><img data-src="//img02.bs178.com/small/bj/uh/c0c64f7efc644fe7.jpg" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328894815927.html" target="_blank">今日油价消息:为何油价一直降不下去,问题出在国外</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328894815927.html" target="_blank">今天是2022年10月20日星期四,油价市场在逐步收缩油价上涨幅度,截止今日第8个工作日,油价从原来的300多元/吨缩小到180元/吨,让油价上涨的速度变慢了许多,虽然下降的幅度不大,但如果能一直保持下去的话,说不定还能回到“七元</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328892815926.html" target="_blank"><img data-src="//img02.bs178.com/small/bj/uh/61a7745a69a409d6.jpg" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328892815926.html" target="_blank">成交量不会骗人,读懂成交量,就等于读懂整个市场</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328892815926.html" target="_blank">初入股市的股民要调整好自己的心态,保持自信的状态,打破“不可能做到”的壁垒。人的潜力是无穷的,没有人做不到,只有你想不想做到;如果你自己给自己打上一个“我做不到”的标签,那么你必然无法达到这个目的。有时候多回想下</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328891815925.html" target="_blank"><img data-src="" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328891815925.html" target="_blank">10.20一哥今日思路:情绪分歧加剧,开始高低切~!今日思路详解</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328891815925.html" target="_blank">No.1【今日思路】前言:今日思路仅作为一哥自己的观点思路记录,不作为投资建议,交流学习为主,投资有风险,入市需谨慎!一哥备用号,还没关注的家人们都关注起来,以防失联。【今日思路】目前市场的高标连板梯队核心是:空间8板:【国</a>
			</div>
		</div>
	</div>
	<div class="box">
		<div class="tpic">
		<a href="/tuijian/1666328889815924.html" target="_blank"><img data-src="//img02.bs178.com/small/bj/uh/abbe2b74d3e35110.jpg" onerror="this.src='/a2020/img/nopic.jpg';this.onerror=null"></a>
		</div>
		<div class="tit">
			<div class="title">
			<h2><a href="/tuijian/1666328889815924.html" target="_blank">这四大县级市晋级“大城市”,GDP领先上市公司闪耀,有你的故乡吗?</a></h2>
			</div>
			<div class="jianjie">
			<a href="/tuijian/1666328889815924.html" target="_blank">江苏昆山、浙江义乌、浙江慈溪和福建晋江4个县级市因为晋级人口大城市而备受关注。其实这四个地方在经济总量上看在全国也排名靠前,且均拥有数量众多的上市公司,其中2021年昆山GDP超4700亿元。接下来财华社就带大家来领</a>
			</div>
		</div>
	</div>
<div class="list_more" id="loading">上滑加载更多 ↓</div>
<div class="list_more" id="nomoreresults" style="display:none">所有内容加载完毕</div>
</div>

<div class="right">
	<div class="rboxs">
	<div class="rtuijian">推荐阅读:</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666327195815795.html">小米12S Ultra用了三个月,体验究竟如何?小米用户还是冤</a></h3>
			</div>
		</div>
	</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666325590815722.html">《风暴奇侠》又名《循环:前线》卡顿、崩溃、报错等问题</a></h3>
			</div>
		</div>
	</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666323558815448.html">中国联通 5G 套餐用户累计突破 2 亿户</a></h3>
			</div>
		</div>
	</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666321877815338.html">补水不能只靠面膜 这几个方法也不能少</a></h3>
			</div>
		</div>
	</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666320192815211.html">怎么参与第一后裔的Beta测试?B测测试资格获取方法图文</a></h3>
			</div>
		</div>
	</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666320028815134.html">NBA直播:尼克斯vs灰熊直播CCTV5在线(中文)高清观看及录</a></h3>
			</div>
		</div>
	</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666318391815027.html">10.20的报恩羊来啦 因为每个人的理解不同,今天放两个方</a></h3>
			</div>
		</div>
	</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666318274814980.html">戴安娜的漂亮继母:一生三嫁伯爵,优雅体面地活到87岁,患癌</a></h3>
			</div>
		</div>
	</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666318267814976.html">刘涛在街头被拍,刚好做了错误示范,圆润身材穿宽松短上衣</a></h3>
			</div>
		</div>
	</div>

	<div class="rbox">
		<div class="rtit">
			<div class="rtitle">
			<h3><a href="/tuijian/1666316702814792.html">「职场必备」优雅与商务兼具</a></h3>
			</div>
		</div>
	</div>

	</div>
	
	<div class="rboxs">
	<div class="rtuijian">友情链接:</div>
	<div class="rbox1">
		<ul>
<li><a href="https://www.bs178.com/" target="_blank">品学网</a></li>
<li><a href="https://www.71396.com/" target="_blank">奇文网</a></li>
<li><a href="https://www.bs178.com/rizhi/" target="_blank">日志</a></li>
<li><a href="https://www.bs178.com/zuowen/" target="_blank">作文</a></li>
<li><a href="https://www.bs178.com/lizhi/" target="_blank">励志</a></li>
<li><a href="https://www.bs178.com/meiwen/" target="_blank">美文</a></li>
<li><a href="https://www.bs178.com/fanwen/" target="_blank">范文</a></li>
<li><a href="https://www.bs178.com/jiaoan/" target="_blank">教案</a></li>
<li><a href="https://www.bs178.com/lunwen/" target="_blank">论文</a></li>
		</ul>
	</div>
	</div>

	<div class="rboxs">
	<div class="rtuijian">更多:</div>
	<div class="rbox1">
		<p>本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  </p>
		<p>© CopyRight 2008-2024 All Rights Reserved. Powered By <a href="https://www.bs178.com/" target="_blank">bs178.com</a>  <a href="https://beian.miit.gov.cn/" target="_blank" rel=”external nofollow">闽ICP备11008920号-3</a><br><a target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=35020302034844"  rel=”external nofollow">闽公网安备35020302034844号</a></p>
	</div>
	</div>
	
</div>

<script type="text/javascript">
var curpage = 2;
var totalpage = 100;
var geturl = '/apib/a2020.php?classid=8&from=3&id=815939&page=';
</script>
<a href="#" class="cd-top">Top</a>
<script type="text/javascript" src="/b2020/js/js.js"></script>
<script type="text/javascript" src="/apib/onclick.php?on=onclick&classid=8&id=815939"></script>
</body>
</html>