webSocket入门以及解决webSocket的Session为null问题

webSocket入门以及解决webSocket的Session为null问题

我想每个小伙伴第一次使用webSocket的时候都会遇到各种坑,我也一样,查阅了各种资料,总结如下:
第一步:pom文件引入webSocket依赖;

1
2
3
4
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

第二部:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * @author: create by kfc
 * @version: v1.0
 * @description: 开启webSocket支持
 * @date:2020/6/9
 */
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

第三部:
编写业务代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
@ServerEndpoint(value ="/webSocket", configurator = GetHttpSessionConfigurator.class)
@Component
public class WebSocket {

    private CommonRepository commonRepository;

    private static  Set<WebSocket> connections = new CopyOnWriteArraySet<>();
   
    private static Session session;
    private static Logger logger = LoggerFactory.getLogger(WebSocket.class);
    //此处是解决无法注入的关键
    private static ApplicationContext applicationContext;

    public static void setApplicationContext(ApplicationContext applicationContext) {
        WebSocket.applicationContext = applicationContext;
    }

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        //此处为了确保只保留一个连接
        connections = new CopyOnWriteArraySet<>();
       
        //将这次会话信息记录
        if(session==null){
            session=this.session;
        }else {
            this.session=session;
        }

        //此处是解决无法注入的关键
        commonRepository = applicationContext.getBean(CommonRepository.class);
        //注入service
        WebSocketService webSocketService = applicationContext.getBean(WebSocketService.class);
        WebSocket webSocketAlarm;
        this.session = session;
        connections.add(this);
        Studennt studennt = webSocketService.getStudennt();
        sendMessage(studennt);

    }

 
    private static void sendMessage(Studennt studennt) {
        for (WebSocket client : connections) {
            try {
                synchronized (client) {
                    client.session.getBasicRemote().sendText(JSON.toJSONString(studennt));
                }
            } catch (IOException e) {
                logger.error("消息发送失败");
                connections.remove(client);
                try {
                    client.session.close();
                } catch (IOException e1) {
                    logger.error("session关闭异常");
                }

            }
        }
    }



    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        try {
            session.close();
        }catch (Exception e){
        }
    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        String logFlag = getClass().getSimpleName() + ".sendErrorMessage";

        try {
            error.printStackTrace();
        } catch (Exception e) {

        }
    }


}

第四部:前端代码可以参考:http://www.websocket-test.com/
在这里插入图片描述
第五部分:如果断开重新连接或者页面刷新导致Session为null时可以配置如下注解,上面我已经配置了

1
configurator = GetHttpSessionConfigurator.class

配置了此注解之后就必须保证session中是有值的,不然就无法建立websocket链接且报空指针错误
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 *
 * @author: create by kfc
 * @version: v1.0
 * @description: 此处解决WebSocket调用的时候Session为null的问题
 * @date:2020/6/9
 */
public class GetHttpSessionConfigurator extends
        ServerEndpointConfig.Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig config,
                                HandshakeRequest request, HandshakeResponse response) {
        // TODO Auto-generated method stub
        HttpSession httpSession = (HttpSession) request.getHttpSession();
        // ActionContext.getContext().getSession()
        config.getUserProperties().put(HttpSession.class.getName(), httpSession);
    }


}

以下为参考的网址
[1]: https://blog.csdn.net/z719725611/article/details/52400404
[2]:http://www.websocket-test.com/
[3]:https://blog.csdn.net/qq_16137795/article/details/100155412