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/chatappId: ####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;@Getterprivate static String hostUrl1;@Getterprivate static String appId1;@Getterprivate static String apiSecret1;@Getterprivate static String apiKey1;@PostConstructpublic void setHostUrl() {hostUrl1 = this.hostUrl;}@PostConstructpublic void setAppId() {appId1 = this.appId;}@PostConstructpublic void setApiSecret() {apiSecret1 = this.apiSecret;}@PostConstructpublic 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<>();/*** 链接成功调用的方法*/@OnOpenpublic 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) {}}/*** 链接关闭调用的方法*/@OnClosepublic void onClose() {try {webSockets.remove(this);sessionPool.remove(this.userId);logger.info("【websocket消息】连接断开,总数为:" + webSockets.size());} catch (Exception ignored) {}}/*** 收到客户端消息后调用的方法*/@OnMessagepublic void onMessage(String message) {SparkParamDto sparkParam = JSON.parseObject(message, SparkParamDto.class);if (Objects.equals(sparkParam.getType(), "spark")){getSparkApiChat(sparkParam);}}/*** 发送错误时的处理* session* error*/@OnErrorpublic 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 {// 构建鉴权urlString 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(){@Overridepublic void onOpen(WebSocket webSocket, Response response) {webSocket.send(body);}@Overridepublic 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",
}
备注:具体问题根据自己的情况修改