This article show you a simple way to implement a websocket demo via springboot.

Step 1: Dependency import

Add spring-boot-starter-websocket dependency in pom.xml

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

Step 2: Implement the websocket controller

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
@Component
@ServerEndpoint(value = "/ws")
public class WebSocketController {
static Map<String,Session> activeMap = new ConcurrentHashMap<>();

static Logger log = Logger.getLogger("WebSocketController");
/**
* when websocket connected.
* @param session
*/
@OnOpen
public void onOpen(Session session) {
Map<String, List<String>> map = session.getRequestParameterMap();
List<String> list = map.get("username");
if(list==null list.size()==0){
sendMessage(session,"no username! authentication failed.");
close(session);
return;
}
String username = list.get(0);
String message = "[" + username + "] join in !";
session.getUserProperties().put("username",username);
addSession(session);
sendMessageForAll(message);
}

/**
* @param session
*/
@OnClose
public void onClose(Session session) {
log.info("onClose, " + session.getUserProperties().get("username"));
String message = "Close...";
close(session);
}

/**
* @param session
*/
@OnMessage
public void onMessage(Session session, String message) {
log.info("onMessage, " + message);
String username = (String)session.getUserProperties().get("username");
String msg = username + " said: " + message;
sendMessageForAll(msg);
}

/**
* @param session
* @param throwable
*/
@OnError
public void onError(Session session, Throwable throwable) {
close(session);
throwable.printStackTrace();
}

public void addSession(Session session) {
activeMap.put(session.getId(),session);
}

public void sendMessageForAll(String message) {
activeMap.forEach((sessionId, session) -> sendMessage(session, message));
}

private void sendMessage(Session session, String message) {
if(session==null){
return;
}
try {
RemoteEndpoint.Async async = session.getAsyncRemote();
async.sendText(message);
}catch (Exception e){
System.out.println(e.getMessage());
}
}

private void close(Session session) {
try {
activeMap.remove(session.getId());
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Step 3: add application class to make it runnable

1
2
3
4
5
6
7
8
9
10
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

Step 4: implement the html5 websocket client

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HTML5 WebSocket Demo</title>
<script type="text/javascript">
var webSocket;
function connect() {
document.getElementById('messages').innerHTML ='';
url = document.getElementById('url').value
webSocket = new WebSocket(url);
webSocket.onerror = function(event) {
alert(event.data);
};
webSocket.onopen = function(event) {
document.getElementById('messages').innerHTML = 'Connected';
};
webSocket.onmessage = function(event) {
document.getElementById('messages').innerHTML += '<br />Receive:'+ event.data;
};

}
function send() {
var msg = document.getElementById('msg').value;
document.getElementById('messages').innerHTML += '<br />Send:'+ msg;
webSocket.send(msg);
}
console.log('yyyy')
</script>
<style>
button{
width: 100px;
height: 30px;
}
input{
width: 300px;
height:20px;
}
div{
margin-top: 10px;
}
</style>
</head>
<body>
<div>
<input id="url" value="ws://localhost:8080/ws?username=junfeng" />
<button onclick="connect()"> Connect </button>
</div>
<div>
<input id="msg" />
<button onclick="send()"> Send </button>
</div>
<div id="messages"></div>
</body>
</html>

Tips

  • you can get the demo code in github. https://github.com/junfengliang/springboot-websocket-demo
  • @Autowired is not supported in websocket for @ServerEndpoint. If you use @Autowired in WebSocketController, NPE will raise. If you need to use beans in spring, you need to get them via application context.