deepseek封装结合websocket实现与ai对话

项目概述与设计思路

在现代Web应用中,集成AI对话能力可以显著提升用户体验。本项目采用分层架构设计,将WebSocket实时通信与DeepSeek AI服务解耦,实现了可维护、可扩展的智能对话系统。

核心设计理念

  • 接口隔离原则:通过接口定义服务契约,便于后续实现替换
  • 单一职责原则:每个类只负责特定功能模块
  • 实时通信:利用WebSocket实现低延迟的双向数据交换

详细代码解析

1. 服务层接口设计 - 定义AI服务契约

java 复制代码
package com.qcby.websocket.service;

import java.io.IOException;

public interface DeepSeekService {
    // 核心方法:向DeepSeek API发送问题并获取响应
    String getDeepSeekResult(String question) throws IOException;
}

设计意图​:

  • 定义标准的AI服务接口,为后续可能的服务替换(如切换为其他AI提供商)提供便利
  • throws IOException 明确声明可能出现的网络异常,强制调用方处理

2. 服务层实现 - DeepSeek API集成

java 复制代码
package com.qcby.websocket.service.Impl;

import com.qcby.websocket.service.DeepSeekService;
import okhttp3.*;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service  // Spring注解,将该类声明为服务层组件
public class DeepSeekServiceImpl implements DeepSeekService {

    @Override
    public String getDeepSeekResult(String question) throws IOException {
        // 1. 创建HTTP客户端实例
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        
        // 2. 设置请求内容类型为JSON
        MediaType mediaType = MediaType.parse("application/json");
        
        // 3. 构造符合DeepSeek API要求的请求体
        String jsonBody = String.format("{\n"
                + "  \"model\": \"deepseek-chat\",\n"      // 指定使用的模型
                + "  \"messages\": [\n"                    // 对话消息数组
                + "    {\"role\": \"user\", \"content\": \"%s\"}\n"  // 用户消息
                + "  ],\n"
                + "  \"temperature\": 0.7,\n"    // 控制回复随机性(0-1)
                + "  \"top_p\": 0.8\n"           // 核采样参数,控制词汇选择范围
                + "}", question);
        
        // 4. 创建请求体对象
        RequestBody body = RequestBody.create(mediaType, jsonBody);
        
        // 5. 构建完整的HTTP请求
        Request request = new Request.Builder()
                .url("https://api.deepseek.com/chat/completions")  // API端点
                .method("POST", body)              // POST请求
                .addHeader("Content-Type", "application/json")     // 请求头
                .addHeader("Accept", "application/json")
                .addHeader("Authorization", "Bearer yourToken")    // 认证令牌
                .build();
        
        // 6. 执行请求并获取响应
        Response response = client.newCall(request).execute();
        
        // 7. 返回响应体内容
        return response.body().string();
    }
}

关键技术点详解​:

请求参数说明​:

  • temperature:值越大回复越随机有创意,值越小回复越确定保守
  • top_p:累计概率阈值,影响词汇选择的多样性

HTTP客户端选择​:

  • 使用OkHttp而非Spring的RestTemplate,因为OkHttp在处理大量并发请求时性能更优
  • OkHttp支持连接池复用,减少TCP握手开销

3. WebSocket消息处理器 - 实时通信核心

java 复制代码
@Component  // Spring组件注解,纳入IoC容器管理
public class ChatHandler implements WebSocketHandler {

    @Autowired  // 依赖注入,Spring自动装配DeepSeekService实例
    private DeepSeekService deepSeekService;
    
    /​**​
     * 用户会话管理Map
     * Key: session.getId() - 会话唯一标识
     * Value: WebSocketSession - 活跃的WebSocket会话对象
     * static修饰确保所有ChatHandler实例共享同一会话集合
     */
    public static final Map<String,WebSocketSession> USERSOCKETSESSION = new HashMap<>();

