SpringBoo+vue3整合讯飞星火3.5通过webscoket实现聊天功能(全网首发)附带展示效果

news2024/11/15 14:08:15

API版本:Spring Boot 整合讯飞星火3.5通过接口Api接口实现聊天功能(首发)复制粘贴即可使用,后续更新WebSocket实现聊天功能_讯飞星火web聊天-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_53722480/article/details/138865508?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22138865508%22%2C%22source%22%3A%22qq_53722480%22%7D

效果展示网址:

天梦星服务平台 (tmxkj.top)icon-default.png?t=N7T8https://tmxkj.top/#/spark图片展示:

1.pom.xml文件

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.72</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </dependency>
           <dependency>
            <groupId>org.jetbrains</groupId>
            <artifactId>annotations</artifactId>
            <version>13.0</version>
            <scope>compile</scope>
        </dependency>

2.yml

spark:
  ai:
    hostUrl: https://spark-api.xf-yun.com/v3.5/chat
    appId: ####
    apiSecret: #####
    apiKey: ######

3.SparkApiConfig


import lombok.Data;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


@Data
@Component
@ConfigurationProperties(prefix = "spark")
public class SparkApiConfig {
    private  String hostUrl;
    private  String appId;
    private  String apiSecret;
    private  String apiKey;

    @Getter
    private static String hostUrl1;
    @Getter
    private static String appId1;
    @Getter
    private static String apiSecret1;
    @Getter
    private static String apiKey1;

    @PostConstruct
    public void setHostUrl() {
        hostUrl1 = this.hostUrl;
    }


    @PostConstruct
    public void setAppId() {
        appId1 = this.appId;
    }


    @PostConstruct
    public void setApiSecret() {
        apiSecret1 = this.apiSecret;
    }

    @PostConstruct
    public void setApiKey() {
        apiKey1 = this.apiKey;
    }

}

 4.Dto

@Data
public class SparkDto {
    private JSONObject payload;
    private JSONObject parameter;
    private JSONObject header;
}
@Data
public class SparkParamDto {
    private String content;
    private String userId;
    private String type;
    private String chatType;
    private String historyId;
}
@Data
public class MessageDto {
    private String content;
}

4.实体类

模型功能分类

/**
 * 模型类型分类
 */
@Data
@TableName("ai_large_model")
public class LargeModel {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String modelName;
    private String modelKey;
    private String modelDescribe;
}
/**
 * 讯飞星火会话历时记录实体类
 */
@Data
@TableName(value = "ai_spark_chat",autoResultMap = true)
public class SparkChat implements Serializable {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String userId;
    private String title;
    private String list;
    private String modelKey;
    private String uuid;
}

5.websocket

/**
 * websocket操作类
 */
@Component
@ServerEndpoint("/websocket/{userId}")
public class WebSocketServer {

    /**
     * 日志工具
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;
    /**
     * 用户id
     */
    private String userId;
    /**
     * 用来存放每个客户端对应的MyWebSocket对象
     */
    private static final CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>();
    /**
     * 用来存在线连接用户信息
     */
    private static final ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<>();


    /**
     * 链接成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId) {
        try {
            this.session = session;
            this.userId = userId;
            webSockets.add(this);
            sessionPool.put(userId, session);
            logger.info("【websocket消息】有新的连接,总数为:" + webSockets.size());
        } catch (Exception ignored) {
        }
    }

    /**
     * 链接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        try {
            webSockets.remove(this);
            sessionPool.remove(this.userId);
            logger.info("【websocket消息】连接断开,总数为:" + webSockets.size());
        } catch (Exception ignored) {
        }
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message) {
        SparkParamDto sparkParam = JSON.parseObject(message, SparkParamDto.class);
        if (Objects.equals(sparkParam.getType(), "spark")){
            getSparkApiChat(sparkParam);
        }
    }

    /**
     * 发送错误时的处理
     *  session
     *  error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        logger.error("用户错误,原因:" + error.getMessage());
        error.fillInStackTrace();
    }


    /**
     * 此为广播消息
     * 向指定用户推送消息
     */
    public boolean sendMessageToUser(String userId, String message) {
        //logger.info("【websocket消息】向用户" + userId + "发送消息:" + message);
        AtomicBoolean pass= new AtomicBoolean(false);
        Session session = sessionPool.get(userId);
        if (session != null && session.isOpen()) {
            try {
                pass.set(true);
                session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.fillInStackTrace();
            }
        }
        return pass.get();
    }


    /**
     * 此为单点消息
     */
    public void sendOneMessage(String userId, String message) {
        Session session = sessionPool.get(userId);
        if (session != null && session.isOpen()) {
            try {
//                logger.info("【websocket消息】 单点消息:" + message);
                session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.fillInStackTrace();
            }
        }
    }

