示例#1
0
        /// <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}");
            }
        }
示例#2
0
        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($"保存到句子表和分词表");
                });
            }
        }
示例#3
0
        /// <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}");
            }
        }