Spring Boot WebSocket

A Example Of Spring Boot WebSocket

Posted by MichaelChen on 2020-11-27
Estimated Reading Time 4 Minutes
Words 952 In Total
Viewed Times

A Example Of Spring Boot WebSocket

Maven

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

Tools Class

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
91
92
93
94
95
96
97
98
99
100
101
102
103
public class WebSocket {

//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;

//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<WebSocket>();

//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;

/**
* 连接建立成功调用的方法
* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
* @throws IOException
*/
@OnOpen
public void onOpen(Session session) throws IOException{
this.session = session;
webSocketSet.add(this);//加入set中
addOnlineCount(); //在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
this.sendMessage("连接成功!!!");
}

/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(){
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) {
Map<String, String> map = session.getPathParameters();
System.out.println("来自客户端用户"+map.get("userId")+"的消息:" + message);
//群发消息
for(WebSocket item: webSocketSet){
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
/**
* 发生错误时调用
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
System.out.println("发生错误");
error.printStackTrace();
}

/**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
}

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

public static synchronized void addOnlineCount() {
WebSocket.onlineCount++;
}

public static synchronized void subOnlineCount() {
WebSocket.onlineCount--;
}

public static CopyOnWriteArraySet<WebSocket> getWebSocketSet() {
return webSocketSet;
}

public static void setWebSocketSet(
CopyOnWriteArraySet<WebSocket> webSocketSet) {
WebSocket.webSocketSet = webSocketSet;
}

public Session getSession() {
return session;
}

public void setSession(Session session) {
this.session = session;
}
}

Annotation

注册服务能够在启动类运行时同时启动,@Component 使得类可以自动注入

1
2
@Component
@ServerEndpoint("/websocket/w")

Transfer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void runMethod(String text) {

//获取WebSocketServer对象的映射。
CopyOnWriteArraySet<WebSocket> webSocketSet = WebSocket.getWebSocketSet();
if (webSocketSet.size() != 0){
for (WebSocket item : webSocketSet) {
try {
//向客户端推送消息
item.getSession().getBasicRemote().sendText(text);
}catch (IOException e){
e.printStackTrace();
}
}
}else {
System.out.println("WebSocket未连接");
}
}

Web

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
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>My WebSocket</title>
</head>

<body>
<input id="text" type="text" />
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div>
</body>

<script type="text/javascript">
var websocket = null;

//判断当前浏览器是否支持WebSocket, 主要此处要更换为自己的地址
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/websocket/w");
} else {
alert('Not support websocket')
}

//连接发生错误的回调方法
websocket.onerror = function() {
setMessageInnerHTML("error");

};

//连接成功建立的回调方法
websocket.onopen = function(event) {
//setMessageInnerHTML("open");
}

//接收到消息的回调方法
websocket.onmessage = function(event) {
setMessageInnerHTML(event.data);
}

//连接关闭的回调方法
websocket.onclose = function() {
setMessageInnerHTML("close");
}

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
websocket.close();
}

//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}

//关闭连接
function closeWebSocket() {
websocket.close();
}

//发送消息
function send() {
var message = document.getElementById('text').value;
websocket.send(message);
}
</script>
</html>

If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !