需求:

服务端收到了客户提交的订单后,给店主进行实时语音提醒,我们的产品有web端,也有app端。方便店主在繁忙时能通过语音知道有新消息。

技术栈:

Vue3

Uniapp

Java

难点:

废话不多说,订单实时语音提醒实现中的难点,在与“实时”二字。

方案选型

我知道的有三种实现方式,就看采用哪种了。分别分析了它们的优劣势,之后我得出了一个最适合我们项目的结论。

1. 轮询

优势:简单快速就能实现

劣势:不是真正的实时!!!浪费很多请求,浪费服务端资源!!!

2. websocket

优势:

  1. 原生协议:WebSocket是一种HTML5标准,它是基于TCP的原生协议,提供了低延迟、高性能的双向通信。
  2. 简洁性:WebSocket协议相对较简单,适用于开发者需要更多控制的场景。
  3. 广泛支持:WebSocket得到广泛的支持,几乎所有现代浏览器都支持WebSocket,同时也有很多服务器端库和框架可以使用。

劣势:

  1. 纯粹的通信协议:WebSocket只提供了基本的通信功能,没有包含更高级的特性,如房间管理、广播等。这些特性需要额外的开发工作。

3. socket io

优势:

  1. 封装复杂性:Socket.IO是一个构建在WebSocket之上的库,它封装了WebSocket的复杂性,提供了更高级的功能,如房间管理、广播、重连等。
  2. 跨平台:Socket.IO不仅支持浏览器端,还支持服务器端,因此可以在多种环境中使用,包括Node.js、Python、Java等。
  3. 自适应:Socket.IO可以根据客户端和服务器的能力选择最佳的传输方式,包括WebSocket、轮询和长轮询,以确保在各种情况下都能实现实时通信。

劣势:

  1. 复杂性:Socket.IO相对于WebSocket来说更复杂,因为它引入了更多的概念和选项,可能需要更多的学习和开发成本。
  2. 不是原生协议:尽管Socket.IO是一个功能强大的库,但它不是原生的WebSocket协议,这意味着它可能会引入一些额外的开销。

结论,websocket更适合我们

我们需要真正的实时,所以轮询并不适合我们;socket.io 对于我们这种场景来讲,有点儿大材小用;websocket是一个简单的、原生的双向通信协议,WebSocket可能更适合我们,但是需要自己搭建一个websocket服务器,这个也是有点儿费时,关键后期还需要维护,如果访问量大,服务器稳定性和带宽的费用也是不小的开支。网上一番搜索,找到了GoEasy websocket消息推送,他们可以提供websocket 云服务,帮我解决了选择websocket协议来实现的后顾之忧。

实现

web端实时接收消息

1. 引入goeasy sdk

我这里采用的是npm的方式引入

 npm install goeasy@2.8.8 --save

2. 导入 goeasy sdk, 初始化goeasy,建立goeasy连接

为了方便大家看,我这里只在一个页面中展示。

app key需要从goeasy官网 www.goeasy.io来注册获得哦

import GoEasy from 'goeasy';
const goEasy = GoEasy.getInstance({
  host:'hangzhou.goeasy.io', //新加坡host:singapore.goeasy.io
  appkey: "您的appkey", //替换为您的应用appkey
  modules: ['pubsub']
});
// 建议在main.js里初始化全局的GoEasy对象
Vue.prototype.goEasy = goEasy;
//建立连接
goEasy.connect({
  onSuccess: function () { //连接成功
    console.log("GoEasy connect successfully.") //连接成功
  },
  onFailed: function (error) { //连接失败
   console.log("Failed to connect GoEasy, code:"+error.code+ ",error:"+error.content);
  }
});

3. 订阅新订单的通道,并处理接收消息后的语音播放

//订阅消息
goEasy.pubsub.subscribe({
  channel: "new_order",//替换为您自己的channel
  onMessage: function (message) { //收到消息
    //收到消息了,播放音频文件
    playAudioForNewOrder(message);
  },
  onSuccess: function () {
    console.log("Channel订阅成功。");
  },
  onFailed: function (error) {
    console.log("Channel订阅失败, 错误编码:" + error.code + " 错误信息:" + error.content)
  }
});

app端实时接收消息

有的客户,他们并没有电脑设备,web端的提醒对于他们也就没有意义,所以我们需要在app端也加上语音提醒,基于app的特性,用户不会让app一直在前台运行,所以也就需要我们实现当app在后台运行或者app的进程被杀后,如果有新的订单也需要实时提醒到用户。

 1. 引入goeasy sdk

这里采用的是本地引入

import GoEasy from '/lib/GOEASY-IM/js_sdk/goeasy-2.8.8.esm.min.js'

2. 导入 goeasy sdk, 初始化goeasy,建立goeasy连接

app key需要从goeasy官网 www.goeasy.io来注册获得哦

