web需要进行声音预警,当报警发生时候,就用相关的字符串发给后台,由TTS负责生成语音wav文件,然后将wav的URL地址
发给前端的flash播放器,播放,在应用的过程,
经常出现当请求的数据量大时,后台生成的语音文件长度为零。而在WinForm下则没有这个问题。
请问为什么?
部分代码。
ISpeechVoice v = new SpVoiceClass();
ISpeechObjectTokens isots = v.GetVoices("name=ScanSoft Mei-Ling_Full_22kHz", "");
if(isots.Count==0)
isots = v.GetVoices("name=Microsoft Lili", "");//win7或win2008下已安装lili
if (isots.Count > 0)
{
SpFileStream s = new SpFileStream();
try
{
//s.Format.Type = SpeechAudioFormatType.SAFT22kHz16BitMono;
s.Format.Type = SpeechAudioFormatType.SAFT16kHz8BitMono;
s.Open(filePath, SpeechStreamFileMode.SSFMCreateForWrite, false);
v.AudioOutputStream = s;
v.Voice = isots.Item(0);
v.Volume = 100;
v.Rate = -3;
v.Speak(speechText, SpeechVoiceSpeakFlags.SVSFDefault);
s.Close();
if (new FileInfo(filePath).Length > 1000)//有时显示成功,但实际没成功,文件大小只有110个字节。
{
context.Response.Write("../wavs/" + fileName);
}
else
{
File.Delete(filePath);
//文件生成失败。
}
}
catch (Exception ex)
{
s.Close();
File.Delete(filePath);
}
}
------解决思路----------------------
你也说了,请求量大的时候会有问题。
本来SpeechSDK也不是给高并发设计的吧?
另外,你一个web站点,提示难道都是毫无规律可循的?各种提示内容总是有限的吧?预先录制好了返回不好么?即便像动态生成,那么每种提示生成之后就缓存起来,不再重复生成会不会好点?
------解决思路----------------------
web里每个请求就是一个线程。
就算用列队,并发量大的时候,也来不及。我表示很好奇,到底什么样的业务逻辑能让你每次提示都不一样,用户名字么?那也可以在用户注册的时候预录名字的wav,其他相同提示预录,提示的时候合起来就好。
------解决思路----------------------
如果你需要高并发,那么filePath别写死,用guid试试
每个线程自己操作自己的文件,不要都往一个文件里写入
高并发状态下,取系统时间也不见得不会重复,精确到毫秒可能能好一些,但也不一定
------解决思路----------------------
那就把代码移动到winform里去。
asp.net 的运行环境中,各种COM组件可能无法工作
在ASP.NET里,就直接向数据库里 记录需要合成的数据。
另一个winfrom定期检查数据库的表【或则信号量通知】,然后执行操作。最后把wav文件写到ASP.NET的数据文件目录下。