spring-boot-starter-websocket 搭建一个websoket服务 实现多个房间群聊
时间: 2023-11-28 16:04:21 浏览: 36
1. 添加依赖
首先,需要在 pom.xml 文件中添加 spring-boot-starter-websocket 依赖:
```
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
```
2. 创建 WebSocket 配置类
创建一个 WebSocketConfig 类,用于配置 WebSocket 相关的组件:
```
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketHandler(), "/socket").setAllowedOrigins("*");
}
}
```
其中,SocketHandler 是自定义的一个 WebSocket 处理器类。
3. 创建 WebSocket 处理器
创建一个 SocketHandler 类,用于处理 WebSocket 的连接、断开、消息发送等操作:
```
@Component
public class SocketHandler extends TextWebSocketHandler {
// 存储所有在线的 WebSocket 连接
private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.put(session.getId(), session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessions.remove(session.getId());
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// 处理消息
}
}
```
在 afterConnectionEstablished 方法中,将新建立的 WebSocket 连接添加到 sessions 中;在 afterConnectionClosed 方法中,将关闭的 WebSocket 连接从 sessions 中移除;在 handleTextMessage 方法中,处理收到的文本消息。
4. 实现多个房间群聊
为了实现多个房间的群聊,可以在 SocketHandler 中添加一个 Map,用于存储每个房间中的在线用户:
```
@Component
public class SocketHandler extends TextWebSocketHandler {
// 存储所有在线的 WebSocket 连接
private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
// 存储每个房间中的在线用户
private static final Map<String, Set<String>> rooms = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.put(session.getId(), session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessions.remove(session.getId());
for (Map.Entry<String, Set<String>> entry : rooms.entrySet()) {
String room = entry.getKey();
Set<String> users = entry.getValue();
users.remove(session.getId());
sendMessage(room, users.size() + " 人在线");
}
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
String[] parts = payload.split(":");
String room = parts[0];
String content = parts[1];
if (!rooms.containsKey(room)) {
rooms.put(room, new HashSet<>());
}
Set<String> users = rooms.get(room);
users.add(session.getId());
for (WebSocketSession s : sessions.values()) {
if (users.contains(s.getId())) {
s.sendMessage(new TextMessage(content));
}
}
}
private void sendMessage(String room, String message) throws IOException {
Set<String> users = rooms.get(room);
if (users != null) {
for (WebSocketSession s : sessions.values()) {
if (users.contains(s.getId())) {
s.sendMessage(new TextMessage(message));
}
}
}
}
}
```
在 handleTextMessage 方法中,根据收到的消息中的房间名,将当前连接加入到对应的房间中,并向该房间中的所有在线用户发送消息。
在 afterConnectionClosed 方法中,将当前连接从所有房间中移除,并向这些房间中的在线用户发送消息。
5. 测试
启动应用程序后,打开两个浏览器窗口,分别连接到 http://localhost:8080/index.html。
在第一个窗口中,输入房间名和用户名,点击“加入”按钮,进入该房间。在第二个窗口中,输入相同的房间名和不同的用户名,点击“加入”按钮,也进入该房间。
在任意一个窗口中,输入消息并按回车键,即可将消息发送到该房间中的所有在线用户。在另一个窗口中,也可以看到这些消息。同时,窗口中会显示当前房间中的在线用户数。