/// <summary> /// 将结果放入当前sessionid的语义槽 /// </summary> /// <param name="sessionId">与请求对应的sessionid</param> /// <param name="_SingleAnswers">返回的答案</param> public static void NlpControlerReceiveMsg(string sessionId, NlpAnswers _NlpAnswers) { //如果语义槽为空不再执行 if (_SemanticsDic.ContainsKey(sessionId)) { //如果当前语义槽标识位为State=0,则表示可以继续执行 if (_SemanticsDic[sessionId].State == 0) { //将结果放入当前sessionid的语义槽 _SemanticsDic[sessionId].NlpAnswers.Add(_NlpAnswers); _SemanticsDic[sessionId].Answertimes += 1; log.Info($"{_SemanticsDic[sessionId].Questions} {_SemanticsDic[sessionId].Answertimes} {_NlpAnswers.Code} 入槽内容(异步): { _NlpAnswers.Answers}"); //判断异步放入语义槽之后的数量,数量相等发送AI进行处理 if (_SemanticsDic[sessionId].Answertimes == INlps) { //把当前session状态设置1,表示全部放入完毕 _SemanticsDic[sessionId].State = 1; //返回AI处理结果 AIControler.GetAIAnswers(_SemanticsDic[sessionId], "异步"); } } else { log.Info($"异步超时入槽失败session :{sessionId},返回语义 : {_NlpAnswers.Answers}"); } } else { log.Info($"异步响应未找到session :{sessionId},返回语义 : {_NlpAnswers.Answers}"); } }
public static void AIFunction(SoundBodyRequest body) { //百度分词 BaiduNlp nlpEntity = BaiduSDK.Nlp(body.questions); //添加句子表,分词表 string talkDevice = "Talk_" + body.deviceId; //每个音响创建一个会话 long newTimestamp = DataHelper.GetTimeSpan(DateTime.Now); //句子时间戳 string newTitleid = nlpEntity.log_id.ToString(); //句子id string _Talkid = ""; string userid = RedisHelper.GetHostId(body.deviceId); //音响对应用户 body.timestamp = newTimestamp; // 时间标签(Long型) body.baidu_Items = nlpEntity.items; // 分词列表(字符串数组) string field = AIControler.Getdomain(body); //获取领域 body.field = field; //领域 int sort = 1; //会话中句子的顺序 string preTitleid = ""; //上一个句子id string questions = ""; //问题列表:(字符串数组) 音箱的会话记录 string answers = ""; //回答列表:(字符串数组) AIcontrol会话记录 //创建会话缓存 using (RedisHashService service = new RedisHashService()) { string _timestampStr = service.GetValueFromHash(talkDevice, "timestamp");//获取缓存时间戳 if (!string.IsNullOrEmpty(_timestampStr)) { long oldTimestamp = Convert.ToInt64(_timestampStr); long cha = newTimestamp - oldTimestamp; if (cha > 60) //一分钟60秒 { _Talkid = body.deviceId + "_" + DateTime.Now.ToString("yyyyMMdd-HHmmss-fff"); //超过一分钟,创建新的会话缓存 service.SetEntryInHash(talkDevice, "talkid", _Talkid); //缓存会话id } //一分钟内继续使用,不更新 else { _Talkid = service.GetValueFromHash(talkDevice, "talkid"); string sortStr = service.GetValueFromHash(talkDevice, "sort");//先获取当前顺序 if (!string.IsNullOrEmpty(sortStr)) { sort = Convert.ToInt32(sortStr); } sort++;//一分钟内顺序+1 } } else { _Talkid = body.deviceId + "_" + DateTime.Now.ToString("yyyyMMdd-HHmmss-fff"); //没有新建 service.SetEntryInHash(talkDevice, "talkid", _Talkid); //缓存会话id } preTitleid = service.GetValueFromHash(talkDevice, "titleid"); //前个句子id //每次都更新句子时间戳 service.SetEntryInHash(talkDevice, "titleid", newTitleid); //缓存新的句子id service.SetEntryInHash(talkDevice, "timestamp", newTimestamp.ToString()); //缓存新的时间戳 service.SetEntryInHash(talkDevice, "field", field); //新的领域 service.SetEntryInHash(talkDevice, "sort", sort.ToString()); //顺序 string talkstate = service.GetValueFromHash(talkDevice, "state"); //获取缓存会话模式,提前赋值 body.talkstate = talkstate; //会话模式 talkstate = "inquiry"; if (talkstate == "inquiry" || talkstate == "await") //询问,等待 { Task.Run(() => { //不用请求任何Nlu服务器,直接丢给AIControl函数Setanswer处理,返回抛给音箱 AIControler.Setanswer(body); }); } //else if(_state== "train")//训练模式 else { Task.Run(() => { //发送收到的语音到NLP管理器 NlpControler.ProcessingRequest(body); }); } //启动线程存数据库 Task.Run(() => { using (HsfDBContext hsfDBContext = new HsfDBContext()) { //句子表 sound_title sound_Title = new sound_title() { titleid = newTitleid, titletext = body.questions, timestamp = newTimestamp, preid = preTitleid, sort = sort, talkid = _Talkid, sender = body.deviceId, userid = userid, sendtype = body.sourceId, field = field, talkstate = talkstate }; hsfDBContext.sound_title.Add(sound_Title); int items_sort = 0; //分词表 foreach (var item in nlpEntity.items) { items_sort++; baidu_items baidu_Items = new baidu_items() { wordid = Guid.NewGuid().ToString(), titleid = newTitleid, byte_length = item.byte_length, byte_offset = item.byte_offset, uri = item.uri, pos = item.pos, ne = item.ne, item = item.item, basic_words = string.Join(",", item.basic_words), formal = item.formal, sort = items_sort, timestamp = newTimestamp }; hsfDBContext.baidu_items.Add(baidu_Items); } hsfDBContext.SaveChanges(); } log.Info($"保存到句子表和分词表"); }); } }
/// <summary> /// 接收到请求过来的消息,再开始发送向所有nlp多线程发送消息 /// </summary> /// <param name="session">接收客户端session</param> /// <param name="body.questions">接收消息内容</param> public static void ProcessingRequest(SoundBodyRequest body) { try { log.Info($"--------------------------开始向各个NLP发送问题: {body.questions} --------------------------"); if (body.sourceId == null) { body.sourceId = ""; } //添加当前请求到语义槽 SemanticsSlot semanticsSlot = new SemanticsSlot() { SessionId = body.sessionId, DeviceId = body.deviceId, Questions = body.questions, SourceId = body.sourceId, NlpAnswers = new List <NlpAnswers>(), Answertimes = 0, State = 0 }; //创建语义槽 _SemanticsDic.TryAdd(body.sessionId, semanticsSlot); //超时检测标识 CancellationTokenSource cts = new CancellationTokenSource(); //多线程集合 List <Task> taskList = new List <Task>(); TaskFactory taskFactory = new TaskFactory(); var type = typeof(INlp); var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(INlp)))) .ToArray(); INlps = types.Count();//语义槽应该放入个数 foreach (var v in types) { if (v.IsClass) { taskList.Add(taskFactory.StartNew(() => { try { //开始发送消息,并接收返回的语义 NlpAnswers _NlpAnswers = (Activator.CreateInstance(v) as INlp).SendMsg(body); //如果线程没有被取消,放入语义槽 if (!cts.IsCancellationRequested) { //过滤异步 if (_NlpAnswers != null) { _SemanticsDic[body.sessionId].Answertimes += 1; lock (_lock) { //过滤"" if (_NlpAnswers.Answers != "") { _SemanticsDic[body.sessionId].NlpAnswers.Add(_NlpAnswers); log.Info($"{body.questions} {_SemanticsDic[body.sessionId].Answertimes} {v.Name} 入槽内容: { _NlpAnswers.Answers.Replace("\r\n","")}"); } else { log.Info($"{body.questions} {_SemanticsDic[body.sessionId].Answertimes} {v.Name} 返回内容为空"); } } } } else { log.Info($"{body.questions} {v.Name} 超时线程取消未入槽!"); } } catch (Exception ex) { log.Info($"开始向{v.Name}发送消息异常:{ex.Message}"); } }, cts.Token)); } } //到了1.5秒还没有全部执行的,取消线程并返回 taskList.Add(Task.Delay(1500).ContinueWith(t => { //如果语义槽为空不再执行 if (_SemanticsDic.ContainsKey(body.sessionId)) { //如果当前语义槽标识位为State=0,则表示可以继续执行 if (_SemanticsDic[body.sessionId].State == 0) { //把当前session状态设置false _SemanticsDic[body.sessionId].State = -1; lock (_lock) { cts.Cancel(); } //如果语义槽不为null再继续执行 if (_SemanticsDic[body.sessionId] != null) { //返回语义结果 AIControler.GetAIAnswers(_SemanticsDic[body.sessionId], "超时"); } } } })); } catch (Exception ex) { log.Info($"发送消息异常:{ex.Message}"); } }