websocket实现监测用户访问网页时长

1.下载好websocket的jar包,下载地址,项目中使用的是1.3.4版本;javascript

2.建立WebSocket类,继承WebSocketServer,实现onClose,onMessage,onError,onStart方法java

public class WebSocket extends WebSocketServer {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocket.class);
    //要检测的页面名称
    private static final List<String> MENU_LIST = new ArrayList<String>();
    //要检测的页面对应id
    private static final List<String> MENU_ID_LIST = new ArrayList<String>();

    public WebSocket(InetSocketAddress address) {
        super(address);
    }

    public WebSocket(int port) throws UnknownHostException {
        super(new InetSocketAddress(port));
    }

    /**
     * 触发链接事件
     */
    @Override
    public void onOpen(org.java_websocket.WebSocket conn, ClientHandshake handshake) {

    }

    /**
     * 触发关闭事件
     */
    @SuppressWarnings("static-access")
    @Override
    public void onClose(org.java_websocket.WebSocket conn, int message, String reason, boolean remote) {
        //从链接池中获取链接传输过来的信息
        VisitLengthVO visitLengthVO = WebSocketPool.getInstance().getVisitLength(conn);
        //判断是否属于须要监测的页面
        if (visitLengthVO != null && MENU_LIST.contains(visitLengthVO.getMenuName())
                && MENU_ID_LIST.contains(visitLengthVO.getMenuId())) {
            VisitLengthVO obj = new VisitLengthVO();
            try {
                //转换实体,计算时长,将数据插入相关表中
                BeanUtilEx.copyProperties(obj, visitLengthVO);
                Long startTime = visitLengthVO.getStartTime();
                double timeLength = (System.currentTimeMillis() - startTime) / 1000.0;
                obj.setTimeLength(timeLength);
                VisitLengthFacade visitLengthFacade = (VisitLengthFacade) AppContext
                        .getBean("visitLengthFacade");
                visitLengthFacade.insertUserVisit(obj);
                 //从链接池移除
                 WebSocketPool.getInstance().removeUser(conn);
            } catch (Exception e) {
                LOGGER.error("webscoket关闭时实体转换异常", e.toString());
            }

        }
    }

    /**
     * 接收到消息触发事件
     */
    @SuppressWarnings("static-access")
    @Override
    public void onMessage(org.java_websocket.WebSocket conn, String message) {
        message = message.toString();
        JSONObject objparams = JSONObject.fromObject(message);
        if (objparams != null) {
            VisitLengthVO vo = new VisitLengthVO();
            try {
                //接收消息,并将消息存入到链接池中
                BeanUtilEx.copyProperties(vo, objparams);
                vo.setStartTime(System.currentTimeMillis());
                WebSocketPool.getInstance().addVisitLength(vo, conn);
            } catch (Exception e) {
                LOGGER.error("webscoket接收消息时实体转换异常", e.toString());
            } 
        }
    }

    /**
     * 触发异常事件
     */
    @Override
    public void onError(org.java_websocket.WebSocket conn, Exception message) {
        LOGGER.error("websocket关闭异常", message.toString());
    }

    @Override
    public void onStart() {
        //初始化要检测的页面和页面对应的id
        MenuFacade menuFacade = (MenuFacade) AppContext.getBean("menuFacade");
        List<MenuVO> menuList = menuFacade.queryMenuList(new MenuVO());
        for (MenuVO vo : menuList) {
            MENU_LIST.add(vo.getMenuName());
            MENU_ID_LIST.add(vo.getMenuId());
        }
    }
}
/*** websocket链接池 */
public final class WebSocketPool {

    /*** 构造器私有化 */
    private WebSocketPool() {
    }

    private static class WebSocketPoolHolder {
        private static WebSocketPool INSTANCE = new WebSocketPool();
    }

    public static WebSocketPool getInstance() {
        return WebSocketPoolHolder.INSTANCE;
    }

    /*** 用户访问时长 */
    private static final Map<WebSocket, VisitLengthVO> VISIT_LENGTH_MAP = new HashMap<WebSocket, VisitLengthVO>();

