微信小程序> 如何在微信小程序中实现实时会话(聊天)系统

如何在微信小程序中实现实时会话(聊天)系统

浏览量:1670 时间: 来源:weixin_36318295

系统分析设计期末大项目——闲得一币TimeForCoin小程序前端
小程序项目地址_闲得一币

概述

实时会话系统包括两大部分:消息管理系统和会话系统。其中“消息”可以定义为一系列会话(即双方之间会话)的集合。通过获取消息列表,我们可以看到很多个消息,每一个消息都有对应的消息id。而通过消息的id,我们可以获取一系列会话,如下:
小程序
小程序

消息管理页

消息管理页将获取的消息分为个人消息以及系统消息。系统消息不能够被回复而个人消息可以。
Message.json中我们需要添加:"enablePullDownRefresh": true以允许下拉刷新。而对于下拉刷新,我们可以通过onPullDownResfresh()函数实现。除此之外,我们还需要在onShow函数中添加信息获取的功能(还要有登录状态的判断)。

onShow函数

 onShow: async function() {    this.setData({      hasUserInfo: app.globalData.hasUserInfo    })    //登录判断    if (!this.data.hasUserInfo) {      wx.showToast({        title: '您未登录~',        image: '/images/icons/error.png'      })      setTimeout(function() {        // 返回        wx.switchTab({          url: '/pages/index/index',          success: function(res) {},          fail: function(res) {},          complete: function(res) {},        })      }, 1000);    }    await this.loadMessage(1)  },

onPullDownRefresh函数

onPullDownRefresh: async function () {    if(!this.data.isLoading){      await this.loadMessage(null)    }  },

至于为什么是onShow而不是onLoad,因为onShow函数在你离开该页面重新进入(可以通过onNavigateBack返回)该页面的时候也会执行一次。消息的状态包括未读已读,如果使用onLoad函数从会话列表页面返回时未读不会更新为已读
在获取消息的函数loadMessage内,我们需要进行https请求,并根据请求的结果(状态码以及数据)进行消息的显示。如果状态码不为200,需要进行异常处理,这里是显示toast。而对于获取的消息,我们根据当前用户选择的是个人消息还是系统消息进行分类,如果选择个人消息就只显示个人消息。除此之外,还需要moment.js进行时间数据的解析。当然,除了时间,所有的数据都要进行正确显示。

当然了,这是个异步函数,因为其中需要等待https请求的结果。
消息页比较有挑战性的是自动刷新ScrollView到底端,使得有新的信息来的时候会自动显示。

loadMessage函数

loadMessage: async function(page) {    this.setData({      isLoading: true    })    if(page != null){      this.data.currentPage = page      this.data.systemMessage = []      this.data.chatMessage = []    } else{      this.data.currentPage++    }    const res = await server.request('GET', 'messages',{      page: this.data.currentPage,      size: 10    })    this.setData({      isLoading :false    })    if(res.statusCode !== 200){      this.setData({hasUserInfo: false})      wx.showToast({        title: '网络错误',        icon: '',        image: '/images/icons/error.png',        duration: 0,        mask: true,        success: function(res) {},        fail: function(res) {},        complete: function(res) {},      })      this.setData({        noMore: true      })      return    }    if(!res.data.data || res.data.data.length === 0){      this.setData({noMore: true})      this.data.currentPage--      return    }    moment.locale('en', {      longDateFormat: {        l: "YYYY-MM-DD",        L: "YYYY-MM-DD HH:mm"      }    })    for (let i in res.data.data) {      res.data.data[i].string_last_time =        moment(res.data.data[i].last_message.time * 1000).format('L');      if (res.data.data[i].target_user.nickname.length > 10) {        res.data.data[i].target_user.nickname = res.data.data[i].target_user.nickname.substr(0, 10) + '...'      }      if (res.data.data[i].type === 'chat') {        this.data.chatMessage.push(res.data.data[i])      } else {        res.data.data[i].target_user.avatar = '/images/icon.png'        this.data.systemMessage.push(res.data.data[i])      }    }    if(!this.data.showSystemInfo){      this.setData({        testMessage: {          data: this.data.chatMessage        }      })    } else{      this.setData({        testMessage:{          data: this.data.systemMessage        }      })    }  },

当然,我们还需要添加单击事件。在标签中添加对应的data-item为消息id,之后根据对应的消息id进行跳转(到会话列表中)。

// 跳转详情  navigateToMessageDetail: function(e) {    var id = e.currentTarget.dataset.id;    wx.navigateTo({      url: '/pages/MessageDetail/MessageDetail?session_id=' + id + '&status=message',    })  },

会话列表页

在会话列表页中,根据消息id进行会话列表的获取。

获取新会话

通过setTimeOut实现定时获取新消息。当然与其他数据一样,列表是分页进行获取的。但与其他数据不同,越接近底部会话的时间是更新的,而通过api获取的页面下标越小是越新的,所以通过调用reverse函数实现反转。如果获取多个页面,还需要进行反转后叠加。

if(isMore){        var arr = []        res.data.messages = res.data.messages.reverse()        for(var val of res.data.messages){          arr.push(val)        }        for(var val of this.data.testMessageDetail.data){          arr.push(val)        }       if(res.data.type !== 'chat'){         // 系统消息不进行整点判断         for (var i = 0; i < arr.length; i = i + 1) {           arr[i].string_time = moment(arr[i].time * 1000).format('L');           arr[i].showTime = true;         }

时间的解析

与之前的时间解析不同,如果对于每一条会话的时间都进行显示,就显得特别繁琐和难看了。这里模仿微信,在每一分钟才进行一次的会话时间的显示。这就需要判断每两个会话之间的时间差是否大于一分钟的。除此之外,第一条会话一定要显示其时间,否则用户无从判断。
实现如下:

// 用于时间显示    moment.locale('zh-cn', {      longDateFormat: {        l: "YYYY-MM-DD",        L: "YYYY-MM-DD HH:mm"      }    })...         // 系统消息不进行整点判断         for (var i = 0; i < arr.length; i = i + 1) {           arr[i].string_time = moment(arr[i].time * 1000).format('L');           arr[i].showTime = true;         }       } else{         // 整点判断         for (var i = 0; i < arr.length - 1; i = i + 1) {           if ((arr[i + 1].time - arr[i].time) > 60 || i === 0) {             arr[i].string_time = moment(arr[i].time * 1000).format('L');             arr[i].showTime = true;           }         }       }                this.
            
            

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

最新资讯

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