项目地址是: github.com/lirongrong/… ,
大家可以自行下载,按照提示运行,就能看到效果;现在只是做了要给基本版的,要做复杂功能,可以继续添加。
功能
websorket长连接
是基于nodejs-websocket的服务,代码如下:(最基础版)
var ws = require("nodejs-websocket")
// Scream server example: "hi" -> "HI!!!"
//创建一个server
var server = ws.createServer(function (conn) {
console.log("New connection")
conn.on("text",function (str) {
// console.log("Received "+str)
// conn.sendText(str.toupperCase()+"!!!")
//链接成功之后,发送欢迎语
"连接成功")
//欢迎语
if(str == 'null'){
conn.sendText("有什么能帮到您?");
}
//输入文字
else if(str != 'null' && str){
conn.sendText("文字")
}
//输入多媒体
else{
conn.sendText("多媒体文本")
}
console.log(str);
})
conn.on("close",51); font-weight: 700;">function (code,reason) {
"Connection closed")
})
}).listen(8001)
复制代码
在项目根目录下运行 npm run dev
服务就能启动了, 启动之后websorket地址为: ws://localhost:8001
chat.js
直接看代码,注释都写清楚了
// pages/user/chat.js
var util = '../utils/util.js');
var app = getApp();
//websocket心跳重连对象
let heartCheck = {
timeout: 1000,//1s
timeoutObj: null,serverTimeoutObj: //重置
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},136);">//开始
start: function () {
wx.sendSocketMessage({
data: "null",});
},};
//微信小程序新录音接口,录出来的是aac或者mp3,这里要录成mp3
const recorderManager = wx.getRecorderManager();
const options = {
duration: 600000,136);">//录音时长,这里设置的是最大值10分钟
sampleRate: 44100,numberOfChannels: 1,encodeBitRate: 192000,format: 'mp3',136);">//frameSize: 50
};
//音频播放
const innerAudioContext = wx.createInnerAudioContext()
Page({
data: {
taskId:'',userId:chatList:[],136);">//聊天内容
isShowModelUp:false,136);">//底部弹框显示true,隐藏为false
isLuYin://没有录音false,开始录音true
luYinText:'按住说话',audioUrl://录音文件地址
isShowLuYin://true为开始播放,false为取消播放
inputValue://输入框内容
lockReconnect://默认进来是断开链接的
limit:0,136);">//重连次数
},onLoad: function (options) {
this.linkSocket();
},136);">//连接socket
linkSocket:function(){
let that = this;
wx.connectSocket({
//url: app.globalData.wsUrl + 'websocket?' + this.data.taskId + '&' + this.data.userId,
url:app.globalData.wsUrl,success() {
'连接成功')
wx.onSocketMessage((res) => {
console.log(res.data);
//收到消息
that.pushChatList(text: res.data
});
})
wx.onSocketopen(() => {
'WebSocket连接打开')
heartCheck.reset().start()
})
wx.onSocketError(function (res) {
'WebSocket连接打开失败')
that.reconnect()
})
wx.onSocketClose('WebSocket已关闭!')
that.reconnect()
})
}
})
},136);">//断线重连
reconnect() {
var that = this;
if (that.lockReconnect) return;
that.lockReconnect = true;
clearTimeout(that.timer)
if (that.data.limit < 12) {
that.timer = setTimeout(() => {
that.linkSocket();
that.lockReconnect = false;
},5000);
that.setData({
limit: that.data.limit + 1
})
}
},136);">//打开底部弹框
showModelUp:function(){
var that=this;
if (that.data.isShowModelUp==false){
that.setData({
isShowModelUp: true,})
}else{
that.setData({
isShowModelUp: //关闭底部弹框
closeModelUp:this;
that.setData({
isShowModelUp://选择照片
chooseImage:this;
wx.chooseImage({
count: // 默认9
sizeType: ['original','compressed'],136);">// 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'],136);">// 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths;
console.log(res);
that.pushChatList(imgurl: tempFilePaths,})
//关闭弹窗
that.closeModelUp();
that.pageScrollToBottom();
}
})
},136);">//界面滚到最底端
pageScrollToBottom: function () {
wx.createSelectorQuery().select('#bottom').boundingClientRect(function (rect) {
console.log(rect.top);
console.log(rect.bottom);
// 使页面滚动到底部
wx.pageScrollTo({
scrollTop: rect.bottom + 200
})
}).exec()
},136);">//预览图片
previewImage:function(e){
console.log(e);
var url=e.currentTarget.dataset.src;
this;
wx.previewImage({
current: url[0],136);">// 当前显示图片的http链接
urls: url // 需要预览的图片http链接列表
})
},136);">//拍摄
paishe:this;
wx.chooseImage({
count: 'camera'],51); font-weight: 700;">function (res) {
//发送位置
getlocat: function () {
this
wx.getLocation({
type: 'gcj02',136);">//返回可以用于wx.openLocation的经纬度
success: function (res) {
that.setData({
latitude: res.latitude,longitude: res.longitude,markers: [{
latitude: res.latitude,name: '时代一号',desc: '现在的位置'
}],})
that.pushChatList(map: true
})
}
})
that.closeModelUp();
that.pageScrollToBottom();
},136);">//切换是否录音按钮
btnRecord:if (that.data.isLuYin==false){
that.setData({
isLuYin: true
});
}else{
that.setData({
isLuYin: teral" style="color: rgb(120,luYinText: '按住说话'
});
}
},136);">//开始录音
startRecord:function(e){
this;
that.setData({
luYinText:'录音中...',});
recorderManager.start(options);
recorderManager.onStart(() => {
'recorder start')
})
},136);">//结束录音
stopRecord:this;
that.setData({
luYinText: '按住说话'
});
recorderManager.stop();
recorderManager.onStop((res) => {
'recorder stop',res)
const { tempFilePath } = res;
that.pushChatList(audioUrl: res.tempFilePath,audioDuration: (res.duration / 60000).toFixed(2),136);">//录音时长,转为分,向后取两位,
})
that.setData({
audioUrl: res.tempFilePath,
})
})
//关闭弹窗
that.closeModelUp();
that.pageScrollToBottom();
},136);">//录音、停止播放
playRecord:function(e){
this;
innerAudioContext.autoplay = true;
innerAudioContext.src = that.data.audioUrl
//innerAudioContext.src = 'http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E061FF02C31F716658E5C81F5594D561F2E88B854E81CAAB7806D5E4F103E55D33C16F3FAC506D1AB172DE8600B37E43FAD&fromtag=46';//测试音频文件
if (!e.currentTarget.dataset.isshowluyin){//开始播放
//innerAudioContext.play();//兼容起见用它
innerAudioContext.onPlay(() => {
'开始播放');
that.setData({
isShowLuYin: true
});
return;
});
}else{//暂停播放
innerAudioContext.pause();
"暂停");
that.setData({
isShowLuYin: false
});
return;
}
},136);">//输入框点击完成按钮时触发
btnConfirm:function(e){
if (typeof (e) == 'undefined' || e.detail.value == ''){
return false;
}else {
var value = e.detail.value;
that.pushChatList(text: value
});
that.setData({
inputValue:''//清空输入框
})
//发送数据
wx.sendSocketMessage({
data: value
})
//关闭弹窗
that.closeModelUp();
that.pageScrollToBottom();
}
},136);">//页面隐藏/切入后台时触发
onHide:function(){
wx.onSocketClose(function (res) {
'WebSocket已关闭!')
})
},136);">//页面卸载时触发
onUnload:'WebSocket已关闭!')
})
},136);">//pushchatList
//enu:0 是客服发送的消息
//enu:1 是我发送的消息
pushChatList:function(enu,options){
var defaults = {
userImage: text: isAdmin: teral" style="color: rgb(120,}
options = util.extendobj(defaults,options);
options.time = util.formatDateTime(util.getNowFormatDate());
console.log(options);
if(enu == 0){
options.userImage = '../images/admin.png';
options.isAdmin = false;
}if(enu==1){
options.userImage = app.globalData.wxUserInfo.avatarUrl;
options.isAdmin = true;
}
var t = that.data.chatList;
t.push(options)
that.setData({
chatList: t
});
}
})
复制代码
需要优化的地方
- 上传图片应该要支持多图上传并压缩一下,我做h5的聊天功能的时候压缩了,这个简版的小程序没做,大家可以自行加上
- 这个demo只是实现了UI和文字的通讯,图片、视频、地图等的通讯还没完善
- 发送消息之后滚到底部的方法需要改进,因为发送图片、地图、语音没有滚到底部
- 需要改进的请大神指点
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。