后端用springboot,前端用angular,使用websocket和STOMP,实现一对一聊天和群聊,若消息未读可以撤回和删除消息,可以写一个例子吗
时间: 2024-03-14 13:43:23 浏览: 206
基于SpringBoot,STOMP实现WebSocket点对点聊天+源代码+文档说明
当然可以,这里提供一个简单的例子供参考。
首先,我们需要搭建一个基于Spring Boot和Angular的Web应用,然后添加WebSocket和STOMP支持。
1. 创建一个Spring Boot项目,添加以下依赖:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
```
2. 在Spring Boot的配置文件中添加WebSocket和STOMP支持:
```yaml
spring:
websocket:
prefix: /websocket
thymeleaf:
cache: false
```
3. 创建一个WebSocket配置类,启用WebSocket和STOMP支持:
```java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic", "/queue");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat").withSockJS();
}
}
```
在这个配置类中,我们启用了简单的代理模式并定义了消息的目的地前缀,以及应用程序前缀。我们还定义了一个StompEndpoint,这个Endpoint暴露了一个SockJS端点,客户端可以使用SockJS连接到服务器。
4. 创建一个Controller类,处理WebSocket请求:
```java
@Controller
public class ChatController {
private final SimpMessagingTemplate messagingTemplate;
private final Map<String, String> users = new ConcurrentHashMap<>();
public ChatController(SimpMessagingTemplate messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
@MessageMapping("/chat/user")
public void sendToUser(ChatMessage message) {
String recipient = users.get(message.getRecipient());
if (recipient != null) {
messagingTemplate.convertAndSendToUser(recipient, "/queue/messages", message);
}
}
@MessageMapping("/chat/group")
public void sendToGroup(ChatMessage message) {
messagingTemplate.convertAndSend("/topic/messages", message);
}
@EventListener
public void handleSessionConnected(SessionConnectedEvent event) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(event.getMessage());
users.put(accessor.getUser().getName(), accessor.getSessionId());
}
@EventListener
public void handleSessionDisconnect(SessionDisconnectEvent event) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(event.getMessage());
users.remove(accessor.getUser().getName());
}
}
```
在这个Controller类中,我们为单个用户和群组分别定义了消息映射路径。当客户端发送消息时,我们使用SimpMessagingTemplate将消息转换为JSON格式并发送到目标用户或群组。我们还定义了两个事件监听器,处理连接和断开连接事件,并将用户信息存储在一个ConcurrentHashMap中。
5. 创建一个ChatMessage类,用于表示消息:
```java
@Data
public class ChatMessage {
private String sender;
private String recipient;
private String content;
private MessageType type;
private LocalDateTime timestamp;
public enum MessageType {
CHAT, JOIN, LEAVE
}
}
```
在这个类中,我们定义了消息的发送者、接收者、内容、类型和时间戳。
6. 创建一个Angular组件,用于处理WebSocket请求:
```typescript
import { Component, OnInit } from '@angular/core';
import { Message } from '../model/message';
import { ChatService } from '../service/chat.service';
@Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.css']
})
export class ChatComponent implements OnInit {
private messages: Message[] = [];
private message: Message = new Message();
constructor(private chatService: ChatService) { }
ngOnInit() {
this.chatService.connect();
this.chatService.receive().subscribe((message: Message) => {
this.messages.push(message);
});
}
send() {
this.chatService.send(this.message);
this.message.content = '';
}
}
```
在这个组件中,我们注入了一个ChatService服务,该服务负责连接WebSocket并处理消息。当组件初始化时,我们使用ChatService连接WebSocket,并通过ChatService.receive()方法订阅消息。当用户发送消息时,我们使用ChatService.send()方法将消息发送到服务器。
7. 创建一个ChatService服务,用于连接WebSocket并处理消息:
```typescript
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { webSocket, WebSocketSubject } from 'rxjs/webSocket';
import { Message } from '../model/message';
@Injectable({
providedIn: 'root'
})
export class ChatService {
private socket: WebSocketSubject<Message>;
constructor() { }
connect() {
this.socket = webSocket('ws://localhost:8080/chat');
}
send(message: Message) {
this.socket.next(message);
}
receive(): Observable<Message> {
return this.socket.asObservable();
}
}
```
在这个服务中,我们使用RxJS的webSocket方法连接到WebSocket服务器。当用户发送消息时,我们使用WebSocketSubject.next()方法将消息发送到服务器。当接收到消息时,我们使用WebSocketSubject.asObservable()方法返回一个Observable对象,组件可以通过该对象订阅消息。
8. 创建一个Message类,用于表示消息:
```typescript
export class Message {
sender: string;
recipient: string;
content: string;
type: MessageType;
timestamp: Date;
}
export enum MessageType {
CHAT = 'CHAT',
JOIN = 'JOIN',
LEAVE = 'LEAVE'
}
```
在这个类中,我们定义了消息的发送者、接收者、内容、类型和时间戳。
9. 创建一个HTML模板,用于显示聊天消息:
```html
<div class="card">
<div class="card-body">
<div class="message" *ngFor="let message of messages">
<div class="message-header">{{ message.sender }} - {{ message.timestamp | date:'medium' }}</div>
<div class="message-body">{{ message.content }}</div>
</div>
</div>
<div class="card-footer">
<form (ngSubmit)="send()">
<div class="form-group">
<input type="text" class="form-control" placeholder="Type your message here" [(ngModel)]="message.content">
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form>
</div>
</div>
```
在这个模板中,我们使用ngFor指令循环显示所有收到的消息。当用户输入消息时,我们使用ngModel指令绑定消息的内容,并在用户点击Send按钮时发送消息。
这就是一个简单的基于Spring Boot和Angular的Web应用,支持WebSocket和STOMP,可以实现一对一聊天和群聊。你可以根据需要进行修改和扩展。
阅读全文