# java-sse-proxy **Repository Path**: suimu/java-sse-proxy ## Basic Information - **Project Name**: java-sse-proxy - **Description**: 使用 JAVA 代理 SSE 接口,中断与 JAVA 的链接,不影响与其他智能体流式服务的输出。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-15 - **Last Updated**: 2026-01-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Dify Chat Proxy 基于 Spring Boot 的 Dify Chat API 代理服务,支持流式对话和断点续传。 ## 🎯 核心特性 - ✅ **统一流式接口**:只有一个接口,支持新请求和断点续传 - ✅ **连接隔离**:每个 SSE 连接独立追踪读取位置 - ✅ **后台持久**:客户端断开不影响 Dify 请求继续执行 - ✅ **自动续传**:重连时自动从断点继续,无消息丢失 - ✅ **多端支持**:同一任务可被多客户端同时读取 - ✅ **完整文档**:Swagger UI + 详细技术文档 ## 🚀 快速开始 ### 1. 配置环境变量 ```bash export DIFY_API_KEY=your-api-key-here ``` ### 2. 启动应用 ```bash cd java-proxy mvn clean spring-boot:run ``` ### 3. 访问 Swagger 打开浏览器访问:http://localhost:8080/swagger-ui.html ### 4. 测试接口 #### 新请求(不传 task_id) ```bash curl -X POST http://localhost:8080/api/v1/chat/stream \ -H "Content-Type: application/json" \ -H "Accept: text/event-stream" \ -d '{ "query": "什么是人工智能?", "user": "user-123" }' ``` 响应: ``` event: task_created data: {"task_id": "abc-123-def"} event: data data: [{"event":"message","answer":"人工智能是..."}] ... ``` #### 断点续传(传入 task_id) ```bash curl -X POST http://localhost:8080/api/v1/chat/stream \ -H "Content-Type: application/json" \ -H "Accept: text/event-stream" \ -d '{ "task_id": "abc-123-def", "query": "什么是人工智能?", "user": "user-123" }' ``` ## 📖 文档资源 | 文档 | 说明 | |------|------| | [API使用说明.md](./API使用说明.md) | API 使用指南、客户端示例 | | [架构说明.md](./架构说明.md) | 技术架构、组件详解 | ## 🏗️ 架构概览 ``` 客户端请求(携带可选的 task_id) ↓ 统一入口:POST /api/v1/chat/stream ↓ ├─ task_id 为空 → 创建新任务 → 启动异步任务 → 阻塞 500ms └─ task_id 不为空 → 读取缓存 → 从连接位置继续 ↓ 返回 SSE 流(每 50ms 轮询缓存推送) ↓ ├─ 异步任务层(后台调用 Dify) ├─ 缓存层(消息队列) └─ 连接位置追踪(每个连接独立) ``` ## 💡 使用场景 ### 场景 1:普通对话 ```javascript fetch('/api/v1/chat/stream', { method: 'POST', body: JSON.stringify({ query: '什么是AI?', user: 'user-123' }) }); ``` ### 场景 2:断线重连 ```javascript // 1. 首次请求,保存 task_id let taskId = null; // ... 从响应中获取 task_id // 2. 重新连接(传入 task_id) fetch('/api/v1/chat/stream', { method: 'POST', body: JSON.stringify({ task_id: taskId, // 关键:传入已有的 task_id query: '什么是AI?', user: 'user-123' }) }); ``` ### 场景 3:多设备同步 ```javascript // 设备 A 和设备 B 使用相同的 task_id // 可以同时读取,每个设备独立追踪位置 ``` ## ⚙️ 配置参数 | 参数 | 默认值 | 说明 | 调优建议 | |------|--------|------|----------| | 初始等待时间 | 500ms | 新任务创建后主线程等待首批数据 | 200-1000ms | | 轮询间隔 | 50ms | SSE 流轮询缓存的间隔 | 20-200ms | | 缓存过期时间 | 1 小时 | 已完成任务的缓存保留时间 | 根据业务调整 | | 核心线程数 | 10 | 异步任务线程池核心线程数 | CPU 核心数 × 2 | | 最大线程数 | 50 | 异步任务线程池最大线程数 | 根据 QPS 调整 | ## 🔧 技术栈 - Spring Boot 3.2.1 - Spring WebFlux (Reactive Streams) - SpringDoc OpenAPI 3 (Swagger) - Lombok - Jackson ## 📦 项目结构 ``` src/main/java/com/ruoyi/ ├── Main.java # 启动类 ├── config/ # 配置类 │ ├── AsyncConfig.java # 异步线程池配置 ⭐ 新增 │ ├── SwaggerConfig.java # Swagger 配置 ⭐ 新增 │ ├── CorsConfig.java # CORS 配置 │ ├── DifyConfig.java # Dify API 配置 │ └── WebClientConfig.java # WebClient 配置 ├── controller/ # 控制器 │ └── ChatController.java # 统一流式接口 ⭐ 简化 ├── dto/ # 数据传输对象 │ ├── ChatRequest.java # 请求 DTO(新增 task_id)⭐ │ ├── ChatResponse.java # 响应 DTO │ ├── ErrorResponse.java # 错误响应 DTO │ ├── TaskInfo.java # 任务信息 DTO │ └── CachedMessage.java # 缓存消息 DTO └── service/ # 服务层 ├── DifyService.java # Dify 服务 ⭐ 重构 ├── AsyncTaskService.java # 异步任务服务 └── MessageCacheService.java # 消息缓存服务 ⭐ 增强 ``` ## 🧪 测试 可通过 Swagger UI 或 curl 命令测试接口功能。 ## 📊 监控 ### 健康检查 ```bash curl http://localhost:8080/api/v1/health ``` ## 🤝 贡献 欢迎提交 Issue 和 Pull Request。 ## 📄 许可证 MIT License --- ## 🆕 更新日志 ### v2.0.0(当前版本) **重大改进**: - ✅ 统一接口设计,只保留一个 stream 接口 - ✅ 支持通过 `task_id` 参数进行断点续传 - ✅ 每个连接独立追踪读取位置 - ✅ 新任务阻塞 500ms 优化首屏体验 - ✅ 添加完整的 Swagger 文档 - ✅ 删除冗余的阻塞接口和查询接口 **改进详情**:见架构说明和API使用说明文档 ### v1.0.0 - 初始版本 - 支持流式和阻塞式对话 - 基础的断点续传功能