简介:本文详细介绍了如何结合StompJS和SpeechSynthesis API实现前端消息的实时语音播报,包括技术原理、实现步骤、代码示例及优化建议。
在物联网监控、即时通讯、金融交易等场景中,用户需要实时接收系统推送的消息。传统视觉通知(如弹窗、Toast)存在两大局限:一是用户可能未持续关注屏幕,二是高密度信息场景下视觉疲劳。语音播报通过听觉通道传递信息,能够有效补充视觉通知的不足,尤其适用于驾驶、工业操作等需要双手操作的场景。
StompJS作为WebSocket的简化封装库,提供了订阅/发布模式的消息通信能力。其核心优势在于:
SpeechSynthesis API是Web Speech API的组成部分,允许开发者通过JavaScript控制浏览器进行文本转语音(TTS)合成。其特点包括:
<!-- 引入StompJS库 -->
<script src="https://cdn.jsdelivr.net/npm/stompjs@2.3.3/lib/stomp.min.js"></script>
<!-- 现代浏览器原生支持SpeechSynthesis,无需额外引入 -->
class WebSocketClient {
constructor(url = 'ws://your-server/ws') {
this.url = url;
this.client = null;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
}
connect() {
this.client = Stomp.over(new WebSocket(this.url));
this.client.connect({},
(frame) => {
console.log('Connected: ' + frame);
this.reconnectAttempts = 0;
this.subscribeToTopic();
},
(error) => {
console.error('Connection error:', error);
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
setTimeout(() => this.connect(), 5000);
}
}
);
}
subscribeToTopic(topic = '/topic/notifications') {
this.client.subscribe(topic, (message) => {
const payload = JSON.parse(message.body);
this.handleNotification(payload);
});
}
}
class SpeechNotifier {
constructor() {
this.synthesis = window.speechSynthesis;
this.voices = [];
this.initVoices();
}
initVoices() {
// 延迟加载语音列表,确保语音引擎就绪
setTimeout(() => {
this.voices = this.synthesis.getVoices();
console.log('Available voices:', this.voices);
}, 100);
}
speak(text, options = {}) {
const utterance = new SpeechSynthesisUtterance(text);
// 配置语音参数
utterance.rate = options.rate || 1.0; // 语速(0.1-10)
utterance.pitch = options.pitch || 1.0; // 音调(0-2)
utterance.volume = options.volume || 1.0; // 音量(0-1)
// 优先使用中文语音(示例)
const chineseVoice = this.voices.find(v =>
v.lang.includes('zh-CN') || v.lang.includes('zh')
);
if (chineseVoice) {
utterance.voice = chineseVoice;
}
this.synthesis.speak(utterance);
}
}
// 初始化客户端
const wsClient = new WebSocketClient('ws://your-server/ws');
const notifier = new SpeechNotifier();
// 自定义消息处理器
wsClient.subscribeToTopic = function() {
this.client.subscribe('/topic/alerts', (message) => {
const alert = JSON.parse(message.body);
console.log('Received alert:', alert);
// 根据消息类型决定播报方式
if (alert.level === 'critical') {
notifier.speak(
`紧急警报:${alert.content}`,
{ rate: 1.2, pitch: 1.5 }
);
} else {
notifier.speak(
`通知:${alert.content}`,
{ rate: 1.0 }
);
}
});
};
// 启动连接
wsClient.connect();
语音队列控制:实现speechSynthesis.cancel()避免消息堆积
class AdvancedSpeechNotifier extends SpeechNotifier {
constructor() {
super();
this.queue = [];
this.isSpeaking = false;
}
speak(text, options) {
this.queue.push({ text, options });
this.processQueue();
}
processQueue() {
if (this.isSpeaking || this.queue.length === 0) return;
this.isSpeaking = true;
const { text, options } = this.queue.shift();
super.speak(text, options);
// 监听结束事件处理下一条
this.synthesis.onvoiceschanged = () => {
this.isSpeaking = false;
this.processQueue();
};
}
}
// 动态选择语音实现
function getVoiceByLang(langCode) {
const voices = speechSynthesis.getVoices();
return voices.find(v => v.lang.startsWith(langCode)) ||
voices.find(v => v.default);
}
// 使用示例
const frenchVoice = getVoiceByLang('fr');
if (frenchVoice) {
const utterance = new SpeechSynthesisUtterance('Bonjour');
utterance.voice = frenchVoice;
speechSynthesis.speak(utterance);
}
function throttleSpeak(notifier, text, options, delay = 3000) {
clearTimeout(notifier.throttleTimer);
notifier.throttleTimer = setTimeout(() => {
notifier.speak(text, options);
}, delay);
}
function checkSpeechSupport() {
if (!('speechSynthesis' in window)) {
console.warn('当前浏览器不支持语音合成功能');
// 降级方案:显示文字提示或播放预录音频
return false;
}
return true;
}
| 浏览器 | 支持版本 | 注意事项 | 
|---|---|---|
| Chrome | 33+ | 最佳语音质量 | 
| Firefox | 49+ | 需用户交互后才能播放 | 
| Safari | 14+ | iOS上限制自动播放 | 
| Edge | 79+ | 基于Chromium的实现 | 
Web Speech API扩展:
服务端TTS集成:
IoT设备集成:
本方案通过StompJS实现了可靠的实时消息推送,结合SpeechSynthesis API提供了自然的语音播报能力。实际开发中,建议根据具体业务场景进行参数调优,并建立完善的错误处理机制。对于高安全性要求的系统,可考虑增加语音内容的加密传输和本地合成引擎的部署。