国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 課堂 > 小程序 > 正文

微信小程序websocket實(shí)現(xiàn)即時(shí)聊天功能

2020-03-21 15:55:48
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

今天給大家分享一下本人做小程序使用websocket的一點(diǎn)小經(jīng)驗(yàn),希望對(duì)大家有所幫助。

使用之前肯定首先要了解一下websocket是什么,簡(jiǎn)單來(lái)講websocket就是客戶(hù)端與服務(wù)器之間專(zhuān)門(mén)建立的一條特殊通道,請(qǐng)求只需要請(qǐng)求一次,而且還可以從通道實(shí)時(shí)獲取服務(wù)器數(shù)據(jù),非常適合應(yīng)用到實(shí)時(shí)應(yīng)用上。

因?yàn)檫@里本人是分享小程序,所以就不去深究websocket的底層和協(xié)議了,感興趣的朋友可以去看下websocket協(xié)議

建議大家在做之前先看看微信小程序官方提供的api關(guān)于websocket的文檔,因?yàn)槲⑿诺膚ebsocket接口雖然和HTML5的websocket基本一樣但是語(yǔ)法上還是有少許偏差,了解一下還是很有必要的。

話(huà)不多說(shuō)上代碼(css代碼就不貼了,就是一些簡(jiǎn)單的聊天樣式排版)

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}}回復(fù){{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="說(shuō)點(diǎn)什么吧" bindinput="sayValue" focus='{{myinputing}}'/>  <button form-type="reset" class='sub' wx-if='{{isSend=="send"||isSend=="sureAsk"}}' bindtap='sendMes'>發(fā)送</button>  <button form-type="reset" class='sub' wx-if='{{isSend=="ask"}}' bindtap='ask'>問(wèn)</button>  </form> </view></view>

js

const app = getApp()var server = app.globalData.myUrl//這是自己的服務(wù)端接口地址設(shè)置于app.jsvar WxParse = require('../../wxParse/wxParse.js');var tellPage = 1var myurl='ws://+"你自己的鏈接地址"'var ws // socket發(fā)送的消息隊(duì)列var socketMsgQueue = []var socketOpen = true  // 判斷心跳變量var heart = ''   // 心跳失敗次數(shù)var heartBeatFailCount = 0 // 終止心跳var heartBeatTimeOut = null; // 終止重新連接var connectSocketTimeOut = null;Page({  /** * 頁(yè)面的初始數(shù)據(jù) */ data: { sayValue:'', tellData:[],//聊天消息 idx:'', id:'', fjh:'',//房間號(hào) myinputing:'', isSend: 'ask', }, /** * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載 */ onLoad: function (options) { this.setData({ id: options.id, fjh:options.roomNum, }) this.history(1) this.connectStart() }, /** * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面初次渲染完成 */ onReady: function () { //監(jiān)聽(tīng)websocket連接狀態(tài) this.deal() }, /** * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面顯示 */ onShow: function () { console.log() }, /** * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面隱藏 */ onHide: function () {  }, /** * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面卸載 */ onUnload: function () { var that = this //離開(kāi)頁(yè)面銷(xiāo)毀websocket并恢復(fù)初始數(shù)據(jù) wx.closeSocket() twice = 0 socketOpen = true heart = ''   // 心跳失敗次數(shù) heartBeatFailCount = 0 // 終止心跳 heartBeatTimeOut = null; // 終止重新連接 connectSocketTimeOut = null; },  /** * 頁(yè)面相關(guān)事件處理函數(shù)--監(jiān)聽(tīng)用戶(hù)下拉動(dòng)作 */ onPullDownRefresh: function () {  }, /** * 頁(yè)面上拉觸底事件的處理函數(shù) */ onReachBottom: function () {  }, /** * 用戶(hù)點(diǎn)擊右上角分享 */ onShareAppMessage: function () { console.log('點(diǎn)擊分享') }, //獲取聊天室歷史記錄 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("進(jìn)入聊天", res) }, fail: (err) => {  wx.showToast({  title: '網(wǎng)絡(luò)異常!',  })  console.log(err) }, })  // 連接成功 wx.onSocketOpen((res) => { console.log('WebSocket 成功連接', res) that.resMes() // 開(kāi)始心跳 that.startHeartBeat() }) //連接失敗 wx.onSocketError((err) => { console.log('websocket連接失敗', err); twice=0 that.connectStart() }) }, // 開(kāi)始心跳 startHeartBeat: function () { // console.log('socket開(kāi)始心跳') var that = this; heart = 'heart'; that.heartBeat(); }, // 心跳檢測(cè) 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++; }, }); }, // 進(jìn)入聊天 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('進(jìn)入房間成功', res); that.deal() }, fail: function (err) { console.log('進(jìn)入房間失敗'); }, }) }, // 結(jié)束心跳 stopHeartBeat: function () { // console.log('socket結(jié)束心跳') var that = this; heart = ''; if (heartBeatTimeOut) { clearTimeout(heartBeatTimeOut); heartBeatTimeOut = null; } if (connectSocketTimeOut) { clearTimeout(connectSocketTimeOut); connectSocketTimeOut = null; } }, // 消息發(fā)送 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, '我的提問(wèn)') } }) } 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' })    }, // 通過(guò) WebSocket 連接發(fā)送數(shù)據(jù) 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() }, // 監(jiān)聽(tīng)socket deal: function () { var that = this ws.onOpen(res => { socketOpen = true; console.log('監(jiān)聽(tīng) WebSocket 連接打開(kāi)事件。', res) }) ws.onClose(onClose => { console.log('監(jiān)聽(tīng) WebSocket 連接關(guān)閉事件。', onClose) // socketOpen = false; // that.connectStart() }) ws.onError(onError => { console.log('監(jiān)聽(tīng) WebSocket 錯(cuò)誤。錯(cuò)誤信息', onError) socketOpen = false }) ws.onMessage(onMessage => { var res = JSON.parse(onMessage.data) // console.log(res,"接收到了消息") if (res.code == 200) { // console.log('服務(wù)器返回的消息', 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('這是提問(wèn)', 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(); //截取小時(shí) 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('獲取焦點(diǎn)') this.setData({ isSend: 'send' }) }, inputed: function () { // console.log('失去焦點(diǎn)') this.setData({ isSend: 'ask',  }) }, ask: function () { // console.log('提問(wèn)') this.setData({ myinputing: true, isSend: 'sureAsk' }) }, })

以上僅是前端部分本人小程序websocket的使用實(shí)例,具體的情況需要配合自己的服務(wù)端。希望對(duì)大家有所幫助,也歡迎大家互相討論。


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 积石山| 溧水县| 安乡县| 铜梁县| 从江县| 刚察县| 安化县| 安塞县| 康马县| 通榆县| 沧州市| 岑巩县| 庆阳市| 长武县| 炉霍县| 筠连县| 克山县| 陇川县| 池州市| 遂宁市| 新密市| 醴陵市| 民勤县| 嘉定区| 沅陵县| 台东县| 武平县| 松滋市| 襄樊市| 红桥区| 互助| 南部县| 甘洛县| 鱼台县| 淮阳县| 商河县| 连州市| 墨竹工卡县| 镇江市| 龙南县| 赣榆县|