解决配置动态刷新问题、修改部分配置

This commit is contained in:
wulin 2023-10-25 21:47:41 +08:00
parent 00ce4c3731
commit 851b8ec364
19 changed files with 169 additions and 97 deletions

View File

@ -6,7 +6,7 @@ import java.util.List;
public interface INlp {
//获取一条语句的分词结果
Mono<Nlp> geSingletNlp(String value);
Mono<Nlp> geSingletNlp(String value, String type);
//获取多条语句的分词结果
Mono<List<Nlp>> getNlp(List<String> values);
Mono<List<Nlp>> getNlp(List<String> values, String type);
}

View File

@ -18,10 +18,8 @@ import java.util.ArrayList;
@Service
@Slf4j
public class AudioService {
@Value("${tts.url:}")
@Value("${nlp.tts.url:}")
private String url;
@Value("${tts.downurl:}")
private String downurl;
public Mono<String> getAudioUrl(String v){
AudioRequest request = new AudioRequest();
request.setData(new ArrayList<>(4));
@ -33,7 +31,7 @@ public class AudioService {
return WebClientUtils.post(url, (JSONObject)JSONObject.toJSON(request)).flatMap(jsonObject -> {
JSONArray array = jsonObject.getJSONArray("data");
jsonObject = array.getJSONObject(1);
String m = jsonObject.getString("name").replaceAll("/data/wzg/vits_results", downurl);
String m = jsonObject.getString("name");//.replaceAll("/data/wzg/vits_results", downurl);
return Mono.just(m);
});
}

View File

@ -34,13 +34,11 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@Service
@Slf4j
public class LacNlpService implements INlp {
@Value("${lac.hub.url:}")
@Value("${nlp.lac.huburl:}")
private String hubUrl;
@Value("${lac.suanfa.url:}")
@Value("${nlp.lac.suanfaurl:}")
private String suanfaUrl;
@Value("${lac.type:}")
private String lacType;
private Mono<JSONObject> getNlpFromHubLac(HubLacRequest request){
return WebClientUtils.post(hubUrl, (JSONObject) JSONObject.toJSON(request)).map(
@ -65,8 +63,8 @@ public class LacNlpService implements INlp {
}
@Override
public Mono<Nlp> geSingletNlp(String value) {
if(!lacType.equals("suanfa")){
public Mono<Nlp> geSingletNlp(String value, String type) {
if(!type.equals("suanfa")){
return getHubFaLac(value);
}
return getSuanFaLac(value);
@ -113,7 +111,7 @@ public class LacNlpService implements INlp {
}
@Override
public Mono<List<Nlp>> getNlp(List<String> values) {
public Mono<List<Nlp>> getNlp(List<String> values, String type) {
HubLacRequest request = new HubLacRequest();
request.setText(values);
Mono<JSONObject> mono = getNlpFromHubLac(request);

View File

@ -37,7 +37,7 @@ public class NlpService {
*/
private static Integer MAX_COUT = 2000;
public Mono<Actions> getActionWithLacSingle(Long userId, String text){
public Mono<Actions> getActionWithLacSingle(Long userId, String text, String type){
if(userId == null) {
userId = 0L;
}
@ -100,7 +100,7 @@ public class NlpService {
}*/
}
}
return getActions(pText, text, includs, systemIncluds);
return getActions(pText, text, includs, systemIncluds, type);
});
@ -108,8 +108,9 @@ public class NlpService {
public Mono<Actions> getActions(String text, String recordText,
List<DeviceUserBindEntity> includs,
List<SystemTalkAnswerConfigEntity> commands) {
return liguoNlpService.geSingletNlp(text).map(nlp -> {
List<SystemTalkAnswerConfigEntity> commands,
String type) {
return liguoNlpService.geSingletNlp(text, type).map(nlp -> {
Actions actions = new Actions();
actions.setActions(new ArrayList<>());
Action action = new Action();

View File

@ -1,5 +1,8 @@
spring:
cloud:
inetutils:
preferredNetworks:
- 192.168 #注册到nacos中心优先匹配的IP
gateway:
routes:
- id: qiuguo-iot-box-user-api

View File

@ -1,9 +1,6 @@
server:
port: 8080
port: 8081
spring:
profiles:
# 环境配置
active: test
application:
name: qiuguo-iot-gateway

View File

@ -1,5 +1,8 @@
spring:
cloud:
inetutils:
preferredNetworks:
- 192.168 #注册到nacos中心优先匹配的IP
# config:
# # 如果本地配置优先级高,那么 override-none 设置为 true包括系统环境变量、本地配置文件等配置
# override-none: true

View File

@ -1,5 +1,8 @@
spring:
cloud:
inetutils:
preferredNetworks:
- 192.168 #注册到nacos中心优先匹配的IP
# config:
# # 如果本地配置优先级高,那么 override-none 设置为 true包括系统环境变量、本地配置文件等配置
# override-none: true

View File

@ -81,11 +81,11 @@
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine -->
<!-- nacos 动态配置用到,注意版本号 -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
<version>${caffeine.version}</version>
</dependency>
<dependency>

View File

@ -4,6 +4,7 @@ import com.tuya.connector.spring.annotations.ConnectorScan;
import org.hswebframework.web.crud.annotation.EnableEasyormRepository;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

View File

@ -31,6 +31,9 @@ import org.springframework.boot.SpringApplication;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.Queue;
@Slf4j
public abstract class ActionCommand {
@ -81,6 +84,17 @@ public abstract class ActionCommand {
});
}
public void sendMessage(BaseSession baseSession, String message, Integer type) {}
protected void setQueueMessage(BaseSession baseSession, Queue<String> queue, Integer type){
if(queue == null){
queue = new LinkedList<>();
}
StringBuilder sb = new StringBuilder();
String message = queue.poll();
baseWebSocketService.sendMoreMsg(baseSession, sb, message, type);
}
protected Mono<Void> toQianWen(Action action, BaseSession baseSession, Integer type){
log.info("调用千问{}", action.getAsk());
TongYiCommunicationRest tongYiCommunicationRest = new TongYiCommunicationRest();
@ -92,29 +106,24 @@ public abstract class ActionCommand {
}else{
tongYiCommunicationRest.setOnlyId(baseSession.getUserId().toString());
}
StringBuilder sb = new StringBuilder();
Queue<String> queue = new LinkedList<String>();
return qwenService.communication(tongYiCommunicationRest, new IQianWen<String>() {
@Override
public void sendMessage(String message) {
//通知到客户端
MDC.put(Log4Constans.PRINT_LOG_ID, baseSession.getLogId());
if (tongYiCommunicationRest.getRequestId().equals(baseSession.getRequestId())) {
//测试后决定是否需要
baseWebSocketService.sendMoreMsg(baseSession, sb, message, type);
queue.add(message);
setQueueMessage(baseSession, queue, type);
return;
}
log.info("已经有新的请求不在推送到客户端SN{} userId:{}", baseSession.getSn(), baseSession.getUserId());
}
@Override
public void finish() {
log.info("千问最后调用finish");
String msg = sb.toString();
if(msg.replace(" ", "").length() > 0){
//纯空格的不推送
baseWebSocketService.normalSendMsg(baseSession, sb.toString(), type);
}
MDC.remove(Log4Constans.PRINT_LOG_ID);
}
}).flatMap(data ->{

View File

@ -0,0 +1,25 @@
package com.qiuguo.iot.box.websocket.api.config.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* Xss配置.
*
* @author yangning
* @since 2023/4/7 18:31
*/
@Data
@Component
@RefreshScope
@ConfigurationProperties(prefix = "nlp.lac")
public class LacProperties {
/**
* 调用LAC类型
*/
private String type;
}

View File

@ -0,0 +1,26 @@
package com.qiuguo.iot.box.websocket.api.config.properties;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* Xss配置.
*
* @author yangning
* @since 2023/4/7 18:31
*/
@Data
@Component
@RefreshScope
public class TtsProperties {
/**
* 调用LAC类型
*/
@Value("${nlp.tts.suanfa}")
private Boolean suanfa;
}

View File

@ -78,9 +78,9 @@ public class WebsocketController {
}
@GetMapping("/test/nlp")
public Mono<Nlp> nlp(@RequestParam String value) {
public Mono<Nlp> nlp(@RequestParam String value, @RequestParam String type) {
return lacNlpService.geSingletNlp(value);
return lacNlpService.geSingletNlp(value, type);
}

View File

@ -6,9 +6,8 @@ import com.qiuguo.iot.base.constans.HttpHeaderConstans;
import com.qiuguo.iot.base.constans.RedisConstans;
import com.qiuguo.iot.base.enums.*;
import com.qiuguo.iot.base.model.UserDeviceInfoModel;
import com.qiuguo.iot.base.utils.Md5Utils;
import com.qiuguo.iot.base.utils.StringUtils;
import com.qiuguo.iot.box.websocket.api.command.ActionCommand;
import com.qiuguo.iot.box.websocket.api.config.properties.LacProperties;
import com.qiuguo.iot.box.websocket.api.domain.BaseSession;
import com.qiuguo.iot.box.websocket.api.domain.box.BoxSession;
import com.qiuguo.iot.box.websocket.api.domain.box.BoxTalkMessage;
@ -17,7 +16,6 @@ import com.qiuguo.iot.box.websocket.api.filter.LogWebFilter;
import com.qiuguo.iot.box.websocket.api.service.BaseWebSocketService;
import com.qiuguo.iot.data.entity.device.DeviceInfoEntity;
import com.qiuguo.iot.data.entity.device.DeviceUserBindEntity;
import com.qiuguo.iot.data.request.device.DeviceInfoRequest;
import com.qiuguo.iot.data.request.device.DeviceUserBindRequest;
import com.qiuguo.iot.data.service.device.DeviceInfoService;
import com.qiuguo.iot.data.service.device.DeviceUserBindService;
@ -62,6 +60,9 @@ public class BoxWebSocketHandler implements WebSocketHandler {
@Resource
private BaseWebSocketService baseWebSocketService;
@Resource
private LacProperties lacProperties;
@Override
public Mono<Void> handle(WebSocketSession session) {
@ -145,7 +146,8 @@ public class BoxWebSocketHandler implements WebSocketHandler {
log.info("收到SN:{},消息:{}", boxTalkMessage.getSn(), boxTalkMessage.getMessage());
return nlpService.getActionWithLacSingle(
boxSession.getUserId(),
boxTalkMessage.getMessage()
boxTalkMessage.getMessage(),
lacProperties.getType()
).defaultIfEmpty(new Actions()).flatMap(actions -> {
boxSession.setRequestId(boxSession.getRequestId() + 1);
return ActionCommand.processAction(actions, boxSession);

View File

@ -9,6 +9,7 @@ import com.qiuguo.iot.base.enums.ResponeEnum;
import com.qiuguo.iot.base.enums.YesNo;
import com.qiuguo.iot.base.utils.WebClientUtils;
import com.qiuguo.iot.box.websocket.api.command.ActionCommand;
import com.qiuguo.iot.box.websocket.api.config.properties.LacProperties;
import com.qiuguo.iot.box.websocket.api.domain.user.UserSession;
import com.qiuguo.iot.box.websocket.api.domain.user.UserTalkMessage;
import com.qiuguo.iot.box.websocket.api.filter.LogMdcConfiguration;
@ -57,6 +58,9 @@ public class CustomerWebSocketHandler implements WebSocketHandler {
@Resource
private BaseWebSocketService baseWebSocketService;
@Resource
private LacProperties lacProperties;
@Override
public Mono<Void> handle(WebSocketSession session) {
@ -119,7 +123,8 @@ public class CustomerWebSocketHandler implements WebSocketHandler {
log.info("收到用户userId:{},消息:{}", userTalkMessage.getUserId(), userTalkMessage.getMessage());
return nlpService.getActionWithLacSingle(
userSession.getUserId(),
userTalkMessage.getMessage()
userTalkMessage.getMessage(),
lacProperties.getType()
).defaultIfEmpty(new Actions()).flatMap(actions -> {
//处理
userSession.setRequestId(userSession.getRequestId() + 1);

View File

@ -1,12 +1,12 @@
package com.qiuguo.iot.box.websocket.api.service;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nls.client.AccessToken;
import com.qiuguo.iot.base.constans.RedisConstans;
import com.qiuguo.iot.base.enums.AskTypeEnum;
import com.qiuguo.iot.base.enums.YesNo;
import com.qiuguo.iot.base.utils.Md5Utils;
import com.qiuguo.iot.base.utils.StringUtils;
import com.qiuguo.iot.box.websocket.api.config.properties.TtsProperties;
import com.qiuguo.iot.box.websocket.api.domain.BaseMessageResp;
import com.qiuguo.iot.box.websocket.api.domain.BaseSession;
import com.qiuguo.iot.box.websocket.api.domain.box.BoxSession;
@ -14,7 +14,6 @@ import com.qiuguo.iot.box.websocket.api.domain.box.resp.BoxMessageResp;
import com.qiuguo.iot.box.websocket.api.domain.user.UserSession;
import com.qiuguo.iot.data.entity.device.DeviceInfoEntity;
import com.qiuguo.iot.data.entity.device.DeviceUserTalkRecordEntity;
import com.qiuguo.iot.data.request.device.DeviceInfoRequest;
import com.qiuguo.iot.data.service.device.DeviceInfoService;
import com.qiuguo.iot.data.service.device.DeviceUserTalkRecordService;
import com.qiuguo.iot.third.nlp.action.Action;
@ -22,27 +21,29 @@ import com.qiuguo.iot.third.service.AudioService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;
@Service
@Slf4j
@RefreshScope
public class BaseWebSocketService {
/**
* 调用算法开关
*/
@Resource
private TtsProperties ttsProperties;
protected static ConcurrentHashMap<Long, UserSession> userGroup = new ConcurrentHashMap<>();
protected static ConcurrentHashMap<String, BoxSession> boxGroup = new ConcurrentHashMap<>();
@Value("${tts.suanfa}")
boolean ttsSuanfa;
@Resource
AudioService audioService;
@ -92,6 +93,12 @@ public class BaseWebSocketService {
return boxGroup.remove(sn);
}
/**
* 获取分段发送文字确保每次发送的都是标点符号前的文字停顿正常
* @param sb
* @param message
* @return
*/
protected String getSendStr(StringBuilder sb, String message){
String old = sb.toString() + message;
int d = old.lastIndexOf("");
@ -130,7 +137,9 @@ public class BaseWebSocketService {
}
public void sendMoreMsg(BaseSession baseSession, StringBuilder sb, String message, int type){
public void sendMoreMsg(BaseSession baseSession,
StringBuilder sb,
String message, int type){
message = getSendStr(sb, message);
if(StringUtils.isNotEmpty(message)){
normalSendMsg(baseSession, message, type, YesNo.NO.getCode());
@ -199,6 +208,32 @@ public class BaseWebSocketService {
sendMsg(baseSession, resp);
}
private String removeStringChars(String text){
text = text.replace("\n", "").replace("\t", "");
if(text.startsWith("") ||
text.startsWith("") ||
text.startsWith("") ||
text.startsWith("") ||
//text.startsWith("") ||
text.startsWith(" ")||
text.endsWith("")
){
//标点符号起始会导致合成的声音第一句话有杂音
text = text.substring(1);
}
if(text.endsWith("") ||
text.endsWith("") ||
text.endsWith("") ||
text.endsWith("") ||
//text.endsWith("") ||
text.endsWith(" ") ||
text.endsWith("")
){
text = text.substring(0, text.length() - 1);
}
return text;
}
public void sendMsg(BaseSession baseSession, BaseMessageResp baseMessageResp) {
if(baseSession instanceof BoxSession){
log.info("果box聊天记录同步到客户端");
@ -206,25 +241,9 @@ public class BaseWebSocketService {
if(userSession != null){
sendMsg(userSession, baseMessageResp);
}
if(ttsSuanfa){
String text = baseMessageResp.getText().replace("\n", "").replace("\t", "");
if(text.startsWith("") ||
text.startsWith("") ||
text.startsWith("") ||
text.startsWith("") ||
text.startsWith("") ||
text.startsWith(" ")){
//标点符号起始会导致合成的声音第一句话有杂音
text = text.substring(1);
}
if(text.endsWith("") ||
text.endsWith("") ||
text.endsWith("") ||
text.endsWith("") ||
text.endsWith("") ||
text.endsWith(" ")){
text = text.substring(0, text.length() - 1);
}
if(ttsProperties.getSuanfa()){
String text = removeStringChars(baseMessageResp.getText());
if(text.length() > ONE_MAX_TEXT){
StringBuilder builder = new StringBuilder();
sendAudioMessage(baseSession,
@ -272,7 +291,6 @@ public class BaseWebSocketService {
String message = text.substring(start, n);
int status = 0;
if(n == length){
message += "";
status = 1;
}
message = getSendStr(builder, message);
@ -301,28 +319,10 @@ public class BaseWebSocketService {
*/
protected Mono<String> sendAudioMessage(BaseSession baseSession, BoxMessageResp boxMessageResp){
if(StringUtils.isEmpty(boxMessageResp.getText())){
//不调用算法语音合成
boxMessageResp.setAudio("");
sendMsg(baseSession, JSONObject.toJSONString(boxMessageResp));
return Mono.just("");
}else if(boxMessageResp.getText().length() == 1 && (
boxMessageResp.getText().equals("")
|| boxMessageResp.getText().equals("")
|| boxMessageResp.getText().equals("")
|| boxMessageResp.getText().equals("")
|| boxMessageResp.getText().equals("")
|| boxMessageResp.getText().equals("")
|| boxMessageResp.getText().equals("")
)){
boxMessageResp.setAudio("");
sendMsg(baseSession, JSONObject.toJSONString(boxMessageResp));
return Mono.just("");
}
try {
//为了算法按顺序收到
Thread.sleep(80);
}catch (Exception e){
log.info("休眠异常{}", e);
}
return audioService.getAudioUrl(boxMessageResp.getText() + "").map(s ->{

View File

@ -1,5 +1,8 @@
spring:
cloud:
inetutils:
preferredNetworks:
- 192.168 #注册到nacos中心优先匹配的IP
# config:
# # 如果本地配置优先级高,那么 override-none 设置为 true包括系统环境变量、本地配置文件等配置
# override-none: true
@ -42,16 +45,13 @@ tianqiapi:
qiuguo:
checktoken:
url: https://qiuguo-app.pre.qiuguojihua.com/pre-api/user/user/getUser
tts:
suanfa: false
url: http://192.168.8.211:18000/run/predict #算法语音合成
downurl: http://192.168.8.211:8880 #算法语音合成后资源下载路径前缀
lac:
type: suanfa
hub:
url: http://192.168.8.175:8866/predict/lac
suanfa:
url: http://192.168.8.211:6000/qg_human/lac_word
nlp:
tts:
url: http://192.168.8.211:18000/run/predict #算法语音合成
lac:
type: suanfa
huburl: http://192.168.8.175:8866/predict/lac
suanfaurl: http://192.168.8.211:6000/qg_human/lac_word
Ali:
qianwen: 'sk-8d64677afaf6404cb83ce1910b5b2558'

View File

@ -30,6 +30,7 @@
<spring.boot.maven.plugin.version>2.7.14</spring.boot.maven.plugin.version>
<lombok.version>1.18.14</lombok.version>
<redis.boot.reactor.version>2.7.14</redis.boot.reactor.version>
<caffeine.version>2.9.3</caffeine.version>
</properties>
<dependencyManagement>
<dependencies>