基于SpringBoot+WebSocket的前后端连接,并接入文心一言大模型API

前言:

本片博客只讲述了操作的大致流程,具体实现步骤并不标准,请以参考为准。

本文前提:熟悉使用webSocket

 如果大家还不了解什么是WebSocket,可以参考我的这篇博客:

rWebSocket 详解:全双工通信的实现与应用-CSDN博客文章浏览阅读214次。WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它使得客户端和服务器之间的数据交换变得更加简单,允许服务器主动向客户端推送数据。通过 WebSocket API,浏览器和服务器只需完成一次握手,即可建立持久性连接,开始双向数据传输。https://blog.csdn.net/Future_yzx/article/details/145359356?spm=1001.2014.3001.5502文章浏览阅读214次。WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它使得客户端和服务器之间的数据交换变得更加简单,允许服务器主动向客户端推送数据。通过 WebSocket API,浏览器和服务器只需完成一次握手,即可建立持久性连接,开始双向数据传输。https://blog.csdn.net/Future_yzx/article/details/145359356?spm=1001.2014.3001.5502https://blog.csdn.net/Future_yzx/article/details/145359356?spm=1001.2014.3001.5502

要使用Java的Springboot+WebSocket连接前后端并接入文心一言大模型API来实现实时聊天,可以分为几个主要步骤:

  1. 搭建WebSocket服务端
  2. 与文心一言大模型API对接
  3. 前端WebSocket连接

一、 搭建WebSocket服务端(使用Java)

我们可以使用Spring Boot来搭建一个WebSocket服务端。

(1)添加依赖: 在pom.xml中添加Spring Boot WebSocket的依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

(2)配置WebSocket连接: 创建一个WebSocket配置类来启用WebSocket功能:

package com.qcby.byspringbootdemo.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

 作用:这个类负责配置Spring WebSocket。通过使用 ServerEndpointExporter 来实现 WebSocket 的启用

(3)创建WebSocketServer : 在WebSocketServer 类中处理连接、消息接收和发送。

