首先要去环信后台里注册测试账号,替换WebIMConfig.js里的地址。
在APP.vue文件中,抄案例。 文本消息,自定义消息,会话已读的回调里有未注释的逻辑,先注掉,等到处理消息时再用。
建议封装成函数,因为im会中途断开,后续很多地方需要用到登录。
在APP登录成功之后,调用环信登录
// 环信密码登录
export const imLoginPassword = function imLoginPassword(uid) {
uni.WebIM.conn.open({
appKey: "1122230110163975#inliao",
pwd: "password",
user: uid,
success: (res) => {
const {
access_token
} = res
uni.setStorageSync('imToken', access_token)
}
});
};
// 环信token登录
export const imLogin = function imLogin() {
let uid = uni.getStorageSync('userUuid')
if (uid) {
console.log(uid)
uni.WebIM.conn.open({
appKey: "1122230110163975#inliao",
accessToken: uni.getStorageSync('imToken'),
user: uid,
success: (res) => {
const {
access_token
} = res
uni.setStorageSync('imToken', access_token)
}
});
}
};
测试代码:
//创建消息
let msg = uni.WebIM.message.create({
type: "txt",
// 消息内容。
// msg: this.chatContent,
msg: "11111",
// 消息接收方:单聊为对方用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。
to: '123', //测试时可以写死
// 会话类型:单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`,默认为单聊。
chatType: "singleChat",
});
//发送消息
uni.WebIM.conn.send(msg).then((e) => {
console.log("Send message success", e);
})
.catch((e) => {
console.log("send error")
});
发消息时,im可能已经断联,会导致消息发不出去,在catch里监听发送错误码,然后重发。
imSend(msg){
uni.WebIM.conn
.send(msg)
.then((e) => {
console.log("Send message success", e);
})
.catch((e) => {
// 重新登录
if (e.type == 39) {
imLogin()
let timer33 = setTimeout(()=>{
clearTimeout(timer33)
this.imSend(msg,messageList)
},3000)
return
}
// 重新登录 510断开连接
if (e.type == 510) {
console.log(510)
imLogin()
let timer33 = setTimeout(()=>{
clearTimeout(timer33)
this.imSend(msg,messageList)
},3000)
return
}
});
},
思路:app.vue里收到消息后,在vuex里处理:存储的消息内容根据具体情况。只是提供一种处理思路。
state: {
//聊天列表
xiaoxiliebiao: [],
//消息内容(每个人的聊天内容)
xiaoxineirong: [],
},
actions: {
async setMsg({ state }, msg){
//自己的id
let currentUserUuid = uni.getStorageSync("userUuid");
console.log(msg)
//收到消息后,处理消息列表和消息内容
state.xiaoxiliebiao=[]
state.xiaoxineirong=[]
//从本地取聊天列表
if (uni.getStorageSync(currentUserUuid + "msglist").length != 0&&
JSON.parse(uni.getStorageSync(currentUserUuid + "msglist"))[0]!=null) {
state.xiaoxiliebiao = JSON.parse(
uni.getStorageSync(currentUserUuid + "msglist")
);
}
//此处对消息类型判断,做不同的处理,例如文本消息,图片消息,自定义消息
if (msg.contentsType == "TEXT"){
//循环判断本地聊天列表,判断有没有跟这个人聊过天
let isnew = true;
// 如果有,更新列表
state.xiaoxiliebiao.forEach((p) => {
console.log(msg.from , p.userUuid)
if(msg.from == p.id){
p.messageContent: msg.data,
p.time = TimestampFormat(msg.time-0);
p.userHeadPortraitUrl = msg.ext.groupImg;
p.unreadNum +=1
isnew = false;
return;
}
})
// 如果没有,把该用户加入聊天列表
if (isnew == true) {
state.xiaoxiliebiao.unshift({
id: msg.from,
name: msg.ext.groupName, //自定义消息,发送者昵称
time: TimestampFormat(msg.time-0), //消息时间
userUuid: msg.from, //发送者id
userHeadPortraitUrl: msg.ext.groupImg, //自定义消息,发送者头像
isnew: 1, //是否是新消息
unreadNum:1, //有多少未读消息
messageContent: msg.data, //消息内容
isTop: 0, //是否置顶
type: '',//类型:单聊还是群聊
});
}
//把聊天列表存到本地
uni.setStorageSync(
currentUserUuid + msg.from,
JSON.stringify(state.xiaoxineirong)
);
//===================================================================
if (uni.getStorageSync(currentUserUuid + msg.from).length != 0) {
state.xiaoxineirong = JSON.parse(
uni.getStorageSync(currentUserUuid + msg.from)
);
}
let msgLastTime;
if (state.xiaoxineirong.length==0) {
//在第一次聊天时,需要添加时间,所以给0
msgLastTime = 0
} else{
msgLastTime = state.xiaoxineirong[state.xiaoxineirong.length-1].timeline
}
state.lastMsgTime = msg.time;
state.chatTime = new Date().getTime();
// 如果距离上一次聊天已过去三分钟,插入一条时间
if (Math.abs(state.chatTime - msgLastTime) > 180000) {
state.xiaoxineirong.push({
direction: "chatTime",
chatTime: TimestampFormat(state.lastMsgTime-0),
messageUuid: msg.ext.messageUuid + "time",
timeline: state.lastMsgTime,
time: msg.time,
});
}
console.log(customObj)
//把收到的消息存起来
state.xiaoxineirong.push({
direction: "chatLeft", //用来在聊天页判断是发送还是收到
name: msg.ext.userName, //自定义消息,存昵称
fromUserUuid: msg.from, //自定义消息,存发送者昵称
toUserUuid: msg.to, //自定义消息,存接收者昵称
messageUuid: msg.ext.messageUuid,
messageContent: msg.data, //消息内容
customObj: customObj, //存自定义消息
userHeadPortraitUrl: msg.ext.headImg, //自定义消息,存头像
read: 0, //是否已读
time: msg.time, //消息时间
});
//把消息存到本地
uni.setStorageSync(
currentUserUuid + msg.from,
JSON.stringify(state.xiaoxineirong)
);
}
}
}
在聊天页:
正在和某用户聊天,借用computed和watch监听vuex里消息的改变,判断和正在聊天的人是不是同一人,如果是更新聊天列表。 此处还要做消息分页,聊天列表置底,已读回调等操作。
data(){
return {
msgList: [],//消息
}
}
computed: {
msgList2() {
// this.sendIsRead()
console.log(this.$store.state.xiaoxineirong)
return this.$store.state.xiaoxineirong;
},
},
watch: {
msgList2: {
deep: true,
handler(newVal, oldVal) {
console.log(newVal)
//此处判断后台 Websocket接收到的数据是否为本用户,如果是本用户,立即宣染数据
if(this.$store.state.curUserId == this.toUserUuid){
if (uni.getStorageSync(this.currentUserUuid + this.toUserUuid).length !=0) {
list = JSON.parse(
uni.getStorageSync(this.currentUserUuid + this.toUserUuid)
);
}
this.msgList = list
}
}
},