public NlpAnswers SendMsg(SoundBodyRequest body) { NlpAnswers semanticsSlot = new NlpAnswers() { Code = "SoundNlp", Name = "音响", Level = 2, Answers = body.req.ToString() }; if (!string.IsNullOrEmpty(body.req.ToString()) && !body.req.ToString().Contains("name\":\"Speak")) { if (body.req.ToString().Contains("askingType\":\"WEATHER")) { dynamic result = JsonConvert.DeserializeObject <dynamic>(body.req.ToString());//反序列化 //临沂今天阴转多云,4℃~11℃,和昨天差不多,当前空气质量指数170,中度污染,外出记得带上口罩。 description semanticsSlot.Answers = result.directive.payload["description"].Value; } else { semanticsSlot.Answers = body.req.ToString(); } } else { semanticsSlot.Answers = ""; } return(semanticsSlot); }
/// <summary> /// 向智能主机发送音响语音内容,异步返回答案为null /// </summary> /// <param name="body"></param> /// <returns></returns> public static NlpAnswers SendMsg(SoundBodyRequest body) { log.Info($"音响{body.sessionId}向智能家居smarthome发送问题:{body.questions}"); string user = "******"; string sendstr = ""; if (!string.IsNullOrEmpty(body.deviceId)) { //读取配置文件中音响对应的主机 user = ConfigAppSettings.GetValue(body.deviceId);//wali_Server log.Info($"音响{body.deviceId}对应的主机为:{user}"); } else { log.Info($"音响{body.deviceId}对应的主机不存在,请配置。"); } try { ///这里要判断,数据类型了 if (body.sourceId == "mengdou") { String temp = body.req.ToString(); if (temp.IndexOf("service\":\"musicX") > -1) { sendstr = body.sessionId + "_" + body.deviceId + ";5;517;" + EncryptionHelp.Encryption("music@" + body.req, false) + "$/r$" + "\r\n"; } else if (temp.IndexOf("service\":\"news") > -1) { sendstr = body.sessionId + "_" + body.deviceId + ";5;517;" + EncryptionHelp.Encryption("news@" + body.req, false) + "$/r$" + "\r\n"; } else if (temp.IndexOf("service\":\"story") > -1) { sendstr = body.sessionId + "_" + body.deviceId + ";5;517;" + EncryptionHelp.Encryption("story@" + body.req, false) + "$/r$" + "\r\n"; } else if (temp.IndexOf("service\":\"joke") > -1) { sendstr = body.sessionId + "_" + body.deviceId + ";5;517;" + EncryptionHelp.Encryption("joke@" + body.req, false) + "$/r$" + "\r\n"; } else { sendstr = body.sessionId + "_" + body.deviceId + ";5;513;" + EncryptionHelp.Encryption(body.questions, false) + "$/r$" + "\r\n"; } } else { //sessionid_deviceId;5;513;base64不zip(打开窗帘)$/r$ sendstr = body.sessionId + "_" + body.deviceId + ";5;513;" + EncryptionHelp.Encryption(body.questions, false) + "$/r$" + "\r\n"; } SmartHomeServer.SendMsg(user, sendstr); log.Info($"智能家居给{user}发送数据:{sendstr}完毕"); } catch {}; return(null); }
public NlpAnswers SendMsg(SoundBodyRequest body) { NlpAnswers semanticsSlot = new NlpAnswers() { Code = "ShopNlp", Name = "购物", Answers = "购买窗帘", }; return(semanticsSlot); }
public NlpAnswers SendMsg(SoundBodyRequest body) { NlpAnswers semanticsSlot = new NlpAnswers() { Code = "MusicNlp", Name = "音乐", Answers = "播放《卷珠帘》", }; return(semanticsSlot); }
/// <summary> /// 向智能主机发送音响语音内容,异步返回答案为null /// </summary> /// <param name="body"></param> /// <returns></returns> public NlpAnswers SendMsg(SoundBodyRequest body) { log.Debug($"SmartHomeNlp接收到问题 :{body.questions}"); try { string hostid = ""; using (RedisHashService service = new RedisHashService()) { //hostid = service.Get(body.deviceId);//获取缓存中与音响绑定的主机 hostid = service.GetValueFromHash("Sound_Host", body.deviceId); //缓存中不存在再查数据库 if (!string.IsNullOrEmpty(hostid)) { //hostid = hostid.Replace("\"", ""); SendStr(body, hostid); } else { //根据设备id获取主机ID using (HsfDBContext hsfDBContext = new HsfDBContext()) { //根据音响devmac找对应的主机userid,向主机发送消息 var soundhostEntity = hsfDBContext.sound_host.Where(t => t.devmac == body.deviceId && t.deletemark == 0).FirstOrDefault(); if (soundhostEntity != null) { if (!string.IsNullOrEmpty(soundhostEntity.userid)) { hostid = soundhostEntity.userid; //service.Set<string>(body.deviceId, hostid);//缓存主机与音响的绑定关系 service.SetEntryInHash("Sound_Host", body.deviceId, hostid);//缓存主机与音响的绑定关系,重复绑定覆盖 SendStr(body, hostid); } else { log.Info($"音响{body.deviceId},对应的主机为空字符"); return(null); } } else { log.Info($"未到找音响{body.deviceId},对应的主机"); return(null); } } } } } catch (Exception ex) { log.Info($"SmartHomeNlp SendMsg 异常:{ex.Message}"); }; return(null); }
public NlpAnswers SendMsg(SoundBodyRequest body) { NlpAnswers semanticsSlot = new NlpAnswers() { Code = "BaseNlp", Name = "基础", Level = 0, }; if (body.questions.Contains("几点")) { semanticsSlot.Answers = "现在时间是" + DateTime.Now.Hour + "点" + DateTime.Now.Minute + "分"; } //else if (body.questions.Contains("天气") && !body.req.ToString().Contains("天气")) //{ // semanticsSlot.Answers = "今天气温2℃~11℃,天气晴,空气质量状况良"; //} else { semanticsSlot.Answers = ""; } return(semanticsSlot); }
/// <summary> /// 发送消息str /// </summary> /// <param name="body"></param> /// <param name="hostid"></param> public static void SendStr(SoundBodyRequest body, string hostid) { string sendstr = ""; ///这里要判断,数据类型了 if (body.talkstate == "train") { //训练模式不发送开关指令,执行5135指令 } else { if (body.sourceId == "mengdou") { //得到发送给智能家居的命令 sendstr = GetMengDouSendStr(body.sessionId, body.deviceId, body.req.ToString(), body.questions); } else { sendstr = body.sessionId + "_" + body.deviceId + ";5;513;" + EncryptionHelp.Encryption(body.questions, false) + "$/r$" + "\r\n"; } //向主机发送数据 SmartHomeNlpServer.SendMsg(hostid, sendstr); } }
/// <summary> /// 接收到消息,发送给Nlp管理器 /// </summary> /// <param name="session">会话</param> /// <param name="message">消息内容</param> public static void ws_NewMessageReceived(WebSocketSession session, string message) { message = message.Replace(" ", ""); message = message.Replace("\t", ""); message = message.Replace("\r", ""); message = message.Replace("\n", ""); //log.Info($"web消息:{session.RemoteEndPoint.ToString()} : {message}"); if (message.Equals("ping")) { session.Send("ping"); } else if (message.Contains("\"actionId\":\"800\""))//心跳 { //log.Info($"心跳: {session.RemoteEndPoint.ToString()}说: {message}"); message = message.Replace("800", "801"); session.Send(message); } else { //log.Info($"心跳外所有的消息: {session.RemoteEndPoint.ToString()}说: {message}"); if (message.Contains("\"actionId\":\"111\""))///注册 { log.Info($"新的注册消息:{session.RemoteEndPoint.ToString()} : {message}"); #region 注册认证 try { SoundAuthentication soundEntity = JsonConvert.DeserializeObject <SoundAuthentication>(message); if (soundEntity.req == "123") { //判断是否已经存在该主机的认证信息 SoundAuthentication soundAuth = SoundListIn.Where(a => a.deviceId == soundEntity.deviceId).FirstOrDefault(); //初次认证 if (soundAuth == null) { soundEntity.actionId = "1111"; soundEntity.IPAddress = session.RemoteEndPoint.Address.ToString(); //登录ip soundEntity.req = Guid.NewGuid().ToString(); // 如果成功,token会放入req内容处,客户端每次提交请求,都需带上token SoundListIn.Add(soundEntity); //放入音响缓存list //保存当前session连接与主机对应 _SessionDic.TryAdd(soundEntity.deviceId, session); //认证返回 SoundAuthenticationBack authBack = new SoundAuthenticationBack() { sessionId = soundEntity.sessionId, actionId = soundEntity.actionId,//1111 req = soundEntity.req, }; session.Send(JsonConvert.SerializeObject(authBack)); log.Info($"认证成功:deviceId { soundEntity.deviceId} token {soundEntity.req}"); } else { //断线之后会再次认证,返回之前的令牌,替换当前的session //已经认证过的 SoundAuthenticationBack authBack = new SoundAuthenticationBack() { sessionId = soundEntity.sessionId, //当前请求的session actionId = soundAuth.actionId, //1111 req = soundAuth.req, //之前认证的令牌 }; //保存当前session连接与主机对应 _SessionDic.TryUpdate(soundEntity.deviceId, session, _SessionDic[soundEntity.deviceId]); session.Send(JsonConvert.SerializeObject(authBack)); log.Info($"{ soundEntity.deviceId}已认证成功,req:{soundAuth.req}"); } } else { SoundAuthenticationBack authBack = new SoundAuthenticationBack() { sessionId = soundEntity.sessionId, actionId = "1112", }; session.Send(JsonConvert.SerializeObject(authBack)); log.Info(soundEntity.deviceId + "认证失败"); } } catch (Exception ex) { SoundAuthenticationBack authBack = new SoundAuthenticationBack() { actionId = "1112", }; session.Send(JsonConvert.SerializeObject(authBack)); log.Info("认证异常:" + ex.Message); } #endregion } else if (message.Contains("\"actionId\":\"201\""))///语音请求,音乐返回的语音结果 { log.Info($"\r\n新的语音请求: {message}"); #region 语音请求 try { SoundBodyRequest body = JsonConvert.DeserializeObject <SoundBodyRequest>(message); //如果缓存中的音响槽,包括当前请求的 1.设备id 2.服务器分配的token一致 3.ip地址 SoundAuthentication sound = SoundListIn.Where(a => a.deviceId == body.deviceId && a.req == body.token).FirstOrDefault(); //&& a.IPAddress == session.RemoteEndPoint.Address.ToString() //缓存中存在,则视为正常访问 if (sound != null) { //2.0增加人工智能处理部分代码 AIFunction(body); ////1.0启动多线程 //Task.Run(() => //{ // //发送收到的语音到NLP管理器 // NlpControler.ProcessingRequest(body); //}); } else { //缓存中不存在则返回认证失败 SoundAuthenticationBack authBack = new SoundAuthenticationBack() { sessionId = body.sessionId, actionId = "1112", req = "认证失败" }; session.Send(JsonConvert.SerializeObject(authBack)); //插入认证失败表 using (HsfDBContext hsfDBContext = new HsfDBContext()) { sound_fail sound_Fail = new sound_fail() { sessionId = body.sessionId, deviceId = body.deviceId, actionId = body.actionId, token = body.token, questions = body.questions, IPAddress = session.RemoteEndPoint.Address.ToString(), CreateTime = DateTime.Now }; hsfDBContext.sound_fail.Add(sound_Fail); hsfDBContext.SaveChanges(); } log.Info(body.deviceId + "认证失败,已写入认证失败记录表"); } } catch (Exception ex) { SoundBodyResult bodyResult = new SoundBodyResult() { actionId = "2025",//异常,暂时返回不能识别 req = ex.Message, blwakeup = "0" }; string jsonResult = JsonConvert.SerializeObject(bodyResult); session.Send(jsonResult); } #endregion } else if (message.Contains("\"actionId\":\"202\""))///url媒体文件播放完 { } else if (message.Contains("\"actionId\":\"205\""))///url媒体文件播放完 { } else { ///不做任何处理,让音箱执行自己逻辑 SoundBodyResult bodyResult = new SoundBodyResult() { actionId = "2010", blwakeup = "0" }; string jsonResult = JsonConvert.SerializeObject(bodyResult); session.Send(jsonResult); } } }
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}"); } }
/// <summary> /// 不用请求任何Nlu服务器,直接丢给AIControl函数Setanswer处理,返回抛给音箱 /// </summary> /// <param name="body"></param> /// <returns></returns> public static void Setanswer(SoundBodyRequest body) { string answers = "不用请求任何Nlu服务器,直接丢给AIControl函数Setanswer处理,返回抛给音箱"; NlpControler.BackAnswers(body.sessionId, body.deviceId, body.questions, "2011", answers, BaiduSDK.Tts(answers)); }
/// <summary> /// 获取领域:音乐,聊天(天气),家庭设备控制,视频 /// </summary> /// <param name="body"></param> /// <returns></returns> public static string Getdomain(SoundBodyRequest body) { return("smarthome"); }
public string sendvoice(SoundBodyRequest body) { log.Info("智能家居smarthome:::::::" + body.questions); string user = "******"; string sendstr = ""; if (!string.IsNullOrEmpty(body.deviceId)) { user = ConfigAppSettings.GetValue(body.deviceId);//wali_Server } else { return(""); } bool sok = false; //群发广播 if (user.IndexOf("%") > 0) { user = user.Replace("%", ""); foreach (var us in ls) { if (us.user.IndexOf(user) > -1) { try { //sendstr = requestInfo.Body.Split(' ')[2].Substring(4, requestInfo.Body.Split(' ')[2].Length - 4); sendstr = "connect user:"******" type:other msg:" + "12345678_Ying" + ";5;513;5omT5byA56qX5biY" + "$/r$" + "\r\n"; us.sesson.Send(sendstr); } catch { }; sok = true; } } } else { user = "******"; foreach (var us in ls) { if (us.user == user) { try { //Task.Run(() => //{ log.Info("多线程发送数据user是:" + user); sendstr = body.sessionId + "_" + body.deviceId + ";5;513;" + EncryptionHelp.Encryption(body.questions, true) + "$/r$" + "\r\n"; us.sesson.Send(sendstr); log.Info("给user发送数据完毕" + body.sessionId); //}); } catch { }; sok = true; break; } } } if (!sok) { //requestInfo.Body.Split(' ')[2].Split(':')[1].Split(';')[0] return("server noactive"); } log.Info("智能家居smarthome完毕:::::::" + body.sessionId); return("sendok"); }