package com.qcby.byspringbootdemo.server;import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qcby.byspringbootdemo.util.WenXinYiYanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;/*** WebSocket 服务端*/
@Component
@Slf4j
@Service
@ServerEndpoint("/api/websocket/{sid}")
public class WebSocketServer {//当前在线连接数private static int onlineCount = 0;//存放每个客户端对应的 WebSocketServer 对象private static final CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();//用户信息private Session session;//当前用户的 sidprivate String sid = "";//JSON解析工具private static final ObjectMapper objectMapper = new ObjectMapper();/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {this.session = session;this.sid = sid;webSocketSet.add(this); //加入集合addOnlineCount(); //在线数加1try {// 发送 JSON 格式的消息String successMessage = "{\"message\": \"conn_success\"}";sendMessage(successMessage);log.info("有新窗口开始监听: " + sid + ", 当前在线人数为: " + getOnlineCount());} catch (IOException e) {log.error("WebSocket IO Exception", e);}}/*** 连接关闭调用的方法*/@OnClosepublic void onClose() {webSocketSet.remove(this); //从集合中删除subOnlineCount(); //在线数减1log.info("释放的 sid 为:" + sid);log.info("有一连接关闭!当前在线人数为 " + getOnlineCount());}/*** 收到客户端消息后调用的方法*/@OnMessagepublic void onMessage(String message, Session session) {log.info("收到来自窗口 " + sid + " 的信息: " + message);String targetSid;String msgContent;try {//解析接收到的 JSON 消息Map<String, String> messageMap = objectMapper.readValue(message, Map.class);targetSid = messageMap.get("targetSid");msgContent = messageMap.get("message");} catch (IOException e) {log.error("消息解析失败", e);return;}//判断目标用户是否为管理员且管理员不在线boolean isTargetAdmin = isAdmin(targetSid);if (isTargetAdmin && !isAdminOnline()) {log.info("管理员不在线,调用文心一言进行自动回复");String wenxinResponse = getWenxinResponse(msgContent);if (wenxinResponse != null) {log.info("文心一言返回的回复: " + wenxinResponse);Map<String, String> responseMap = new HashMap<>();responseMap.put("sourceSid", sid);responseMap.put("message", wenxinResponse);String jsonResponse;try {//将回复消息转换为 JSON 格式jsonResponse = objectMapper.writeValueAsString(responseMap);} catch (IOException e) {log.error("JSON 序列化失败", e);return;}//发送自动回复消息给发送方try {sendMessage(jsonResponse);log.info("发送自动回复消息: " + jsonResponse);} catch (IOException e) {log.error("消息发送失败", e);}return;}}//如果管理员在线或者不是管理员,按照正常逻辑发送消息Map<String, String> responseMap = new HashMap<>();responseMap.put("sourceSid", sid);responseMap.put("message", msgContent);String jsonResponse;try {//将消息转换为 JSON 格式jsonResponse = objectMapper.writeValueAsString(responseMap);} catch (IOException e) {log.error("JSON 序列化失败", e);return;}//将消息发送给目标 sidfor (WebSocketServer item : webSocketSet) {try {if (targetSid.equals(item.sid)) {item.sendMessage(jsonResponse);break;}} catch (IOException e) {log.error("消息发送失败", e);}}}/*** 判断是否是管理员*/private boolean isAdmin(String sid) {return "admin".equals(sid);}/*** 发生错误时调用的方法*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("发生错误", error);}/*** 实现服务器主动推送*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 群发自定义消息*/public static void sendInfo(String message, @PathParam("sid") String sid) throws IOException {log.info("推送消息到窗口 " + sid + ",推送内容: " + message);for (WebSocketServer item : webSocketSet) {try {if (sid == null) {item.sendMessage(message); //推送给所有人} else if (item.sid.equals(sid)) {item.sendMessage(message); //推送给指定 sid}} catch (IOException e) {log.error("推送消息失败", e);}}}public static synchronized int getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketServer.onlineCount++;}public static synchronized void subOnlineCount() {WebSocketServer.onlineCount--;}public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() {return webSocketSet;}public String getSid() {return this.sid;}private boolean isAdminOnline() {for (WebSocketServer item : webSocketSet) {if (isAdmin(item.sid)) {log.info("管理员已在线: " + item.sid);return true;}}log.info("管理员不在线");return false;}private String getWenxinResponse(String query) {try {//调用WenXinYiYanUtil类的静态方法获取回复String wenxinReplyJson = WenXinYiYanUtil.getWenxinReply(query);//将文心一言回复的JSON字符串解析为JSONObjectJSONObject wenxinReplyObj = JSONObject.parseObject(wenxinReplyJson);//提取出要展示给用户的回复内容String result = wenxinReplyObj.getString("result");return result;} catch (IOException | JSONException e) {log.error("调用文心一言失败", e);return null;}}}

 作用:使用 @ServerEndpoint 注解声明了 WebSocket 端点,指定了路径 /api/websocket/{sid},其中 {sid} 是一个动态路径参数,代表每个连接的唯一标识。

WebSocket 事件处理:

@OnOpen: 连接建立时调用的方法。每当一个新的 WebSocket 连接建立时,执行此方法,并将当前连接的 sid 和 session 保存到 webSocketSet 中,同时增加在线人数。
发送一个 JSON 格式的 "conn_success" 消息给客户端,表示连接成功。
@OnClose: 连接关闭时调用的方法。每当一个 WebSocket 连接关闭时,执行此方法,并从 webSocketSet 中移除该连接,同时减少在线人数。
@OnMessage: 收到客户端消息时调用的方法。该方法解析接收到的消息并根据目标用户的 sid 将消息发送给目标客户端。如果目标用户是管理员且管理员不在线,系统会通过 WenXinYiYanUtil 获取自动回复,进行自动响应。
@OnError: 发生错误时调用的方法,日志记录错误信息。
消息发送:

sendMessage: 该方法用于向客户端发送消息,利用 session.getBasicRemote().sendText() 实现。
sendInfo: 该方法用于群发消息,向所有连接的客户端发送自定义的消息。可以根据传入的 sid 进行定向推送。

二、 调用文心一言大模型API

要与文心一言大模型API进行集成,你需要访问其官方文档并获取API密钥,通常通过HTTP请求与API交互。

步骤:
1.在百度智能云开放平台中注册成为开发者

官网:全面解读 百度智能云 API 服务商 -- 服务商门户 -- 幂简集成

2.进入百度智能云官网进行登录,点击立即体验

3.进入千帆ModelBuilder,点击左侧的应用接入并且点击创建应用

4.在页面上的应用名称输入自己想要的应用名称和应用描述

5.获取对应的API Key 和 Secret Key

6.配置文心一言ERNIE4.0 API并调用,选择一个想要使用的模型

7.添加依赖

<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.3</version>
</dependency>


8.我们可以参考官方提供的示例代码,编写自己的程序

代码实例

下面这段代码是一个 Java 示例程序,使用 OkHttp 库向文心一言 API 发送请求,并通过用户提供的输入获取模型的响应。 

import okhttp3.*;
import org.json.JSONException;
import org.json.JSONObject;import java.io.*;
import java.util.concurrent.TimeUnit;class Sample {// 密钥public static final String API_KEY = "";public static final String SECRET_KEY = "";// OkHttpClient 配置,设置连接超时和读取超时static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().connectTimeout(60, TimeUnit.SECONDS)  // 设置连接超时为60秒.readTimeout(60, TimeUnit.SECONDS)     // 设置读取超时为60秒.build();public static void main(String[] args) throws IOException, JSONException {// 定义请求的媒体类型MediaType mediaType = MediaType.parse("application/json");// 构建请求体,消息内容包含了用户请求RequestBody body = RequestBody.create(mediaType, "{\"messages\":["+ "{\"role\":\"user\",\"content\":\"北京的天气是什么\"}" // 用户输入的消息内容+ "],"+ "\"temperature\":0.95,"   // 设置温度参数,控制模型的输出多样性+ "\"top_p\":0.8,"          // 设置 top_p 参数,控制模型输出的多样性+ "\"penalty_score\":1,"    // 设置惩罚得分参数,影响模型对重复内容的惩罚+ "\"enable_system_memory\":false," // 禁用系统内存+ "\"disable_search\":false,"        // 禁用搜索功能+ "\"enable_citation\":false}");    // 禁用引用功能// 构建 HTTP 请求Request request = new Request.Builder().url("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + getAccessToken()).method("POST", body)  // 设置请求方法为 POST.addHeader("Content-Type", "application/json")  // 设置请求头,表示发送的内容是 JSON 格式.build();// 发送请求并获取响应try (Response response = HTTP_CLIENT.newCall(request).execute()) {// 输出响应内容,打印接口返回的数据System.out.println(response.body().string());} catch (IOException e) {// 捕获 IO 异常(如网络错误、超时等),并打印异常信息e.printStackTrace();}}/*** 从用户的 API 密钥(AK、SK)生成鉴权签名(Access Token)** @return 鉴权签名(Access Token)* @throws IOException 如果发生 I/O 异常* @throws JSONException 如果发生 JSON 解析异常*/static String getAccessToken() throws IOException, JSONException {// 设置请求体的媒体类型为 x-www-form-urlencodedMediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");// 创建请求体,包含 API 的 client_id 和 client_secretRequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY+ "&client_secret=" + SECRET_KEY);// 构建请求,使用 POST 方法获取 Access TokenRequest request = new Request.Builder().url("https://aip.baidubce.com/oauth/2.0/token") // 请求 URL,获取 Access Token.method("POST", body)  // 使用 POST 方法发送请求.addHeader("Content-Type", "application/x-www-form-urlencoded") // 请求头.build();// 发送请求并获取响应try (Response response = HTTP_CLIENT.newCall(request).execute()) {// 从响应中解析出 Access Tokenreturn new JSONObject(response.body().string()).getString("access_token");}}
}

解释如下:

这段代码是一个 Java 示例程序,使用 OkHttp 库向文心一言 API 发送请求,并通过用户提供的输入获取模型的响应。具体来说,它包括了两个主要部分:

  • 获取访问令牌(Access Token):通过 API_KEYSECRET_KEY 获取用于访问文心一言 API 的 Access Token。
  • 发送请求到文心一言 API:使用获取到的 Access Token,向文心一言 API 发送一个包含用户输入的消息,请求模型生成响应。
具体步骤:

1. 获取 Access Token

getAccessToken() 方法的作用是通过 API_KEYSECRET_KEY 获取一个 Access Token。这个令牌是调用文心一言 API 所必需的。步骤如下:

static String getAccessToken() throws IOException, JSONException {// 设置请求体的媒体类型为 x-www-form-urlencodedMediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");// 创建请求体,包含 API 的 client_id 和 client_secretRequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY+ "&client_secret=" + SECRET_KEY);// 构建请求,使用 POST 方法获取 Access TokenRequest request = new Request.Builder().url("https://aip.baidubce.com/oauth/2.0/token") // 请求 URL,获取 Access Token.method("POST", body)  // 使用 POST 方法发送请求.addHeader("Content-Type", "application/x-www-form-urlencoded") // 请求头.build();// 发送请求并获取响应try (Response response = HTTP_CLIENT.newCall(request).execute()) {// 从响应中解析出 Access Tokenreturn new JSONObject(response.body().string()).getString("access_token");}
}
  • 请求体grant_type=client_credentials&client_id=API_KEY&client_secret=SECRET_KEY,请求体中的 client_idclient_secret 是用来鉴权的。
  • 响应解析:在获取到响应后,程序解析出其中的 access_token,这是后续访问文心一言 API 的凭证。

2. 发送请求到文心一言 API

接下来的部分是构建并发送请求到文心一言的聊天 API。

RequestBody body = RequestBody.create(mediaType, "{\"messages\":[" + "{\"role\":\"user\",\"content\":\"北京的天气是什么\"}" // 用户输入的消息内容+ "],"+ "\"temperature\":0.95,"   // 设置温度参数,控制模型的输出多样性+ "\"top_p\":0.8,"          // 设置 top_p 参数,控制模型输出的多样性+ "\"penalty_score\":1,"    // 设置惩罚得分参数,影响模型对重复内容的惩罚+ "\"enable_system_memory\":false," // 禁用系统内存+ "\"disable_search\":false,"        // 禁用搜索功能+ "\"enable_citation\":false}");    // 禁用引用功能
  • 请求体:请求体是一个 JSON 字符串,其中包含了用户的消息(例如:"北京的天气是什么"),以及一些参数,如 temperature, top_p 等,控制生成的回答的多样性和随机性。
    • "messages": 包含一个消息对象,其中 "role""user",表示消息来源是用户,"content" 是用户的实际问题。
    • "temperature": 控制模型生成内容的多样性,值越高,生成的内容越随机,通常在 0 到 1 之间。0.95 是一个比较高的值,表示会有更多的随机性。
    • "top_p": 也是控制生成内容多样性的参数,决定了模型从哪些概率分布中选择内容。0.8 表示在一个给定的概率质量上选取词汇。
    • "penalty_score": 惩罚得分,影响模型对重复内容的惩罚,值越高,模型更倾向于避免重复。
    • "enable_system_memory", "disable_search", "enable_citation": 这些选项是与文心一言 API 功能相关的配置项,用于启用或禁用某些功能。
Request request = new Request.Builder().url("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + getAccessToken()).method("POST", body)  // 设置请求方法为 POST.addHeader("Content-Type", "application/json")  // 设置请求头,表示发送的内容是 JSON 格式.build();
  • 请求 URL:请求的 URL 中包含了获取到的 access_token,它会用来验证请求的合法性。
  • 请求方法POST,表示发送的数据(如用户消息)需要上传到服务器。
  • 请求头Content-Type 设置为 application/json,表示请求体的格式是 JSON。
try (Response response = HTTP_CLIENT.newCall(request).execute()) {// 输出响应内容,打印接口返回的数据System.out.println(response.body().string());
} catch (IOException e) {// 捕获 IO 异常(如网络错误、超时等),并打印异常信息e.printStackTrace();
}
  • 发送请求:调用 HTTP_CLIENT.newCall(request).execute() 发送请求,并获取服务器的响应。
  • 打印响应:如果请求成功,打印返回的响应内容,通常是文心一言的回答。
3. 整体流程
  1. 程序启动后,调用 getAccessToken() 方法获取 Access Token。
  2. 使用获取到的 Access Token,构建一个带有用户消息的请求,发送到文心一言 API。
  3. 接收文心一言的响应(比如对用户问题的回答),并打印在控制台。
4. 需要的外部依赖
  • OkHttp:用于发送 HTTP 请求,处理网络连接。
  • JSON库:用于解析 JSON 数据,这里使用的是 org.json 库(JSONObject 类)。

我们也可以使用RestTemplateWebClient来调用文心一言API,具体怎么使用大家可以自行探索。

三、 前端WebSocket连接

在前端,你可以使用JavaScript的WebSocket API来连接后端WebSocket服务并进行通信。

前端代码示例:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>实时聊天</title>
</head>
<body><div><input type="text" id="inputMessage" placeholder="请输入消息"><button onclick="sendMessage()">发送</button></div><div id="chatBox"></div><script>// 创建WebSocket连接const socket = new WebSocket("ws://localhost:8080/api/websocket/+sid");// 监听消息socket.onmessage = function(event) {const chatBox = document.getElementById("chatBox");const message = event.data;chatBox.innerHTML += `<p>机器人: ${message}</p>`;};// 发送消息到WebSocketfunction sendMessage() {const inputMessage = document.getElementById("inputMessage").value;socket.send(inputMessage);const chatBox = document.getElementById("chatBox");chatBox.innerHTML += `<p>你: ${inputMessage}</p>`;}</script>
</body>
</html>

参考文章:

实现 WebSocket 接入文心一言_apipost websocket-CSDN博客

文心一言ERNIE-Bot 4.0模型流式和非流式API调用(SpringBoot+OkHttp3+SSE+WebSocket) - autunomy - 博客园

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

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

相关文章

技术速递|.NET 9 中的 OpenAPI 文档生成

作者&#xff1a;Mike Kistler 排版&#xff1a;Alan Wang .NET 9 中的 ASP.NET Core 通过引入全新的对 OpenAPI 文档生成功能的内置支持&#xff0c;简化了为 API 端点创建 OpenAPI 文档的过程。这项新功能旨在简化开发工作流程&#xff0c;并改善 OpenAPI 定义在 ASP.NET 应用…

StarRocks BE源码编译、CLion高亮跳转方法

阅读SR BE源码时&#xff0c;很多类的引用位置爆红找不到&#xff0c;或无法跳转过去&#xff0c;而自己的Linux机器往往缺乏各种C依赖库&#xff0c;配置安装比较麻烦&#xff0c;因此总体的思路是通过CLion远程连接SR社区已经安装完各种依赖库的Docker容器&#xff0c;进行编…

STM32 按键密码系统的实现

本次基于STM32F407开发板&#xff0c;来实现密码系统&#xff0c;输入四位密码&#xff0c;密码正确时LED1亮&#xff0c;密码错误时四个LED灯双闪。 LED双闪代码 简单的逻辑&#xff0c;让四个LED灯先亮然后再延时一会LED灯灭&#xff0c;循环4此实现双闪的效果。 按键密码的…

linux常用加固方式

目录 一.系统加固 二.ssh加固 三.换个隐蔽的端口 四.防火墙配置 五.用户权限管理 六.暴力破解防护 七.病毒防护 八.磁盘加密 九.双因素认证2FA 十.日志监控 十一.精简服务 一.系统加固 第一步&#xff1a;打好系统补丁 sudo apt update && sudo apt upgra…

hadoop==docker desktop搭建hadoop

hdfs map readuce yarn https://medium.com/guillermovc/setting-up-hadoop-with-docker-and-using-mapreduce-framework-c1cd125d4f7b 清理资源 docker-compose down docker system prune -f

【Elasticsearch 基础入门】Centos7下Elasticsearch 7.x安装与配置(单机)

Elasticsearch系列文章目录 【Elasticsearch 基础入门】一文带你了解Elasticsearch&#xff01;&#xff01;&#xff01;【Elasticsearch 基础入门】Centos7下Elasticsearch 7.x安装与配置&#xff08;单机&#xff09; 目录 Elasticsearch系列文章目录前言单机模式1. 安装 J…

Fullcalendar @fullcalendar/react 样式错乱丢失问题和导致页面卡顿崩溃问题

问题描述&#xff1a; 我使用 fullcalendar的react版本时&#xff0c;出现了一个诡异的问题&#xff0c;当我切换到 一个iframe页面时&#xff08;整个页面是一个iframe嵌入的&#xff09;&#xff0c;再切换回来日历的样式丢失了&#xff01;不仅丢失了样式还导致页面崩溃了&…

算法12(力扣739)-每日温度

1、问题 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 2、示例 &#…

STM32项目分享:智能厨房安全检测系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 PCB图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; STM32智能厨房安全检测系统 &#xff08;资料分…

定时器按键tim_key模版

低优先级放在高优先级内势必是程序卡死 把高优先级放到低优先级内&#xff0c;会使程序卡死 可修改 Debuger调试方法 Pwm rcc #include "my_main.h" uint8_t led_sta0x10; char text[30]; void LED_Disp(uint8_t dsLED) {HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPI…

大模型-本地化部署调用--基于ollama+openWebUI+springBoot

大模型-本地化部署调用–基于ollamaopenWebUIspringBoot 前言 前段时间&#xff0c;啊&#xff0c;可能不是前段时间&#xff0c;过去的2024年吧&#xff0c;大模型这块的内容也是非常火的&#xff0c;各家巨头也开始卷大模型的研发。那么本人呢也在过去的一年中也是用到了一…

Vue组件开发-使用 html2canvas 和 jspdf 库实现PDF文件导出 设置页面大小及方向

在 Vue 项目中实现导出 PDF 文件、调整文件页面大小和页面方向的功能&#xff0c;使用 html2canvas 将 HTML 内容转换为图片&#xff0c;再使用 jspdf 把图片添加到 PDF 文件中。以下是详细的实现步骤和代码示例&#xff1a; 步骤 1&#xff1a;安装依赖 首先&#xff0c;在项…

RV1126+FFMPEG推流项目源码

源码在我的gitee上面&#xff0c;感兴趣的可以自行了解 nullhttps://gitee.com/x-lan/rv126-ffmpeg-streaming-projecthttps://gitee.com/x-lan/rv126-ffmpeg-streaming-project

宏_wps_宏修改word中所有excel表格的格式_设置字体对齐格式_删除空行等

需求&#xff1a; 将word中所有excel表格的格式进行统一化&#xff0c;修改其中的数字类型为“宋体&#xff0c; 五号&#xff0c;右对齐&#xff0c; 不加粗&#xff0c;不倾斜”&#xff0c;其中的中文为“宋体&#xff0c; 五号&#xff0c; 不加粗&#xff0c;不倾斜” 数…

ServletOutputStream failed to write: Broken pipe

案发现场 问题&#xff1a; org.springframework.web.context.request.async.AsyncRequestNotUsableException: ServletOutputStream failed to write: Broken pipe org.springframework.web.context.request.async.AsyncRequestNotUsableException: ServletOutputStream …

CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测(Matlab完整源码和数据)

CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测&#xff08;Matlab完整源码和数据&#xff09; 目录 CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测&#xff08;Matlab完整源码和数据&#xff09;预测效果基本介绍 CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测一…

14-6-2C++STL的list

(一&#xff09;list对象的带参数构造 1.list&#xff08;elem);//构造函数将n个elem拷贝给本身 #include <iostream> #include <list> using namespace std; int main() { list<int> lst(3,7); list<int>::iterator it; for(itlst.begi…

Docker 系列之 docker-compose 容器编排详解

文章目录 前言一、Docker-compose简介二、Docker-compose 的安装三、Docker-compose卸载四、Docker-compose常用命令4.1 Docker-compose命令格式4.2 docker-compose up4.3 docker-compose ps4.4 docker-compose stop4.5 docker-compose -h4.6 docker-compose down4.7 docker-co…

React第二十五章(受控组件/非受控组件)

React 受控组件理解和应用 React 受控组件 受控组件一般是指表单元素&#xff0c;表单的数据由React的 State 管理&#xff0c;更新数据时&#xff0c;需要手动调用setState()方法&#xff0c;更新数据。因为React没有类似于Vue的v-model&#xff0c;所以需要自己实现绑定事件…