    /**
     * 获取用户访问时长信息
     * 
     * @param conn 链接对应的对象
     * @return 用户访问时长信息
     */
    public static VisitLengthVO getVisitLength(WebSocket conn) {
        return VISIT_LENGTH_MAP.get(conn);
    }

    /**
     * 添加用户访问信息
     * 
     * @param vo 用户访问信息
     * @param conn 连接对象
     */
    public static void addVisitLength(VisitLengthVO vo, WebSocket conn) {
        VISIT_LENGTH_MAP.put(conn, vo);
    }

    /**
     * 移除连接
     * 
     * @param conn 移除连接
     */
    public static void removeUser(WebSocket conn) {
        if (VISIT_LENGTH_MAP.containsKey(conn)) {
            VISIT_LENGTH_MAP.remove(conn);
        }
    }
}

实体类:web

public class VisitLengthVO {
    /** * 主键ID */
    @Column(name = "SEQ_ID", length = 32, precision = 0)
    private String seqId;

    /** * 菜单ID */
    @Column(name = "MENU_ID", length = 32, precision = 0)
    private String menuId;

    /** * 菜单名称 */
    @Column(name = "MENU_NAME", length = 50, precision = 0)
    private String menuName;

    /** * 访问者 */
    @Column(name = "EMPLOYEE_NAME", length = 50, precision = 0)
    private String employeeName;

    /** * 访问者帐号 */
    @Column(name = "EMPLOYEE_ACCOUNT", length = 100, precision = 0)
    private String employeeAccount;

    /** * 访问者类型,0非重点用户,1重点用户 */
    @Column(name = "EMPLOYEE_TYPE", length = 32, precision = 0)
    private String employeeType;

    /** * 用户所属区域 */
    @Column(name = "ORG_CODE", length = 32, precision = 0)
    private String orgCode;

    /** * 访问时长 */
    @Column(name = "TIME_LENGTH", length = 10, precision = 2)
    private Double timeLength;

    /** * 访问时间 */
    @Column(name = "VISIT_DATE", length = 7, precision = 0)
    private Date visitDate;

    /** * 统计年月 */
    @Column(name = "TIME_ID", length = 32, precision = 0)
    private String timeId;

    /** * 访问时长 */
    @Column(name = "IMPORTANT_TIME_LENGTH", length = 10, precision = 2)
    private Double importantTimeLength;

    /** * 同比 */
    @Column(name = "PRECENT", precision = 2)
    private Double precent;
    
    /** * 开始访问时间 */
    private long  startTime;
    
    

    /**
     * 主键ID
     * 
     * @return 主键ID
     */
    public String getSeqId() {
        return seqId;
    }

    /**
     * 主键ID
     * 
     * @param seqId 主键ID
     */
    public void setSeqId(String seqId) {
        this.seqId = seqId == null ? null : seqId.trim();
    }

    /**
     * 菜单ID
     * 
     * @return 菜单ID
     */
    public String getMenuId() {
        return menuId;
    }

    /**
     * 菜单ID
     * 
     * @param menuId 菜单ID
     */
    public void setMenuId(String menuId) {
        this.menuId = menuId == null ? null : menuId.trim();
    }

    /**
     * 菜单名称
     * 
     * @return 菜单名称
     */
    public String getMenuName() {
        return menuName;
    }

    /**
     * 菜单名称
     * 
     * @param menuName 菜单名称
     */
    public void setMenuName(String menuName) {
        this.menuName = menuName == null ? null : menuName.trim();
    }

    /**
     * 访问者
     * 
     * @return 访问者
     */
    public String getEmployeeName() {
        return employeeName;
    }

