今天给大家分享一下本人做小程序使用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.js
var WxParse = require('../../wxParse/wxParse.js');
var tellPage = 1
var 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的使用实例,具体的情况需要配合自己的服务端。希望对大家有所帮助,也欢迎大家互相讨论。
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。