在线客服系统开发难点mark

931 阅读2分钟

背景

公司决定将内部稳定运营支撑上10万商家的客服系统独立出来,独立成一个产品,对外提供服务。在此记录一下此系统对外提供服务遇到的问题及其解决方法。

效果

消息支持

我们设置了消息体参数,核心参数如下

名称类型例子说明
cmdint5消息类型,5代表心跳
mediaint1消息样式,如txt,pic,video,audio,articel
............

websocket掉线

产品主打Uniapp业态,以websocket协议与后端提供通讯。该协议大部分人高级浏览器都支持,但是因为部分网络差异或者用户切换网络导致websocket掉线,解决办法是重连

const CONNECTNOT = 0
const CONNECTING = 1
const CONNECTED = 2

let wsstat = CONNECTING
 let ws = new WebSocket("ws://localhost:9998/ws/push?xxx");
ws.onclose(()=>{
    wsstat = CONNECTNOT
})
ws.onerror(()=>{
    wsstat = CONNECTNOT
})
ws.onopen(()=>{
    wsstat = CONNECTED
})
function task(){
    if(wsstat==CONNECTNOT){
        ws.open(...)
        wsstat=CONNECTING
    }
}
//1秒检测一次重连
setInterval(task,1000)

websocket心跳

有时候后端服务器对长时有数据传输的的链接进行优化,关闭一些空闲链接,解决此问题办法是心跳机制。心跳机制有俩个细节需要考虑

  • 心跳传输什么数据 我们经过多次优化后,建议心跳传输一个简单的json字符串
{"cmd":5,"corpid":1}
  • 心跳间隔是多少 最初我们设置心跳周期为30秒,经过实际运行发现完全没有必要,最后我们改成最后一次数据接收起30秒内无数据则发送心跳
let lastrecvttl = 0
ws.onmessage(()=>{
    lastrecvttl = 30
})
//心跳报文函数
function sendheartbeatmsg(){

}
function task(){
    //   断线重连机制

    //lastrecvttl
    lastrecvttl = lastrecvttl - 1
    if(lastrecvttl<0){
        //发送心跳报文
        lastrecvttl = 30
        sendheartbeatmsg()
    }
}
//1秒检测一次重连
setInterval(reconnect,1000)

服务后端通知

当访客访问通过客服入口联系我们时,我们希望能及时通知商家,为了解决这个问题,我们做了如下工作

  • 微信模板消息,事实证明这个有用,但是不能解决全部问题,因为微收到模板消息后,系统不会通过振动或者播放声音提醒
  • 通过app推送,我们集成了unipush推送,也完善了厂家通道,但是我们发现推送并不及时。
  • 通过短信,提醒成功率很高,但是有费用成倍
  • 提供桌面端支持,在桌面端提醒。最后我们研发了桌面端,可行性非常不错。

##桌面端界面 询单管理界面 ##app端

当前咨询界面 历史记录界面 个人中心界面 询单管理界面

高并发挑战

我们系统使用量非常大,为了解决这个问题我们对系统进行如下优化

  • 核心逻辑才用 golang编辑
  • 采用go微服务架构,这里推荐一下go-zero微服务架构体系

体验

关注公众号turingdanc->点击购买咨询菜单->售前咨询,即可体验H5版本,小程序版本和APP版本可导入示例项目体验。

询单管理界面

插件地址

ideakefu客服组件地址

建议

由于即时通讯领域有一定技术含量,另外消息触达比较麻烦,因此建议采用第三方提供的服务。