    /​**​
     * 连接建立成功回调
     * 当客户端成功建立WebSocket连接时触发
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("新用户连接,会话ID:" + session.getId());
        // 将新会话存入管理Map,便于后续消息定向发送
        USERSOCKETSESSION.put(session.getId(), session);
    }

    /​**​
     * 核心消息处理方法
     * 当客户端发送消息到服务端时触发
     */
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        System.out.println("接收到来自会话[" + session.getId() + "]的消息:" + message.getPayload().toString());
        
        // 步骤1:JSON反序列化 - 将客户端消息转换为Message对象
        Message meg = GsonUtils.fromJson(message.getPayload().toString(), Message.class);
        String question = meg.getMessage();
        
        // 步骤2:调用AI服务 - 将用户问题发送给DeepSeek
        String answer = deepSeekService.getDeepSeekResult(question);
        
        // 步骤3:解析DeepSeek API响应
        JSONObject jsonObject = new JSONObject(answer);        // 将JSON字符串转换为对象
        JSONArray choices = jsonObject.getJSONArray("choices"); // 获取choices数组
        JSONObject choicesAnswer = choices.getJSONObject(0);   // 获取第一个选择
        JSONObject messageAnswer = choicesAnswer.getJSONObject("message"); // 获取消息内容
        String content = messageAnswer.getString("content");   // 提取最终回复文本
        
        System.out.println("AI回复内容:" + content);
        
        // 步骤4:检查会话状态并返回响应
        if(session.isOpen()){  // 重要:发送前检查连接是否仍然有效
            // 构造TextMessage对象并发送给客户端
            session.sendMessage(new TextMessage(content));
        }
    }

    /​**​
     * 群发消息功能 - 向所有在线用户广播消息
     * 适用于公告、系统通知等场景
     */
    public void sendMessageToAll(Message message) throws IOException {
        // 遍历所有活跃会话
        for (Map.Entry<String, WebSocketSession> entry : USERSOCKETSESSION.entrySet()){
            final WebSocketSession webSocketSession = entry.getValue();
            // 检查会话有效性后再发送
            if(webSocketSession.isOpen()){
                // 将Message对象序列化为JSON字符串
                webSocketSession.sendMessage(new TextMessage(GsonUtils.toJson(message)));
            }
        }
    }

    /​**​
     * 私聊功能 - 向指定用户发送消息
     * @param userId 目标用户的会话ID
     */
    public void sendMessageToUser(String userId, Message message) throws IOException {
        // 根据用户ID从会话Map中查找对应会话
        WebSocketSession webSocketSession = USERSOCKETSESSION.get(userId);
        if(webSocketSession != null && webSocketSession.isOpen()){
            webSocketSession.sendMessage(new TextMessage(GsonUtils.toJson(message)));
        }
    }

    /​**​
     * 传输错误处理 - 网络异常、协议错误等
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println("会话[" + session.getId() + "]连接出错:" + exception.getMessage());
        // 从会话管理中移除异常会话
        USERSOCKETSESSION.remove(session.getId());
        // 确保关闭异常会话,释放资源
        if (session.isOpen()) {
            session.close();
        }
    }

    /​**​
     * 连接关闭回调 - 客户端主动断开或超时断开
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        System.out.println("会话[" + session.getId() + "]已关闭,状态:" + closeStatus.toString());
        // 清理会话资源
        USERSOCKETSESSION.remove(session.getId());
    }

    /​**​
     * 是否支持部分消息 - 对于大文件分片传输
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;  // 本项目不处理大消息分片
    }
}

核心架构优势

1. 会话管理机制

  • 实时状态维护:通过HashMap实时跟踪所有在线用户
  • 自动清理:连接异常或关闭时自动清理会话资源,防止内存泄漏
  • 会话查找优化:O(1)时间复杂度的用户会话查找

2. 消息处理流程

复制代码
客户端消息 → WebSocket接收 → JSON反序列化 → AI服务调用 → 响应解析 → WebSocket返回

3. 异常处理策略

  • 网络异常:IOException处理API调用失败
  • 会话异常:自动移除无效会话,保持系统稳定
  • JSON解析异常:通过try-catch确保格式错误的响应不会导致系统崩溃
相关推荐
hesorchen8 小时前
算力与数据驱动的 AI 技术演进全景(1999-2024):模型范式、Infra 数据、语言模型与多模态的关键突破
人工智能·语言模型·自然语言处理
你也渴望鸡哥的力量么8 小时前
基于边缘信息提取的遥感图像开放集飞机检测方法
人工智能·计算机视觉
xian_wwq8 小时前
【学习笔记】深度学习中梯度消失和爆炸问题及其解决方案研究
人工智能·深度学习·梯度
StarRocks_labs8 小时前
StarRocks 4.0:Real-Time Intelligence on Lakehouse
starrocks·人工智能·json·数据湖·存算分离
Tracy9738 小时前
DNR6521x_VC1:革新音频体验的AI降噪处理器
人工智能·音视频·xmos模组固件
weixin_307779139 小时前
基于AWS Lambda事件驱动架构与S3智能生命周期管理的制造数据自动化处理方案
人工智能·云计算·制造·aws
yumgpkpm9 小时前
CMP(类ClouderaCDP7.3(404次编译) )完全支持华为鲲鹏Aarch64(ARM)使用 AI 优化库存水平、配送路线的具体案例及说明
大数据·人工智能·hive·hadoop·机器学习·zookeeper·cloudera
cpq379 小时前
AI学习研究——KIMI对佛教四圣谛深度研究
人工智能·学习
丁浩6669 小时前
统计学---2.描述性统计-参数估计
人工智能·算法