微信小程序> 微信小程序websocket实现即时聊天

微信小程序websocket实现即时聊天

浏览量:587 时间: 来源:谭少居然

今天给大家分享一下本人做小程序使用websocket的一点小经验,希望对大家有所帮助。

使用之前肯定首先要了解一下websocket是什么,简单来讲websocket就是客户端与服务器之间专门建立的一条特殊通道,请求只需要请求一次,而且还可以从通道实时获取服务器数据,非常适合应用到实时应用上。

因为这里本人是分享小程序,所以就不去深究websocket的底层和协议了,感兴趣的朋友可以去看下websocket协议

建议大家在做之前先看看微信小程序官方提供的api关于websocket的文档,因为微信的websocket接口虽然和HTML5的websocket基本一样但是语法上还是有少许偏差,了解一下还是很有必要的。

话不多说上代码(css代码就不贴了,就是一些简单的聊天样式排版)

wxml

view scroll-view scroll-y="true" scroll-with-animation="true" scroll-x="false" scroll-into-view="list-{{idx}}" class="twnav"        view class='twChild'        !-- text视频聊天室/text --        view class='tellRoom'  wx:for="{{tellData}}" wx:for-index="idx" wx:for-item="li" wx:key="li" id='list-{{li.id}}'          view class='myHead'            image class='sayHead' wx-if='{{li.type=="question"||li.type=="message"}}' src='{{li.avatarurl}}'/image            image class='sayHead' wx-if='{{li.type=="answer"}}' src='{{li.content.orgLogo}}'/image          /view          view class='tellDetail'              text class='name' wx-if='{{li.type=="question"||li.type=="message"}}'{{li.displayName}}:/text              text class='name' wx-if='{{li.type=="answer"}}'{{li.content.orgName}}回复{{li.displayName}}:/text              view wx-if='{{li.type=="answer"}}' class='answer'                view class='anQue'{{li.content.question}}/view                view class='anAn'{{li.content.answer}}/view              /view              image wx-if='{{li.type=="question"}}' class='question' src='../../image/icon_quiz@2x.png' mode='widthFix'/image              text class='sayDetail' wx-if='{{li.type=="question"}}'{{li.content.content}}/text              text class='sayDetail' wx-if='{{li.type=="message"}}'{{li.content}}/text          /view        /view        view class='ccds'/view        /view  /scroll-view            view class='btn' wx-if='{{tell==true&&promodal==false}}'          form bindreset="foo"            input class="myinput"  placeholder="说点什么吧" bindinput="sayValue" focus='{{myinputing}}'/            button form-type="reset" class='sub' wx-if='{{isSend=="send"||isSend=="sureAsk"}}'  bindtap='sendMes'发送/button            button form-type="reset" class='sub' wx-if='{{isSend=="ask"}}' bindtap='ask'问/button          /form        /view   /view

js

