Build a Simple Group Chat with Spring Boot WebSocket – Step‑by‑Step Guide
This tutorial walks you through creating a real‑time group chat using Spring Boot and Java WebSocket, covering Maven dependencies, core server classes, annotation explanations, configuration, and testing with an online client, all backed by complete source code on GitHub.
Introduction
This article demonstrates how to build a simple real‑time group chat using Spring Boot and the Java WebSocket API.
Dependencies
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.2.5.RELEASE</version>
</dependency></code>Project Structure
Core Classes
WebSocketApplication
Bootstrap class with @SpringBootApplication and a main method.
<code>@SpringBootApplication
public class WebSocketApplication {
public static void main(String[] args) {
SpringApplication.run(WebSocketApplication.class, args);
}
}</code>WebSocketServer
Annotated with @Component and @ServerEndpoint, it manages client sessions, handles connection events (@OnOpen, @OnMessage, @OnClose) and broadcasts messages to all other participants.
<code>@Component
@ServerEndpoint(value = "/chat/{username}", configurator = SpringBasedConfigurator.class)
public class WebSocketServer {
private final Map<Session, String> userSessionMap = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("username") String username) {
userSessionMap.put(session, username);
multicastMessage(session, "欢迎" + username + "加入群聊!");
}
@OnMessage
public void onMessage(Session session, String message) {
String username = userSessionMap.get(session);
multicastMessage(session, username + ": " + message);
}
@OnClose
public void onClose(Session session) {
String username = userSessionMap.remove(session);
multicastMessage(session, username + "退出群聊。");
}
private void multicastMessage(Session session, String message) {
for (Session userSession : userSessionMap.keySet()) {
if (userSession == session) {
continue;
}
try {
userSession.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}</code>Explanation of annotations: @ServerEndpoint defines the endpoint, @OnOpen triggers when a client connects, @PathParam extracts the username from the URL, @OnMessage processes incoming text, @OnClose runs when a client disconnects, and Session represents the WebSocket session.
SpringBasedConfigurator
Extends ServerEndpointConfig.Configurator to obtain endpoint instances from the Spring container, enabling dependency injection inside WebSocket beans.
<code>@Component
public class SpringBasedConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringBasedConfigurator.applicationContext = applicationContext;
}
@Override
public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
return applicationContext.getBean(clazz);
}
}</code>WebSocketConfiguration
Registers all @ServerEndpoint beans by exposing a ServerEndpointExporter bean.
<code>@Configuration
public class WebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}</code>Testing the Chat
Use an online WebSocket client (e.g., https://www.idcd.com/tool/socket) to connect to ws://localhost:8080/chat/{username} . Open two browser windows, enter different usernames, and send messages; each client receives messages from the other, confirming the group chat works.
Conclusion
The complete source code is available on GitHub at https://github.com/sanyou3/sanyou-parent.git for further exploration.
Sanyou's Java Diary
Passionate about technology, though not great at solving problems; eager to share, never tire of learning!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.