    /**
     * 访问者
     * 
     * @param employeeName 访问者
     */
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName == null ? null : employeeName.trim();
    }

    /**
     * 访问者帐号
     * 
     * @return 访问者帐号
     */
    public String getEmployeeAccount() {
        return employeeAccount;
    }

    /**
     * 访问者帐号
     * 
     * @param employeeAccount 访问者帐号
     */
    public void setEmployeeAccount(String employeeAccount) {
        this.employeeAccount = employeeAccount == null ? null : employeeAccount.trim();
    }

    /**
     * 访问者类型,0非重点用户,1重点用户
     * 
     * @return 访问者类型,0非重点用户,1重点用户
     */
    public String getEmployeeType() {
        return employeeType;
    }

    /**
     * 访问者类型,0非重点用户,1重点用户
     * 
     * @param employeeType 访问者类型,0非重点用户,1重点用户
     */
    public void setEmployeeType(String employeeType) {
        this.employeeType = employeeType == null ? null : employeeType.trim();
    }

    /**
     * 用户所属区域
     * 
     * @return 用户所属区域
     */
    public String getOrgCode() {
        return orgCode;
    }

    /**
     * 用户所属区域
     * 
     * @param orgCode 用户所属区域
     */
    public void setOrgCode(String orgCode) {
        this.orgCode = orgCode == null ? null : orgCode.trim();
    }

    /**
     * 访问时长
     * 
     * @return 访问时长
     */
    public Double getTimeLength() {
        return timeLength;
    }

    /**
     * 访问时长
     * 
     * @param timeLength 访问时长
     */
    public void setTimeLength(Double timeLength) {
        this.timeLength = timeLength;
    }

    public Date getVisitDate() {
        return visitDate;
    }

    public void setVisitDate(Date visitDate) {
        this.visitDate = visitDate;
    }

    public String getTimeId() {
        return timeId;
    }

    public void setTimeId(String timeId) {
        this.timeId = timeId;
    }

    public Double getImportantTimeLength() {
        return importantTimeLength;
    }

    public void setImportantTimeLength(Double importantTimeLength) {
        this.importantTimeLength = importantTimeLength;
    }

    public Double getPrecent() {
        return precent;
    }

    public void setPrecent(Double precent) {
        this.precent = precent;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }
}

3.建立一个WebSocketFilter,用来启动拦截请求,并启动websocket;安全

public class WebSocketFilter implements Filter {

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        this.startWebsocketOnline();
    }

    public void startWebsocketOnline() {
        System.out.println("开始启动websocket");
        WebSocketImpl.DEBUG = false;
        int port =8888; //端口号
        WebSocket s = null;
        try {
            s = new WebSocket(port);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        s.start();
        System.out.println("启动websocket成功!");
    }

}

4.在web.xml中配置拦截器服务器

<!-- websocket过滤器 -->
	<filter>
	    <filter-name>websocketFilter</filter-name>
	    <filter-class>com.filiter.WebSocketFilter</filter-class>
	</filter>
	 <filter-mapping>
		<filter-name>websocketFilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
		<dispatcher>REQUEST</dispatcher>
	</filter-mapping>
	<filter-mapping>
		<filter-name>websocketFilter</filter-name>
		<url-pattern>*.ac</url-pattern>
		<dispatcher>REQUEST</dispatcher>
	</filter-mapping>

5.实现websocket.js,主要实现两个方法websocket

/**
 * 申请一个WebSocket对象,参数是须要链接的服务器端的地址, 同http协议使用http://开头同样,
 * WebSocket协议的URL使用ws://开头, 另外安全的WebSocket协议使用wss://开头
 */
function openWs(message){
	var ws = new WebSocket("ws://127.0.0.1:8888");
	//当websocket建立成功时,即会触发onopen事件
	ws.onopen = function(){
		ws.send(message);
	};
	//当客户端收到服务端发来的消息时,会触发onmessage事件,参数evt.data中包含server传输过来的数据
	ws.onmessage = function(evt){
		
	};
	//当客户端收到服务端发送的关闭链接的请求时,触发onclose事件
	ws.onclose = function(evt){
	};
	//若是出现链接,处理,接收,发送数据失败的时候就会触发onerror事件
	ws.onerror = function(evt){
	};
}

/**
 * 根据指标序号封装不一样的客户端信息
 * @param index 指标序号
 */
function getWsMessage(index){
	var message = {};
	message = {
				employeeAccount :"",
				employeeName : "",
				orgCode : "",
				menuId : "",
				menuName : ""
	}
	return message;
}

6.在jsp的onload里面调用openWs方法java-web

$(function(){
	//开启websocket
	openWs(JSON.stringify(getWsMessage("9")));
});
相关文章
相关标签/搜索