项目背景:小程序直播平台上显示实时聊天
技术站:小程序API
首先对于不了解webSocket的来个简单的介绍,因为http协议只能由客户端发送请求,服务端收到请求之后返回相应结果,而且是一个客户端对应一个服务端,所以对于现在好多的实时聊天是不合适的,想一下,如果你发送了一条消息,服务端收到消息后又给你返回你发送成功了,而且你只能跟一个人聊天不能接受好多人的消息,所以出现了wss协议,使用webSocket技术可以使这个功能实现,详情请参照 这里
切入正题:
需求:首先进入页面要显示10条最新的聊天记录,如果记录比较多就显示加载更多,然后加载出更多的消息内容,然后输入内容发送出内容到页面上
看代码:
HTML:
// 获取到最新的消息循环显示
{{item.nickname}}:
{{item.content}}
// 用户自己发送的内容
{{item.nickname}}:
{{item.content}}
// socket是否链接的提示(有无都可以)
{{statusMsg}}
// 用户发送信息的输入框
发送
css代码不贴了,简单的写样式
js
Page({
/**
* 页面的初始数据
*
*
*/
data: {
resource_id: '',
book_id: '',
content: '',
chatList: '',
is_content_chat: true,
isShowMore: false,
isOpen: false,
statusMsg: '已断开',
input_value_content:'',
UserChatList: [],
isUser: false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var that = this;
this.setData({
resource_id: options.resource_id,
book_id: options.book_id,
is_content_chat: true,
isShowMore: false,
input_value_content: '',
UserChatList: [],
fixed: true,
isUser: false,
isOpen: false
})
this.data.resource_id = options.resource_id;
this.wssInit()
},
// 获取直播聊天列表
handleGetChatList () {
getChatList({
token: wx.getStorageSync('token'),
resource_id: this.data.resource_id,
book_id: this.data.book_id
}).then(res => {
if (res.data.length > 9) {
this.setData({
isShowMore: true,
chatList: res,
isOpen: false,
})
} else {
this.setData({
chatList: res,
isShowMore: false,
isOpen: false,
})
}
}).catch(err => {
Event.initShowToast(err, this);
})
},
// // 获取输入框value
bindContent(e) {
this.setData({
content: e.detail.value,
send: true
})
if (e.detail.value == '') {
this.setData({
content: e.detail.value,
send: false
})
}
},
// // 下拉获取更多聊天记录
getMoreChatList() {
if (this.data.chatList.min_id == 0) {
wx.showToast({
title: '没有更多记录了哦',
icon: 'none',
duration: 1000
})
return;
}
this.setData({
loading: true
})
getChatList({
token: wx.getStorageSync('token'),
resource_id: this.data.resource_id,
book_id: this.data.book_id,
page_index: 0,
page_size: 10,
start_id: this.data.chatList.min_id
}).then(res => {
// 把之前得到的聊天数据和重新加载的拼接在一起
res.data.reverse().forEach(item => {
this.data.chatList.data.unshift(item)
})
this.data.chatList.min_id = res.min_id;
var that = this;
setTimeout(function () {
that.setData({
chatList: that.data.chatList,
loading: false
})
}, 500)
}).catch(err => {
Event.initShowToast(err, this);
})
},
wssInit () {
var that = this;
this.connectWss();
// 链接失败显示
wx.onSocketError(function (res) {
console.log('WebSocket连接打开失败,请检查!', res);
that.setData({
isOpen: false,
statusMsg: '已断开'
});
});
// 监听连接成功
wx.onSocketOpen(function (res) {
console.log('WebSocket连接已打开!')
that.setData({
isOpen: true,
statusMsg: '已连接'
});
that.handleGetChatList()
wx.onSocketMessage(function (res) {
console.log('收到服务器内容:', res);
var res_data = JSON.parse(res.data);
if (res_data.errcode > 0) {
wx.showToast({
title: '内容涉及敏感信息!',
icon: 'none',
duration: 2000
})
}
if (!res_data.msg && !res_data.rooms) {
that.data.UserChatList.push(res_data)
that.setData({
isUser: true,
UserChatList: that.data.UserChatList
})
setTimeout(function () {
wx.createSelectorQuery().select('#chatContent').boundingClientRect(function (rect) {
that.setData({
scrollTop: rect.height + 100000
})
}).exec()
}, 500)
} else {
wx.showToast({
title: res_data.msg,
icon: 'none',
duration: 3000
})
}
});
wx.sendSocketMessage({
data: JSON.stringify({
token: wx.getStorageSync('token'),
resource_id: that.data.resource_id,
book_id: that.data.book_id,
}),
success: res => {
console.log(res+'发送成功')
},
fail: err=> {
console.log(err+'失败')
}
});
})
},
// 向服务器发送消息
handleSendMessage: function () {
var that = this;
console.log('尝试向服务器发送消息:');
connect()
if (that.data.content.trim() == '') {
wx.showToast({
title: '内容不能为空!',
icon: 'none',
duration: 2000
})
return;
}
wx.sendSocketMessage({
data: JSON.stringify({content:that.data.content}),
success: res => {
that.setData({
input_value_content: '',
content: ''
})
}
});
},
connectWss: function () {
this.setData({
statusMsg: '连接中。。。'
});
connect();
},
})
function connect() {
wx.connectSocket({
url: 'wss://api.tl100.com/wss',
success: function (res) {
console.log('连接成功');
}
});
}
好了,代码就这些,到此已经可以实现实时聊天的效果了