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;
    }
}
原文地址:https://www.cnblogs.com/wdp1990/p/11058245.html