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")));
});
相關文章
相關標籤/搜索