import GoEasy from 'goeasy';
const goEasy = GoEasy.getInstance({
  host:'hangzhou.goeasy.io', //新加坡host:singapore.goeasy.io
  appkey: "您的appkey", //替换为您的应用appkey
  modules: ['pubsub']
});
// 建议在main.js里初始化全局的GoEasy对象
Vue.prototype.goEasy = goEasy;
//建立连接
goEasy.connect({
  onSuccess: function () { //连接成功
    console.log("GoEasy connect successfully.") //连接成功
  },
  onFailed: function (error) { //连接失败
   console.log("Failed to connect GoEasy, code:"+error.code+ ",error:"+error.content);
  }
});

3. 订阅新订单的通道,并处理接收消息后的语音播放

//订阅消息
goEasy.pubsub.subscribe({
  channel: "new_order",//替换为您自己的channel
  onMessage: function (message) { //收到消息
    //收到消息了,播放音频文件
    playAudioForNewOrder(message);
  },
  onSuccess: function () {
    console.log("Channel订阅成功。");
  },
  onFailed: function (error) {
    console.log("Channel订阅失败, 错误编码:" + error.code + " 错误信息:" + error.content)
  }
});

4. app在后台运行或者app进程被杀后,对新订单进行语言提醒

这个功能的重点,其实就是要实现离线通知栏提醒,且需要一个自定义铃声来提醒用户这条通知的独特性。所以,我们需要集成GoEasy 提供的通知栏提醒和自定义铃声功能。

4.1. 集成通知栏推送功能

有过app开发经验的童鞋都知道,国内的android市场,没有统一的厂商推送通道,不同的手机厂商都是走自己的厂商通道来推送离线消息。所以要集成通知栏推送,就绕不开厂商通道集成。

下面我记录一下大致的实现步骤,方便大家了解集成思路,如果有具体问题,还是建议直接咨询goeasy官网。

a. 初始化GoEasy允许通知栏提醒
    Vue.prototype.goeasy = GoEasy.getInstance({
        host: "hangzhou.goeasy.io",  //若是新加坡区域:singapore.goeasy.io
        appkey: "您的common key",
        modules: ['pubsub'],//根据需要,传入‘pubsub’或'im’,或数组方式同时传入
        allowNotification: true,  // true表示支持通知栏提醒,false则表示不需要通知栏提醒
    });
b. 在main.js GoEasy初始化后,立即监听onClickNotification事件
    //当用户点击通知栏消息触发,开发者可以根据消息数据,执行不同的业逻辑,比如跳转到不同的页面,或显示不同的内容
    goeasy.onClickNotification((message) => {
        // message
        // {
        //  channel: "new_order",
        //  content: "hello GoEasy!"
        // }
        console.log('Clicked notification message - ', message);
    });
c. 集成厂商通道并添加自定义铃声

注意:sdk版本不能低于2.8.0; goeasy原生插件版本不能低于1.5.2.

        1)参考goeasy文档配置厂商通道,他们官方文档中有,不再重复赘述 接入厂商通道 - Uniapp推送 | GoEasy文档

        根据文档在goeasy后台和原生插件页面配置好厂商通道。

        2) 添加自定义铃声

        GoEasy自定义铃声当前文件格式支持情况:

        iOS: 仅支持caf文件,其他格式如何转换成caf,网上有很多教程

        Android:为了确保同一套代码能够在不同手机播放,建议统一使用mp3格式,其他格式可能导致无法兼容其他手机品牌。(如需要使用其他格式,各厂商支持的文件格式不同,具体请参考各个厂商的文档,并自行测试)

3)在发送消息的代码中添加通知栏推送的代码和自定义铃声的文件名称
    pubsub.publish({
        channel: "new_order",  //请确认与接收端一致
        message: "新的订单xxxx",   //app内onMessage收到的消息内容
        notification: { //定义通知栏推送
            title: '新订单提醒', //通知栏提醒标题,仅显示于通知栏
            body: "您有新的订单哦", //通知栏提醒内容,仅显示于通知栏
            sound: 'sound' //铃声文件名,注意不可包含扩展名!!!
        },
        onSuccess: function () {
            console.log("Publish successfully.")
        },
        onFailed: function (error) {
            console.log("Failed to publish message, code:" + error.code + ' error:' + error.content);
        }
    });
4)打自定义基座测试

如何制作自定义基座:制作自定义基座 - Uniapp推送 | GoEasy文档

到此就集成完毕了。

注意事项

  1. 如果收不到通知栏提醒,可以参考文档Uniapp+GoEasy原生插件实现通知栏推送过程中的问题排查记录_uniapp通知栏-CSDN博客 来排查
  2. 如果自定义铃声不工作,可以重新再打基座试试 (有可能音频文件没有打到安装包中)
  3. 如果有其他什么疑问,可以直接联系他们的客服人员。

哦哦哦  对了,他们最近新建了个qq群,里面有专人回答问题,感兴趣的可以进群讨论。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