const app = getApp()var server = app.globalData.myUrl//这是自己的服务端接口地址设置于app.jsvar WxParse = require('../../wxParse/wxParse.js');var tellPage = 1var myurl='ws://+"你自己的链接地址"'var ws     // socket发送的消息队列var socketMsgQueue = []var socketOpen = true            // 判断心跳变量var heart = ''                   // 心跳失败次数var heartBeatFailCount = 0       // 终止心跳var heartBeatTimeOut = null;     // 终止重新连接var connectSocketTimeOut = null;Page({  /**   * 页面的初始数据   */  data: {    sayValue:'',    tellData:[],//聊天消息    idx:'',    id:'',    fjh:'',//房间号    myinputing:'',    isSend: 'ask',  },  /**    * 生命周期函数--监听页面加载    */  onLoad: function (options) {    this.setData({      id: options.id,      fjh:options.roomNum,    })   this.history(1)   this.connectStart()  },  /**   * 生命周期函数--监听页面初次渲染完成   */  onReady: function () {    //监听websocket连接状态      this.deal()  },  /**   * 生命周期函数--监听页面显示   */  onShow: function () {    console.log()  },  /**   * 生命周期函数--监听页面隐藏   */  onHide: function () {     },  /**   * 生命周期函数--监听页面卸载   */  onUnload: function () {    var that = this    //离开页面销毁websocket并恢复初始数据    wx.closeSocket()    twice = 0    socketOpen = true    heart = ''                   // 心跳失败次数    heartBeatFailCount = 0       // 终止心跳    heartBeatTimeOut = null;     // 终止重新连接    connectSocketTimeOut = null;  },  /**   * 页面相关事件处理函数--监听用户下拉动作   */  onPullDownRefresh: function () {     },  /**   * 页面上拉触底事件的处理函数   */  onReachBottom: function () {     },  /**   * 用户点击右上角分享   */  onShareAppMessage: function () {    console.log('点击分享')  },  //获取聊天室历史记录  history: function (a) {    var that = this    wx.request({      url: server + 'api/message/chatmsg',      header: {        "Authorization": app.globalData.token,      },      data: {        page: a,        type: '',        resultsPerPage: 1000,        stream: that.data.id      },      success: (res) = {        var h = res.data.data.items        if (h.length  0) {          var myArr = []          var c = 0          h.forEach(i = {            c++            i.id = c            if (i.type == 'question' || i.type == 'answer') {              i.content = JSON.parse(i.content)            }            myArr.push(i)          })          var j = h.length - 1          var idx = h[j].id          // console.log(h, idx)          that.setData({            tellData: h,            idx: idx,          })        }      }    })  },  //与socket建立连接  connectStart: function () {    var that = this      ws = wx.connectSocket({        url: myurl,        header: {          "Authorization": app.globalData.token,          'content-type': 'application/json'        },        data: JSON.stringify({          token: app.globalData.token,          type: 3,          payLoad: {            topic: that.data.fjh          }        }),        success: (res) = {          // console.log("进入聊天", res)        },        fail: (err) = {          wx.showToast({            title: '网络异常!',          })          console.log(err)        },      })      //  连接成功    wx.onSocketOpen((res) = {      console.log('WebSocket 成功连接', res)      that.resMes()      //  开始心跳      that.startHeartBeat()    })    //连接失败    wx.onSocketError((err) = {      console.log('websocket连接失败', err);      twice=0      that.connectStart()    })  },  // 开始心跳  startHeartBeat: function () {    // console.log('socket开始心跳')    var that = this;    heart = 'heart';    that.heartBeat();  },  // 心跳检测  heartBeat: function () {    var that = this;    if (!heart) {      return;    }    var xtData = {      token: app.globalData.token,      type: 1,      payLoad: ""    }    // console.log(JSON.stringify({ xtData }))    that.sendSocketMessage({      msg: JSON.stringify(xtData),      data: JSON.stringify(xtData),      success: function (res) {        // console.log('socket心跳成功',res);        if (heart) {          heartBeatTimeOut = setTimeout(() = {            that.heartBeat();          }, 5000);        }      },      fail: function (res) {        console.log('socket心跳失败');        if (heartBeatFailCount  2) {          // 重连          console.log('socket心跳失败')          that.connectStart();        }        if (heart) {          heartBeatTimeOut = setTimeout(() = {            that.heartBeat();          }, 5000);        }        heartBeatFailCount++;      },    });  },  // 进入聊天  resMes: function () {    var that = this    var joinData = {      token: app.globalData.token,      type: 3,      payLoad: JSON.stringify({        topic: that.data.fjh      }),    }    // console.log(joinData)    that.sendSocketMessage({      msg: JSON.stringify(joinData),      data: JSON.stringify(joinData),      success: function (res) {        // console.log('进入房间成功', res);        that.deal()      },      fail: function (err) {        console.log('进入房间失败');      },    })  },  // 结束心跳  stopHeartBeat: function () {    // console.log('socket结束心跳')    var that = this;    heart = '';    if (heartBeatTimeOut) {      clearTimeout(heartBeatTimeOut);      heartBeatTimeOut = null;    }    if (connectSocketTimeOut) {      clearTimeout(connectSocketTimeOut);      connectSocketTimeOut = null;    }  },  // 消息发送  foo: function () {    if (this.data.inputValue) {      //Do Something    } else {      //Catch Error    }    this.setData({      inputValue: ''//将data的inputValue清空    });    return;  },  sayValue: function (e) {    var that = this    // console.log(this.data.isSend)    if (that.data.isSend == 'ask') {      that.setData({        isSend: 'send'      })    }    that.setData({      sayValue: e.detail.value    })  },  sendMes: function (e) {    var that = this    // console.log(this.data.sayValue, 111)    var myInput = this.data.sayValue    var token = app.globalData.token    if (that.data.isSend == 'sureAsk') {      wx.request({        url: server + 'api/question/add',        method: 'POST',        header: {          "Authorization": app.globalData.token,          'content-type': 'application/json'        },        data: {          content: myInput,          streamId: that.data.id        },        success: (res) = {          console.log(res, '我的提问')        }      })    } else {      // console.log(app.globalData.userInfo)      var chatInfo = {        user: app.globalData.userInfo.id,        displayName: app.globalData.userInfo.displayName,        avatarurl: app.globalData.userInfo.avatarUrl,        stream: that.data.id,        content: myInput,        type: "message",        createdat: "2018-10-8 14:30"      }      var sendData = {        token: token,        type: 2,        payLoad: JSON.stringify({          topic: that.data.fjh,          chatInfo: JSON.stringify(chatInfo)        })      }      // console.log(JSON.stringify(sendData))      that.sendSocketMessage({        msg: JSON.stringify(sendData)      })    }    that.setData({      sayValue: '',      isSend: 'ask'    })  },  // 通过 WebSocket 连接发送数据  sendSocketMessage: function (options) {    var that = this    if (socketOpen) {      wx.sendSocketMessage({        data: options.msg,        success: function (res) {          if (options) {            options.success && options.success(res);          }        },        fail: function (res) {          if (options) {            options.fail && options.fail(res);          }        }      })    } else {      socketMsgQueue.push(options.msg)    }    // ws.closeSocket();    // that.deal()  },  //  监听socket  deal: function () {    var that = this    ws.onOpen(res = {      socketOpen = true;      console.log('监听 WebSocket 连接打开事件。', res)    })    ws.onClose(onClose = {      console.log('监听 WebSocket 连接关闭事件。', onClose)      // socketOpen = false;      // that.connectStart()    })    ws.onError(onError = {      console.log('监听 WebSocket 错误。错误信息', onError)      socketOpen = false    })    ws.onMessage(onMessage = {      var res = JSON.parse(onMessage.data)      // console.log(res,"接收到了消息")      if (res.code == 200) {        // console.log('服务器返回的消息', res.data)        var resData = JSON.parse(res.data)        var arr = that.data.tellData        resData.id = arr.length + 1        if (resData.type == 'question' || resData.type == 'answer') {          resData.content = JSON.parse(resData.content)          console.log('这是提问', resData.type, resData.content.content)        }        arr.push(resData)        console.log(resData, arr.length)        that.setData({          tellData: arr,          idx: resData.id        })      } else {      }    })  },  time: function (a) {    var data = new Date(a)    var year = data.getFullYear();    var month = data.getMonth() + 1;    var day1 = data.getDate();    var hh = data.getHours(); //截取小时    var mm = data.getMinutes(); //截取分钟    if (month  10) {      month = '0' + month    }    if (day1  10) {      day1 = '0' + day1    }    if (hh  10) {      hh = '0' + hh    }    if (mm  10) {      mm = '0' + mm    }    var newday = month + "月" + day1 + ' ' + hh + ':' + mm    return newday  },  inputing: function () {    console.log('获取焦点')    this.setData({      isSend: 'send'    })  },  inputed: function () {    // console.log('失去焦点')    this.setData({      isSend: 'ask',    })  },  ask: function () {    // console.log('提问')    this.setData({      myinputing: true,      isSend: 'sureAsk'    })  },  })

以上仅是前端部分本人小程序websocket的使用实例,具体的情况需要配合自己的服务端。希望对大家有所帮助,也欢迎大家互相讨论。

 

版权声明

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

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