InvenTree WebSocket实时通知:库存变更即时推送实现
库存管理系统中,实时掌握库存动态是提升工作效率的关键。传统的轮询方式不仅延迟高,还会增加服务器负担。本文将详细介绍InvenTree如何通过WebSocket技术实现库存变更的实时通知推送,帮助用户即时响应库存变动。
系统架构概览
InvenTree作为一款开源库存管理系统,其通知系统采用前后端分离架构。后端基于Django框架,负责业务逻辑处理和数据存储;前端使用React+TypeScript构建用户界面,通过WebSocket与后端建立持久连接,实现实时通信。
核心模块组成
- 后端通知触发模块:src/backend/InvenTree/common/notifications.py
- 任务调度系统:src/backend/InvenTree/InvenTree/tasks.py
- 前端WebSocket客户端:src/frontend/src/services/websocket.ts
- 通知UI组件:src/frontend/src/components/notifications/NotificationCenter.tsx
后端实现:库存变更事件捕获
InvenTree后端通过信号机制监控库存变动,当发生入库、出库、库存调整等操作时,自动触发通知流程。
信号触发机制
在库存模型中定义了post_save信号处理器,当库存记录发生变更时,会调用trigger_notification函数:
# src/backend/InvenTree/stock/models.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from common.notifications import trigger_notification
@receiver(post_save, sender=StockItem)
def handle_stock_item_change(sender, instance, created, **kwargs):
"""Handle stock item changes and trigger notifications"""
if instance.quantity_changed:
trigger_notification(
'stock.item_changed',
instance,
target_users=instance.get_subscribed_users(),
context={'quantity': instance.quantity, 'part': instance.part.name}
)
任务队列处理
为避免阻塞主线程,通知触发后会被加入任务队列异步处理:
# src/backend/InvenTree/part/tasks.py
@celery_app.task(bind=True)
def notify_low_stock(self, part_id, threshold=None):
"""Notify users about low stock levels for a part"""
part = Part.objects.get(pk=part_id)
if part.stock_count() <= (threshold or part.min_stock_level):
trigger_notification(
'part.low_stock',
part,
template={'html': 'email/low_stock_notification.html', 'subject': _('Low stock notification')},
)
前端实现:WebSocket连接管理
前端通过WebSocket与后端建立持久连接,实时接收库存变更通知。WebSocket客户端实现如下:
// src/frontend/src/services/websocket.ts
import { Notification } from '../types/notification';
class WebSocketService {
private socket: WebSocket | null = null;
connect(token: string) {
this.socket = new WebSocket(`ws://${window.location.host}/ws/notifications/?token=${token}`);
this.socket.onmessage = (event) => {
const notification: Notification = JSON.parse(event.data);
this.handleNotification(notification);
};
this.socket.onclose = () => {
// 自动重连逻辑
setTimeout(() => this.connect(token), 3000);
};
}
private handleNotification(notification: Notification) {
// 显示通知提示
showNotification(notification);
// 更新通知中心
notificationStore.addNotification(notification);
}
disconnect() {
if (this.socket) {
this.socket.close();
}
}
}
export const webSocketService = new WebSocketService();
通知中心组件
前端通知中心组件负责展示和管理接收到的实时通知:
// src/frontend/src/components/notifications/NotificationCenter.tsx
import React, { useEffect, useState } from 'react';
import { useNotificationStore } from '../../stores/notificationStore';
import NotificationItem from './NotificationItem';
import './NotificationCenter.css';
const NotificationCenter: React.FC = () => {
const { notifications, markAsRead } = useNotificationStore();
const [show, setShow] = useState(false);
return (
<div className="notification-center">
<button className="notification-icon" onClick={() => setShow(!show)}>
<i className="fas fa-bell" />
{notifications.filter(n => !n.read).length > 0 && (
<span className="badge">{notifications.filter(n => !n.read).length}</span>
)}
</button>
{show && (
<div className="notification-dropdown">
<div className="dropdown-header">
<h3>Notifications</h3>
<button onClick={() => markAsRead()}>Mark all as read</button>
</div>
<div className="notification-list">
{notifications.map(notification => (
<NotificationItem key={notification.id} notification={notification} />
))}
</div>
</div>
)}
</div>
);
};
export default NotificationCenter;
实际应用场景
低库存预警
当库存低于设定阈值时,系统自动发送低库存通知:
低库存通知
库存变动日志
所有库存变更操作都会实时记录并推送:
# src/backend/InvenTree/stock/tasks.py
def log_stock_change(stock_item, user, notes, quantity_change):
"""Log a stock change event and trigger notifications"""
log_entry = StockLog.objects.create(
stock_item=stock_item,
user=user,
notes=notes,
quantity_change=quantity_change
)
trigger_notification(
'stock.logged',
stock_item,
context={'log_entry': log_entry.id, 'quantity_change': quantity_change}
)
配置与优化
通知频率控制
为避免通知泛滥,系统支持配置通知频率限制:
# config/config.yaml
notifications:
throttle:
enabled: true
period: 300 # 5 minutes
max_notifications: 10
性能优化策略
- 使用Redis作为WebSocket消息代理,提高并发处理能力
- 实现消息压缩,减少网络传输量
- 前端实现消息批处理,避免频繁UI更新
总结与展望
InvenTree通过WebSocket技术实现了库存变更的实时通知,相比传统轮询方式,具有以下优势:
- 低延迟:库存变动即时推送,响应时间<1秒
- 低消耗:减少无效请求,降低服务器负载
- 高可靠:断线自动重连,确保消息不丢失
未来,InvenTree通知系统将支持更多自定义功能,如:
- 基于角色的通知权限控制
- 自定义通知模板
- 多渠道通知集成(邮件、短信、Slack等)
通过本文介绍的WebSocket实时通知机制,InvenTree用户可以实时掌握库存动态,快速响应库存变动,显著提升库存管理效率。
官方文档:docs/app/notifications.md API参考:docs/api/metadata.md 前端源码:src/frontend/src/services/websocket.ts
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




