StompJS+SpeechSynthesis实时语音播报

1,518 阅读4分钟

1.应用场景

假设这么一个场景,一个患者情况危急,急需医生看诊,并书写急诊报告以便后续安排治疗等,这时系统就需要主动推送消息到医生那里,为了更好的引起注意,使用语音播报的方式。下面就使用StompJs和SpeechSynthesis接口来实现这一功能。

2.介绍StompJS

说起服务端消息的实时推送,相信很多人都会想到WebSocket,服务器只需要和浏览器完成一次握手,两者之间就可以建立持久性的连接,并且可以进行双向数据传输。WebSocket能够很好的节省服务器资源和带宽,是实时通信的首选方案。

Stomp是基于 WebSocket(SockJS)的上层协议。websocket在客户端的实现看起来比较简单,但是需要与后台进行很好的配合和调试才能达到最佳效果。通过SockJS、Stomp来进行浏览器兼容,增加消息语义,增强了可用性。

1.安装

npm install stompjs
npm install sockjs-client

2.创建客户端

// 使用StompJs
let url = "ws://xxxx";
let socket = new SockJS(url);
let client = Stomp.over(socket);

// 使用WebSocket
let url = "ws://xxxx";
let client = Stomp.client(url);

3.连接服务端 (connect)

client.connect({login,passcode},successCallback,errorCallback);
// login,passcode是用户的登录名和密码凭证,
// successCallback 连接成功的回调
// errorCallback 连接失败的回调

4.断开连接 (disconnect)

client.disconnect(function(){
   console.log("断开连接")
})

5.Heart-beating

heart-beating(心跳):消息传送的频率,有两个属性:incoming是接收频率,outgoing是发送频率,其默认值都为10000ms,也手动设置:

client.heartbeat.incoming = 5000;
client.heartbeat.outgoing = 5000;

6.发送消息 (send)

客户端向服务端发送消息,使用client.send(destination, {}, body),有三个参数:

  • 第一个参数(string)必需,为发送消息的目的地;
  • 第二个参数(object)可选,包含了额外的头部信息;
  • 第三个参数(string)可选,为发送的消息。

7.订阅消息 (subscribe)

客户端接收服务端发送的消息,使用client.subscribe(destination, callback, {}),有三个参数

  • 第一个参数(string)必需,接收消息的目的地;
  • 第二个参数 必需,为回调函数;
  • 第三个参数{object} 可选,包含额外的头部信息。

8.取消订阅 (unsubscribe)

取消订阅消息可以利用unsubscribe()方法

let mySubscribe =  client.subscribe;
 mySubscribe.unsubscribe();

3.介绍SpeechSynthesis

HTML5中新增语音合成API,用于将指定文字合成为对应的语音,不支持IE浏览器。

SpeechSynthesisUtterance

SpeechSynthesisUtterance接口,包含语音服务应阅读的内容以及有关如何阅读的信息(例如语言、音调和音量)。

属性

  • text 需要读的内容
  • lang 使用的语言(比如:"zh-CN")
  • pitch 话语的音调(0-2之间,默认1,值越大越尖锐,越低越低沉)
  • rate 说话的速度(0.1-10之间,默认1,值越大语速越快,越小语速越慢)
  • voice 设置说话的声音
  • volume 音量(0-1之间,默认1) 方法
  • onstart 语音开始合成时触发
  • onpause 语音暂停时触发
  • onresume 语音合成重新开始时触发
  • onend 语音结束时触发

使用new SpeechSynthesisUtterance()可以创建一个文本实例,而真正的语音是由speechSynthesis创建的。

SpeechSynthesis 接口是语音服务的控制接口;它可以用于获取设备上关于可用的合成声音的信息,开始、暂停语音,或除此之外的其他命令

以下是一些常用方法:

  • speak 开始合成语音,将对应的实例添加到语音队列中
  • cancel 停止合成语音,删除队列中所有的语音
  • pause 暂停语音合成
  • resume 恢复暂停的语音
  • getVoices 返回浏览器所支持的语音包数组 使用示例
let u = new SpeechSynthesisUtterance()
u.text = '你好小蝉儿'
u.lang = 'zh'
u.rate = 0.8
window.speechSynthesis.speak(u)

4.代码实践

import SockJS from 'sockjs-client'
import Stomp from 'stompjs'
export default{
  data(){
    return{
      stompClient:null,
      connectNumber:0
    }
  },
  mounted(){
    this.initWebSocket()
  },
  methods:{
    initWebSocket () {
      // 建立连接对象
      let socket = new SockJS('/ws')
      // 获取STOMP子协议的客户端对象
      this.stompClient = Stomp.over(socket)
      // 向服务器发起websocket连接
      this.stompClient.connect({}, this.onConnected, this.onError)
    },
    onConnected () {
      this.stompClient.subscribe('/user/queue/newRegisterSend', function (payload) {
         //接受到消息,进行语音播报
         let u = new SpeechSynthesisUtterance()
         u.text = payload.body
         u.lang = 'zh'
         u.rate = 0.8
         window.speechSynthesis.speak(u)
      })
      this.connectNumber = 0
    },
    onError () {
      this.connectNumber++
      if(this.connectNumber<10){
        this.initWebSocket()
      }
    },
     disconnect () {
      // 判断上一个连接是否已经建立好,建立好后直接断开,否则等待3秒后断开
      if (this.stompClient && this.stompClient.connected) {
        this.stompClient.disconnect()
      } else if (this.stompClient && !this.stompClient.connected) {
        setTimeout(function () {
          that.stompClient.disconnect()
        }, 3000)
      }
    }
  },
  beforeDestroy: function () {
    // 页面离开时断开连接,清除定时器
    if (this.stompClient) {
      this.disconnect()
    }
  }
}