Files
OneMD/posts/blog/工作/项目/DeviceTransfer.md
T
2026-06-19 14:45:07 +08:00

218 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: DeviceTransfer
date: 2025-04-07
categories: [工作, 项目]
tags: [项目]
---
```Plain
请为我生成一个基于 Spring Boot 的后端项目,项目名称为 "DeviceTransfer",实现设备间消息和文件传输功能,使用 Redis、RabbitMQ 和 MySQL 作为辅助技术。以下是具体要求:
1. **项目结构**
- 包名:`com.example.devicetransfer`
- 结构:
- `Application.java`Spring Boot 启动类
- `config/`
- `WebSocketConfig.java`:配置 WebSocket,支持 STOMP 协议
- `RabbitMQConfig.java`:配置 RabbitMQ 交换机和队列
- `RedisConfig.java`:配置 Redis 客户端
- `MyBatisConfig.java`:配置 MyBatis 数据访问层
- `controller/`
- `FileController.java`:处理 HTTP 文件上传、下载及传输控制
- `websocket/`
- `NotificationController.java`:处理 WebSocket 实时通知
- `service/`
- `DeviceService.java`:管理设备状态
- `FileService.java`:处理文件传输逻辑(包括分片、断点续传、暂停)
- `MessageService.java`:处理消息发送和通知
- `mq/`
- `producer/FileMessageProducer.java`:发送消息到 RabbitMQ
- `consumer/FileMessageConsumer.java`:消费 RabbitMQ 消息
- `repository/`
- `DeviceRepository.java`:使用 Redis 存储设备状态
- `mapper/FileMetadataMapper.java`:使用 MyBatis 操作 MySQL 文件元数据
- `model/`
- `Device.java`:设备实体类
- `FileMetadata.java`:文件元数据类(映射到 MySQL)
- `util/`
- `FileChunkUtil.java`:大文件分片和断点续传工具类
- `resources/`
- `application.yml`:配置文件
- `mapper/FileMetadataMapper.xml`MyBatis SQL 映射文件
2. **功能需求**
- **文件传输**
- HTTP POST `/upload`:支持大文件分片上传,保存到 `uploads/` 目录,返回文件 ID。
- 参数:`file`(分片内容)、`fileId`(文件唯一标识)、`chunkIndex`(分片索引)、`totalChunks`(总分片数)。
- 支持断点续传:记录已上传分片,客户端可续传未完成部分。
- 支持中途暂停/取消:HTTP DELETE `/upload/cancel/{fileId}` 取消上传并清理分片。
- HTTP GET `/download/{fileId}`:根据文件 ID 下载,支持分片下载和断点续传。
- 参数:`Range` 头支持范围请求(如 `Range: bytes=0-1048575`)。
- 支持暂停:客户端可随时中断请求。
- **实时通知**
- WebSocket 端点 `/ws`,订阅 `/topic/messages`,发送消息到 `/app/send`。
- 在线设备通过 WebSocket 接收通知,离线设备消息存入 RabbitMQ。
- **设备管理**
- 设备通过 WebSocket 注册(发送 userId 和 deviceId)。
- Redis 存储用户设备状态(键格式:`user:{userId}:devices`)。
- **离线支持**
- 文件上传后,若目标设备离线,消息发送到 RabbitMQ 的 `file-queue`。
- 设备上线时,消费队列消息并通过 WebSocket 推送。
- **数据持久化**
- 使用 MySQL 存储文件元数据,表名 `file_metadata`,字段:
- `id` (主键)、`file_id` (唯一标识)、`file_name`、`file_path`、`user_id`、`total_chunks`、`uploaded_chunks`、`status` (上传状态:uploading/completed/canceled)、`upload_time`。
- MyBatis 操作数据库,定义增删改查 SQL。
3. **技术要求**
- 使用 Spring Boot 2.x 或 3.x。
- Redis 用于存储设备状态(键格式:`user:{userId}:devices`)和分片进度(键格式:`file:{fileId}:chunks`)。
- RabbitMQ 使用 Direct 交换机(`file-exchange`)、队列(`file-queue`)、路由键(`file.routing.key`)。
- MySQL 通过 MyBatis 持久化文件元数据。
- 文件存储在本地 `uploads/` 目录,分片文件命名格式:`{fileId}_{chunkIndex}`,完成后合并为 `{fileId}`。
- 不配置 TLSHTTP 和 WebSocket 使用非加密协议)。
4. **依赖**
- `spring-boot-starter-web`
- `spring-boot-starter-websocket`
- `spring-boot-starter-data-redis`
- `spring-boot-starter-amqp`
- `mybatis-spring-boot-starter`
- `mysql-connector-java`
5. **其他说明**
- 提供基本的错误处理和日志记录(使用 SLF4J)。
- 代码注释清晰,说明每个类的作用。
- 生成完整的 Maven `pom.xml` 文件。
- **大文件分片和断点续传**:
- 客户端上传分片,服务端记录进度到 Redis`file:{fileId}:chunks` 存储已上传分片索引)。
- 续传时,客户端查询已上传分片(GET `/upload/status/{fileId}`),跳过已完成部分。
- 暂停/取消:DELETE `/upload/cancel/{fileId}` 删除分片并更新状态为 canceled。
- **下载支持**
- 服务端响应 `Range` 头,返回指定范围的分片。
- 客户端可暂停下载,续传时通过 `Range` 请求剩余部分。
请根据以上要求生成完整的项目代码,确保结构清晰、可运行,并支持未来扩展(如引入 Netty 或替换 RabbitMQ 为 Kafka)。
```
请为我生成一个基于 Spring Boot 的后端项目,项目名称为 "DeviceTransfer",实现设备间消息和文件传输功能,使用 Redis、RabbitMQ 和 MySQL 作为辅助技术。以下是具体要求:
1. **项目结构**
- 包名:`com.qgs.devicetransfer`
- 结构:
- `Application.java`Spring Boot 启动类
- `config/`
- `WebSocketConfig.java`:配置 WebSocket,支持 STOMP 协议
- `RabbitMQConfig.java`:配置 RabbitMQ 交换机和队列
- `RedisConfig.java`:配置 Redis 客户端
- `controller/`
- `FileController.java`:处理 HTTP 文件上传、下载及传输控制
- `websocket/`
- `NotificationController.java`:处理 WebSocket 实时通知
- `service/`
- `DeviceService.java`:管理设备状态
- `FileService.java`:处理文件传输逻辑(包括分片、断点续传、暂停)
- `MessageService.java`:处理消息发送和通知
- `mq/`
- `producer/FileMessageProducer.java`:发送消息到 RabbitMQ
- `consumer/FileMessageConsumer.java`:消费 RabbitMQ 消息
- `repository/`
- `DeviceRepository.java`:使用 Redis 存储设备状态
- `mapper/FileMetadataMapper.java`:使用 MyBatis 操作 MySQL 文件元数据
- `model/`
- `Device.java`:设备实体类
- `FileMetadata.java`:文件元数据类(映射到 MySQL
- `util/`
- `FileChunkUtil.java`:大文件分片和断点续传工具类
- `resources/`
- `application.yml`:配置文件
- `mapper/FileMetadataMapper.xml`MyBatis SQL 映射文件
2. **功能需求**
- **文件传输**
- HTTP POST `/upload`:支持大文件分片上传,保存到 `uploads/` 目录,返回文件 ID。
- 参数:`file`(分片内容)、`fileId`(文件唯一标识)、`chunkIndex`(分片索引)、`totalChunks`(总分片数)。
- 支持断点续传:记录已上传分片,客户端可续传未完成部分。
- 支持中途暂停/取消:HTTP DELETE `/upload/cancel/{fileId}` 取消上传并清理分片。
- HTTP GET `/download/{fileId}`:根据文件 ID 下载,支持分片下载和断点续传。
- 参数:`Range` 头支持范围请求(如 `Range: bytes=0-1048575`)。
- 支持暂停:客户端可随时中断请求。
- **实时通知**
- WebSocket 端点 `/ws`,订阅 `/topic/messages`,发送消息到 `/app/send`
- 在线设备通过 WebSocket 接收通知,离线设备消息存入 RabbitMQ。
- **设备管理**
- 设备通过 WebSocket 注册(发送 userId 和 deviceId)。
- Redis 存储用户设备状态(键格式:`user:{userId}:devices`)。
- **离线支持**
- 文件上传后,若目标设备离线,消息发送到 RabbitMQ 的 `file-queue`
- 设备上线时,消费队列消息并通过 WebSocket 推送。
- **数据持久化**
- 使用 MySQL 存储文件元数据,表名 `file_metadata`,字段:
- `id` (主键)、`file_id` (唯一标识)、`file_name``file_path``user_id``total_chunks``uploaded_chunks``status` (上传状态:uploading/completed/canceled)、`upload_time`
- MyBatis 操作数据库,定义增删改查 SQL。
3. **技术要求**
- 使用 Spring Boot 3.4.4
- Redis 用于存储设备状态(键格式:`user:{userId}:devices`)和分片进度(键格式:`file:{fileId}:chunks`)。
- RabbitMQ 使用 Direct 交换机(`file-exchange`)、队列(`file-queue`)、路由键(`file.routing.key`)。
- MySQL 通过 MyBatis 持久化文件元数据。
- 文件存储在本地 `uploads/` 目录,分片文件命名格式:`{fileId}_{chunkIndex}`,完成后合并为 `{fileId}`
- 不配置 TLSHTTP 和 WebSocket 使用非加密协议)。
4. **其他说明**
- 提供基本的错误处理和日志记录(使用 SLF4J)。
- 代码注释清晰,说明每个类的作用。
- **大文件分片和断点续传**
- 客户端上传分片,服务端记录进度到 Redis(`file:{fileId}:chunks` 存储已上传分片索引)。
- 续传时,客户端查询已上传分片(GET `/upload/status/{fileId}`),跳过已完成部分。
- 暂停/取消:DELETE `/upload/cancel/{fileId}` 删除分片并更新状态为 canceled。
- **下载支持**
- 服务端响应 `Range` 头,返回指定范围的分片。
- 客户端可暂停下载,续传时通过 `Range` 请求剩余部分。
请根据以上要求生成完整的项目代码,确保结构清晰、可运行,并支持未来扩展(如引入 Netty 或替换 RabbitMQ 为 Kafka)。
```Java
CREATE TABLE file_metadata (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
file_id VARCHAR(64) NOT NULL UNIQUE,
file_name VARCHAR(255) NOT NULL,
file_path VARCHAR(255) NOT NULL,
user_id VARCHAR(64) NOT NULL,
total_chunks INT NOT NULL,
uploaded_chunks INT NOT NULL,
status VARCHAR(20) NOT NULL,
upload_time VARCHAR(30) NOT NULL,
INDEX idx_file_id (file_id),
INDEX idx_user_id (user_id)
);
```
登录
- http → 登录获得token
ws请求、连接都携带token
连接后、上线:
- 查看历史消息(可限制天数、已发送消息)、redis查询离线消息,进行返回;
推送消息:客户端接收离线消息并返回确认,服务器接收确认消息,更新sql状态、redis状态
发送消息:
- 接收消息,**基础校验,防止恶意请求**,写入消息队列,
- 消费队列处理信息,**深度校验(防止越权、内容监控、广告)**
- 写入MySQL
- 判断是否在线,在线则进行消息推送
- 不在线保存到redis中
推送机制
- 推送成功,修改数据库内容
- 推送失败,重试