    /**
     * 此为单点消息(多人)
     */
    public void sendMoreMessage(String[] userIds, String message) {
        for (String userId : userIds) {
            Session session = sessionPool.get(userId);
            if (session != null && session.isOpen()) {
                try {
                    logger.info("【websocket消息】 单点消息:" + message);
                    session.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                    e.fillInStackTrace();
                }
            }
        }

    }

    /**
     * 讯飞星火请求chat聊天
     * @param sparkParam
     */
    public void getSparkApiChat(SparkParamDto sparkParam){
        try {
            // 构建鉴权url
            String authUrl = getAuthUrl(
                    SparkApiConfig.getHostUrl1(),
                    SparkApiConfig.getApiKey1(),
                    SparkApiConfig.getApiSecret1());
            OkHttpClient client = new OkHttpClient.Builder().build();
            String url = authUrl.toString().replace("http://", "ws://").replace("https://", "wss://");
            Request request = new Request.Builder().url(url).build();
            String body = getSparkJsonSocket(SparkApiConfig.getAppId1(),sparkParam);

            StringBuilder builderSb =new StringBuilder();
            CompletableFuture<String> messageReceived = new CompletableFuture<>();

            WebSocket webSocket = client.newWebSocket(request, new WebSocketListener(){

                @Override
                public void onOpen(WebSocket webSocket, Response response) {
                    webSocket.send(body);
                }
                @Override
                public void onMessage(WebSocket webSocket, String res) {
                    JSONObject obj = JSON.parseObject(res);
                    String str= obj.getJSONObject("payload").getJSONObject("choices").getJSONArray("text").getJSONObject(0).getString("content");
                    builderSb.append(str);
                     sendOneMessage(sparkParam.getUserId(),str);
                    if(obj.getJSONObject("header").getLong("status")==2){
                        webSocket.close(1000, "Closing WebSocket connection");
                        messageReceived.complete(res); // 将收到的消息传递给 CompletableFuture
                    }
                }
            });

            String resItem = messageReceived.get(30, TimeUnit.SECONDS);// 阻塞等待消息返回
            webSocket.close(1000, "Closing WebSocket connection");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

 6.测试

{
	"content": "写一份本地js模糊查询",
	"userId": "ec491cc5c60c4a4791046caccd9c7d10",
	"type": "spark",
	"historyId": null,
	"chatType": "spaark",
}

 备注:具体问题根据自己的情况修改

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1698447.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于xilinx FPGA的 FFT IP使用例程说明文档(可动态配置FFT点数,可计算信号频率与幅度)

目录 1 概述2 IP examples功能3 IP 使用例程3.1 IP设置3.2 fft_demo端口3.3 例程框图3.4 仿真结果3.5 仿真验证得出的结论4 注意事项5例程位置 1 概述 本文用于讲解xilinx IP 的FFT ip examples的功能说明&#xff0c;方便使用者快速上手。 参考文档&#xff1a;《PG109》 2 …

推荐13款常用的Vscode插件,提高前端日常开发效率

1. Live Server Live Server 插件是一个用于前端开发的扩展&#xff0c;它的主要作用是提供一个本地开发服务器&#xff0c;以便实时预览和调试网页应用程序。其最大特点在于热重载&#xff0c;即开发者可实时预览代码效果。 因为Live Server 允许开发者在浏览器中实时预览您正…

Android Webview加载pdf文件无法缩放问题

WebView设置开启页面缩放&#xff1a; settings webView.getSettings(); settings.setSupportZoom(true); settings.setJavaScriptEnabled(true); settings.setUseWideViewPort(true); settings.setLoadWithOverviewMode(true); settings.setBuiltInZoomControls(true); sett…

集成开发环境GoLand安装配置结合内网穿透实现ssh远程访问服务器

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

MOS选型及其参数解析

背景&#xff1a; 整理现有常用元器件选型&#xff0c;日后使用时针对性观看&#xff0c;生成列表链接如下&#xff1a; https://blog.csdn.net/caozhaokun/article/details/126069701 作者&#xff1a;Cayden 时间&#xff1a;2024/05/26 一、MOS选用现状 MOS是电路设计…

【Text2SQL】Spider 数据集

论文&#xff1a;Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task ⭐⭐⭐⭐⭐ EMNLP 2018, arXiv:1809.08887 Dataset: spider GitHub: github.com/taoyds/spider 一、论文速读 本文提出了 Text2SQL 方向的…

【机器学习】基于核的机器学习算法(Kernel-based Algorithms):原理,应用与优化

&#x1f440;传送门&#x1f440; 文章引言&#x1f50d;&#x1f340;核函数的概念&#x1f680;基于核的算法原理&#x1f496;基于核的算法应用&#x1f41f;支持向量机&#xff08;SVM&#xff09;&#x1f4d5;核主成分分析&#xff08;KPCA&#xff09; &#x1f340;未…

创新实训2024.05.26日志:服务端接口实现——用户开启多个会话

1. 概念图 类似于Kimi&#xff0c;文心一言&#xff0c;chatGPT等市面上主流的大模型&#xff0c;我们的大模型也支持同一个用户的多个会话&#xff0c;并且提供支持联系上下文给出解答的能力。 2. 基于会话的对话 在langchain chatchat这个对langchain框架进行二次封装的第三…

汇编语言程序设计-5-流程转移与子程序

5. 流程转移与子程序 文章目录 5. 流程转移与子程序5.0 导学5.1 “转移”综述5.2 操作符offset5.3 jmp指令5.4 其他转移指令-jcxz、loop5.5 call指令和ret指令5.6 call和ret的配合使用5.7 mul指令5.8 汇编语言的模块化程序设计5.9 寄存器冲突的问题-子程序标准框架5.10 标志寄存…

postgresql|数据库|闪回插件e-maj的部署和使用

前言&#xff1a; E-Maj 是 PostgreSQL 数据库的一个扩展插件&#xff0c;它的全称为 "Elementary Majordomo"。这个扩展的主要功能是为数据库中的表集提供细粒度的写入日志记录和时间旅行能力。这意味着使用 E-Maj 的用户可以在数据库的特定子集上实现事务的回滚&a…

python列表元素的增减之道:删除篇

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、前言 二、删除元素的基本方法 1. 使用remove()方法 2. 使用pop()方法 3. 使用del语句…

mars3d的V2版本的Video2D与V3版本的Video2D实现数据快速迁移

场景&#xff1a; 目前是v2和v3的两个相机视角的不同格式&#xff0c;在Mars3d的V2的旧数据想可以快速迁移到V3版本。 V2版本的数据&#xff1a; {"camera": {"fov": 1.0471975511965976,"dis": 20,"stRotation": 0,"showFrust…

第 33 次CCF认证

1. 词频统计 题目描述 样例输入 代码 #include <bits/stdc.h>using namespace std;int main() {int n,m;cin>>n>>m;vector<int> ans1(m,0),ans2(m,0);while (n --) {int t;cin>>t;vector<int> vis(m1,0);for (int i 1;i < t;i ) {i…

这样的直男程序员,活该你单身一万年!

#分享下相亲时遇到过哪些奇葩现象# 这样的直男程序员&#xff0c;活该你单身一万年&#xff01; 在丛丛脱单小程序上相亲&#xff0c;遇到一个程序员妹纸&#xff0c;于是有了如下的真实故事&#xff1a; 妹子说她是程序员来着&#xff0c;想着我也是程序员&#xff0c;就想交…

【HMGD】STM32/GD32 CAN通信

各种通信协议速度分析 协议最高速度(btis/s)I2C400KCAN1MCAN-FD5M48510MSPI36M CAN协议图和通信帧 CubeMX CAN配置说明 CAN通信波特率 APB1频率 / 分频系数 /&#xff08;BS1 BS2 同步通信段&#xff09;* 1000 ​ 42 / 1 / (111) * 1000 ​ 14,000 KHz ​ 1400000…

1.4 Mac 电脑 Clion 安装教程

目录 1 安装 2 激活 3 汉化 1 安装 去 https://www.jetbrains.com/clion/download/other.html 下载: 也可以直接到链接进行下载:https

DOS学习-目录与文件应用操作经典案例-comp

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 案例 1: 基本比较 案例 2: 十进制显示差异 案例 3: 字符形式显…

1-Django开端--学生管理系统

目录 项目结构 前端页面: add_data.html class_data.html index.html apps.py models.py views.py settings,py urls.py ...实现简略的身架... 项目结构 前端页面: add_data.html --添加数据. {% extends index/index.html %}{% block content %} <div class&qu…

基于机器学习的一线城市租房价格预测分析与实现,实现三种算法预测

本文旨在基于机器学习方法&#xff0c;对一线城市租房价格进行预测分析&#xff0c;并使用Matplotlib可视化、随机森林、一元线性回归和多元线性模型进行模型对比。通过爬取北京链家二手房数据作为研究对象&#xff0c;探讨了租房价格与各种因素之间的关系&#xff0c;阐述了研…

实时计算及异构计算随笔笔记

3、异构计算的典型应用 异构计算并不神秘&#xff0c;目前已渗透各个领域&#xff0c;不仅是PC领域&#xff0c;也包括了手持移动设备领域、行业领域&#xff0c;甚至是云计算、分布式计算领域。事实上&#xff0c;异构计算至少在应用端&#xff08;前台&#xff09;并不像它的…