|
@@ -22,6 +22,7 @@ import okhttp3.sse.EventSources;
|
|
|
import org.apache.commons.io.FileUtils;
|
|
import org.apache.commons.io.FileUtils;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.StringUtils;
|
|
import org.springframework.util.StringUtils;
|
|
@@ -35,6 +36,8 @@ import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.temporal.ChronoUnit;
|
|
import java.time.temporal.ChronoUnit;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
|
+import java.util.concurrent.Executors;
|
|
|
|
|
+import java.util.concurrent.ScheduledExecutorService;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
@@ -78,6 +81,9 @@ public class BigModelServiceImpl implements IBigModelService
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private FileInfoMapper fileInfoMapper;
|
|
private FileInfoMapper fileInfoMapper;
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ public RedisTemplate redisTemplate;
|
|
|
|
|
+
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public List<BmMediaReplacement> selectMediaList(BmMediaReplacement mData) {
|
|
public List<BmMediaReplacement> selectMediaList(BmMediaReplacement mData) {
|
|
@@ -117,6 +123,34 @@ public class BigModelServiceImpl implements IBigModelService
|
|
|
@Override
|
|
@Override
|
|
|
public SseEmitter sseInvoke(SseParams sseParams) {
|
|
public SseEmitter sseInvoke(SseParams sseParams) {
|
|
|
SseEmitter sseEmitter = new SseEmitter(0L);
|
|
SseEmitter sseEmitter = new SseEmitter(0L);
|
|
|
|
|
+
|
|
|
|
|
+ // 生成唯一会话ID(可从请求参数获取或自动生成)
|
|
|
|
|
+ String sessionId = UUID.randomUUID().toString();
|
|
|
|
|
+
|
|
|
|
|
+ redisTemplate.opsForValue().set(
|
|
|
|
|
+ "sse:terminate:" + sessionId,
|
|
|
|
|
+ "false",
|
|
|
|
|
+ 1, TimeUnit.HOURS
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // 定时检查终止信号(每2秒检查一次)
|
|
|
|
|
+ ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
|
|
|
|
|
+ scheduler.scheduleAtFixedRate(() -> {
|
|
|
|
|
+ try {
|
|
|
|
|
+ String flag = redisTemplate.opsForValue()
|
|
|
|
|
+ .get("sse:terminate:" + sessionId).toString();
|
|
|
|
|
+
|
|
|
|
|
+ if ("true".equals(flag)) {
|
|
|
|
|
+ // 主动终止流程
|
|
|
|
|
+ sseEmitter.complete();
|
|
|
|
|
+ scheduler.shutdown();
|
|
|
|
|
+ redisTemplate.delete("sse:terminate:" + sessionId);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("终止检查失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 0, 2, TimeUnit.SECONDS);
|
|
|
|
|
+
|
|
|
String url = bigModelConfig.getBaseurl() + bigModelConfig.getSse().replace("{id}",sseParams.getAppId());
|
|
String url = bigModelConfig.getBaseurl() + bigModelConfig.getSse().replace("{id}",sseParams.getAppId());
|
|
|
JSONObject json = new JSONObject();
|
|
JSONObject json = new JSONObject();
|
|
|
List<PromptObject> list = sseParams.getPrompt();
|
|
List<PromptObject> list = sseParams.getPrompt();
|
|
@@ -152,6 +186,11 @@ public class BigModelServiceImpl implements IBigModelService
|
|
|
@Override
|
|
@Override
|
|
|
public void onEvent(@NotNull EventSource eventSource, String id, String type, @NotNull String data) {
|
|
public void onEvent(@NotNull EventSource eventSource, String id, String type, @NotNull String data) {
|
|
|
try {
|
|
try {
|
|
|
|
|
+ // 检查Redis终止标记(双重保障)
|
|
|
|
|
+ if ("true".equals(redisTemplate.opsForValue().get("sse:terminate:" + sessionId))) {
|
|
|
|
|
+ eventSource.cancel();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
String newData = data.substring(preData.length());
|
|
String newData = data.substring(preData.length());
|
|
|
preData = data;
|
|
preData = data;
|
|
|
if(newData.indexOf(START_SIGN) > -1 || symbolData.length() > 0) {
|
|
if(newData.indexOf(START_SIGN) > -1 || symbolData.length() > 0) {
|
|
@@ -203,6 +242,7 @@ public class BigModelServiceImpl implements IBigModelService
|
|
|
//sseEmitter.send(json);
|
|
//sseEmitter.send(json);
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
log.error("智谱 推送数据失败", e);
|
|
log.error("智谱 推送数据失败", e);
|
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
@Override
|
|
@Override
|
|
@@ -211,14 +251,22 @@ public class BigModelServiceImpl implements IBigModelService
|
|
|
sseEmitter.completeWithError(t);
|
|
sseEmitter.completeWithError(t);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void send(SseEmitter sseEmitter, Object obj) {
|
|
|
|
|
|
|
+ private void send(SseEmitter sseEmitter, Object obj) throws IOException {
|
|
|
try {
|
|
try {
|
|
|
sseEmitter.send(obj);
|
|
sseEmitter.send(obj);
|
|
|
} catch (IOException e) {
|
|
} catch (IOException e) {
|
|
|
log.error("智谱 推送数据失败", e);
|
|
log.error("智谱 推送数据失败", e);
|
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+ // 资源清理
|
|
|
|
|
+ sseEmitter.onCompletion(() -> {
|
|
|
|
|
+ scheduler.shutdown();
|
|
|
|
|
+ redisTemplate.delete("sse:terminate:" + sessionId);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
OkHttpClient client = buildOkHttpClient();
|
|
OkHttpClient client = buildOkHttpClient();
|
|
|
EventSource.Factory factory = EventSources.createFactory(client);
|
|
EventSource.Factory factory = EventSources.createFactory(client);
|
|
|
factory.newEventSource(request, listener);
|
|
factory.newEventSource(request, listener);
|