WebSocket 使用,同時獲取HttpSession,並注入springBean


1. 添加jar包

<dependency>
    <groupId>javax.websocket</groupId>
    <artifactId>javax.websocket-api</artifactId>
    <version>1.1</version>
     <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

2. 配置類

@EnableWebSocket
@Configuration
public class WebSocketConfig {
//    @Bean
//    public ServerEndpointExporter serverEndpointExporter() {  
//        return new ServerEndpointExporter();  
//    }  
}

3 .  從websocket中獲取用戶session

public class HttpSessionConfigurator extends Configurator{

    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        HttpSession httpSession = (HttpSession) request.getHttpSession();
        sec.getUserProperties().put(HttpSession.class.getName(), httpSession);
    }

}

4 . 設置監聽

@WebListener
@Component
public class RequestListener implements ServletRequestListener{

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        ServletRequestListener.super.requestDestroyed(sre);
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        //將所有request請求都攜帶上httpSession
        ((HttpServletRequest) sre.getServletRequest()).getSession();
    }

    public RequestListener() {
    }
}

5. 獲取spring容器工具類

@Component
@Lazy(false)
public class ApplicationContextRegister implements ApplicationContextAware {
    private static ApplicationContext APPLICATION_CONTEXT;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        APPLICATION_CONTEXT = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return APPLICATION_CONTEXT;
    }

}

6. webSocket服務類

@Component
@ServerEndpoint(value = "/onlineUser", configurator = HttpSessionConfigurator.class)
public class WebSocketServer {
    
    //靜態變量,用來記錄當前在線連接數。應該把它設計成線程安全的。
    private static int onlineCount = 0;
    //concurrent包的線程安全Set,用來存放每個客戶端對應的MyWebSocket對象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

    //與某個客戶端的連接會話,需要通過它來給客戶端發送數據
    private Session session;
    //用來存放在線用戶
    //private static CopyOnWriteArraySet<Object> user = new CopyOnWriteArraySet<Object>();
    /**
     * 用戶標識
     */
    private String userId;
    /**
     *     連接建立成功調用的方法
     * */
    @OnOpen
    public void onOpen(Session session,EndpointConfig config) {
        UserLoginDao userLoginDao =  (UserLoginDao) ApplicationContextRegister.getApplicationContext().getBean(UserLoginDao.class);  
        HttpSession httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName());       
        this.session = session;       
        webSocketSet.add(this);     //加入set中
        this.userId = ((UserPo)httpSession.getAttribute("user")).getUserId();
       
        addOnlineCount();   //在線數加1
        userLoginDao.online(this.userId, 1);
        //user.add(httpSession.getAttribute("user"));
        //httpSession.setAttribute("websocket", this);
        

    }

    /**
     *     連接關閉調用的方法
     */
    @OnClose
    public void onClose() {  
        UserLoginDao userLoginDao =  (UserLoginDao) ApplicationContextRegister.getApplicationContext().getBean(UserLoginDao.class);
        HttpSession httpSession= (HttpSession) this.session.getUserProperties().get(HttpSession.class.getName());
        
        userLoginDao.online(this.userId, 0);
        //user.remove(httpSession.getAttribute("user"));        
        webSocketSet.remove(this);  //從set中刪除
        subOnlineCount();           //在線數減1
        
    }

    /**
     * 收到客戶端消息后調用的方法
     *
     * @param message 客戶端發送過來的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {

    }

    /**
     * 
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }
    /**
     * 實現服務器主動推送
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 群發自定義消息
     * */
    public static void sendInfo(String message) throws IOException {
        
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    private static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    private static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }

//    public static CopyOnWriteArraySet<Object> getUser() {
//        return user;
//    }
    
    public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() {
        return webSocketSet;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM