API版本:Spring Boot 整合讯飞星火3.5通过接口Api接口实现聊天功能(首发)复制粘贴即可使用,后续更新WebSocket实现聊天功能_讯飞星火web聊天-CSDN博客https://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)https://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",
}
备注:具体问题根据自己的情况修改