实现用户通知
构建健壮的通知系统,实时向用户发送即时告警和更新。
实现用户通知 是 CoddyKit 上的免费 WebSockets & Real-Time Systems with Spring 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 WebSockets & Real-Time Systems with Spring 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 WebSockets & Real-Time Systems with Spring 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
What are User Notifications?
User notifications are essential for modern applications. They keep users informed about important events, updates, or messages in real-time.
Think about social media alerts, new email warnings, or game invites. They boost engagement and ensure users don't miss crucial information.
Core Notification System
A robust real-time notification system typically involves a few key components:
- Backend Service: To generate and send notifications.
- Message Broker: To route notifications efficiently to the correct users.
- Client-Side Logic: To receive, display, and manage notifications.
We'll focus on the in-app, real-time aspect using Spring WebSockets and STOMP.
Crafting a Notification Model
First, we need a data structure for our notifications. This model defines what information each notification carries.
Key fields often include:
id: Unique identifier.recipientId: Who gets the notification.senderId: Who sent it (optional).message: The actual content.type: Category (e.g., "message", "alert", "friend_request").timestamp: When it was created.isRead: Has the user seen it? (true/false)
Server-Side Notification Creation
On the server, an event (like a new message or a user action) triggers the creation of a Notification object. This object is then processed and sent.
Here's a simple Java class representing our notification model:
public class Notification {
private String id;
private String recipientId;
private String senderId;
private String message;
private String type;
private long timestamp;
private boolean isRead;
// Constructor
public Notification(String recipientId, String senderId, String message, String type) {
this.id = java.util.UUID.randomUUID().toString();
this.recipientId = recipientId;
this.senderId = senderId;
this.message = message;
this.type = type;
this.timestamp = System.currentTimeMillis();
this.isRead = false;
}
// Getters (and setters if needed)
public String getId() { return id; }
public String getRecipientId() { return recipientId; }
public String getSenderId() { return senderId; }
public String getMessage() { return message; }
public String getType() { return type; }
public long getTimestamp() { return timestamp; }
public boolean isRead() { return isRead; }
public void setRead(boolean read) { isRead = read; }
@Override
public String toString() {
return "Notification [recipient=" + recipientId + ", msg='" + message + "']";
}
}Directing User Notifications
To send a notification to a specific user, we leverage STOMP's user destinations. Spring's messaging template simplifies this.
The destination typically looks like /user/{userId}/queue/notifications. When the server sends a message to this destination, Spring automatically routes it to the WebSocket session(s) associated with that userId.
This ensures only the intended recipient receives the notification.
Pushing Notifications (Server Concept)
On the server, when an event triggers a notification, a backend service will create a Notification object. Then, using Spring's SimpMessagingTemplate, it sends this notification to the recipient's private STOMP queue.
The convertAndSendToUser method is crucial here, mapping the user ID to their active WebSocket session(s).
While SimpMessagingTemplate needs a Spring context, we can illustrate the notification object and a conceptual send:
public class Notification {
private String recipientId;
private String message;
private long timestamp;
public Notification(String recipientId, String message) {
this.recipientId = recipientId;
this.message = message;
this.timestamp = System.currentTimeMillis();
}
public String getRecipientId() { return recipientId; }
public String getMessage() { return message; }
public long getTimestamp() { return timestamp; }
@Override
public String toString() {
return "Notification [to=" + recipientId + ", msg='" + message + "']";
}
public static void main(String[] args) {
// This simulates creating and conceptually sending a notification
String userId = "user123";
String notificationMessage = "You have a new message!";
Notification newNotification = new Notification(userId, notificationMessage);
System.out.println("Created notification: " + newNotification);
System.out.println("Spring's SimpMessagingTemplate would then send this to /user/" + userId + "/queue/notifications");
System.out.println("Client-side would receive this via their WebSocket subscription.");
}
}Client Listens for Updates
On the client side (e.g., a web browser), the user needs to subscribe to their personal notification queue. This is done via the WebSocket connection, once authenticated.
The subscription destination will match the server-side sending pattern: /user/queue/notifications.
Any message sent by the server to this destination for the authenticated user will be received by the client.
Client-Side Subscription (JS)
Here's a basic JavaScript snippet using a STOMP client library (like stomp.js or @stomp/stompjs) to connect and subscribe.
// Assume 'stompClient' is already connected to WebSocket
// and authenticated.
// Function to handle incoming notifications
function onNotificationReceived(notification) {
console.log("Received notification:", notification.body);
// Parse JSON body, e.g., JSON.parse(notification.body)
// Then update UI to display the notification
displayNotification(JSON.parse(notification.body));
}
// Function to display notification in UI
function displayNotification(notifObj) {
const notifArea = document.getElementById("notificationArea");
const newNotif = document.createElement("div");
newNotif.innerHTML = `<b>${notifObj.message}</b>
<small>(${new Date(notifObj.timestamp).toLocaleTimeString()})</small>`;
notifArea.prepend(newNotif);
}
// Subscribe to the user's private notification queue
stompClient.subscribe('/user/queue/notifications', onNotificationReceived);
console.log("Subscribed to /user/queue/notifications");
// In a real app, you'd have a 'connect' function first.
// Example: stompClient.connect({}, frame => { ... subscribe here ... });Marking Notifications as Read
Once a user views a notification, it's good practice to mark it as read. This typically involves a separate interaction, not directly through WebSockets for the update itself.
The client can send a simple REST API call (e.g., a PUT or POST request) to the backend, indicating which notification(s) should be marked as read.
The backend then updates the notification's isRead status in the database.
Notification Delivery Check
You've built a system to send real-time notifications to specific users. How does the server ensure a notification reaches only the intended recipient?
Recap: Building Notifiers
In this lesson, we explored how to implement a real-time user notification system.
- We designed a
Notificationmodel. - Learned to use Spring's
SimpMessagingTemplatewithconvertAndSendToUserfor targeted delivery. - Understood how clients subscribe to their private queues (
/user/queue/notifications). - Discussed marking notifications as read via a REST API.
These principles allow you to build engaging, interactive applications that keep users informed instantly!
常见问题解答
「实现用户通知」课时是免费的吗?
是的 — 「实现用户通知」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 WebSockets & Real-Time Systems with Spring 课程的其余内容,请升级到 CoddyKit PRO。 WebSockets & Real-Time Systems with Spring 课程共包含 4 节课。
「实现用户通知」这节课中我会学到什么?
构建健壮的通知系统,实时向用户发送即时告警和更新。 你通过在浏览器中直接运行的动手代码来练习 WebSockets & Real-Time Systems with Spring,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 WebSockets & Real-Time Systems with Spring 需要有经验吗?
无需任何先前经验。CoddyKit 上的 WebSockets & Real-Time Systems with Spring 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「实现用户通知」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 WebSockets & Real-Time Systems with Spring 课中编写并运行代码吗?
能。每节 WebSockets & Real-Time Systems with Spring 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。