本人用的是环信

首先要去环信后台里注册测试账号,替换WebIMConfig.js里的地址。

下载环信demo后,将newSDK文件放到根目录下,WebIM.js和WebIMConfig.js本人放到了utils目录下。

android环信should first set up with conversation 环信uniapp_javascript

android环信should first set up with conversation 环信uniapp_自定义消息_02

在APP.vue文件中,抄案例。  文本消息,自定义消息,会话已读的回调里有未注释的逻辑,先注掉,等到处理消息时再用。

<script>
   import { imLogin } from "@/utils/utils.js";
   //全局注册一个变量
   let WebIM = (wx.WebIM = require("./utils/WebIM")["default"]);

   export default {
		globalData: {
			conn: {
				closed: false,
				curOpenOpt: {},

				open(opt) {
					uni.showLoading({
						title: "正在初始化客户端..",
						mask: true,
					});
					// debugger
					this.curOpenOpt = opt;
					this.closed = false;
				},

				reopen() {
					if (this.closed) {
						WebIM.conn.open(this.curOpenOpt);
						this.closed = false;
					}
				},
			},
		},
        onShow(){
			//切换APP或者息屏再开启,导致im断联,所以要在这里登录一下
			console.log("imshow")
			this.imLogin()
		},
        onLaunch() {
            WebIM.conn.listen({
				onOpened: function() {
				}, //连接成功回调 
				onClosed: function() {
					// 不能登录,在此登录可能会陷入循环登录与退出
					// that.imLogin()
				}, //连接关闭回调
				onTextMessage: function(message) {
					console.log(message)
					if (message) {
						store.dispatch("setMsg", message);
						console.log(message)
					}
					
				}, //收到文本消息
				onEmojiMessage: function(message) {}, //收到表情消息
				onPictureMessage: function(message) {}, //收到图片消息
				onCmdMessage: function(message) {}, //收到命令消息
				onAudioMessage: function(message) {}, //收到音频消息
				onLocationMessage: function(message) {}, //收到位置消息
				onFileMessage: function(message) {}, //收到文件消息
				onCustomMessage: function(message) {
					store.dispatch("setMsg", message);
					console.log(message)
				}, //收到自定义消息
				onVideoMessage: function(message) {
				}, //收到视频消息
				onPresence: function(message) {}, //处理“广播”或“发布-订阅”消息,如联系人订阅请求、处理群组、聊天室被踢解散等消息
				onRoster: function(message) {}, //处理好友申请
				onInviteMessage: function(message) {}, //处理群组邀请
				onOnline: function(message) {
					console.log(message)
				}, //本机网络连接成功
				onOffline: function() {
					console.log(message)
					WebIM.conn.close()
					this.imLogin()
				}, //本机网络掉线
				onError: function(error) {
					console.log(error)
				}, //失败回调
				onBlacklistUpdate: function(list) { //黑名单变动
					// 查询黑名单,将好友拉黑,将好友从黑名单移除都会回调这个函数,list则是黑名单现有的所有好友信息
					console.log(list);
				},
				onRecallMessage: function(message) {}, //收到撤回消息回调
				onReceivedMessage: function(message) {
					console.log(message)
				}, //收到消息送达服务器回执
				onDeliveredMessage: function(message) {
					console.log(message)
				}, //收到消息送达客户端回执
				onReadMessage: function(message) {}, //收到消息已读回执
				onCreateGroup: function(message) {}, //创建群组成功回执(需调用createGroupNew)
				onMutedMessage: function(message) {}, //如果用户在A群组被禁言,在A群发消息会走这个回调并且消息不会传递给群其它成员
				onChannelMessage: function(message) {
					console.log(message)
					let msg  = {
						contentsType:"isRead",
						id:message.from
					}
					store.dispatch("setMsg", msg);
					
				} //收到整个会话已读的回执,在对方发送channel ack时会在这个回调里收到消息
	 		});
        }
   }
</script>

 

 

1.登录

建议封装成函数,因为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)
            }
        });
    }
};

2.发消息

测试代码: 

//创建消息
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
						}
				
					});
			},

3.收消息

思路: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
                }

                
                 
            }
					
},