uniapp接融云即时通讯IM

因为融云含ui的聊天室并不适用于uniapp,所以uniapp中所有东西就需要自己来实现,好在融云给的接口还是很全的,因为项目的差异性我只介绍聊天室的代码(因为没做任何优化,可能代码可读性并不强,而且只实现了发送文字信息的功能,分享出来只是方便自己看,接不通可以私信我)
在开始聊天之前需要先连接融云的im(main.js中)


//引入融云SDK
const RongIMib = require('./common/libs/RongIMLib-3.0.7.1-dev.js')
const RongIMLib = require('./common/libs/RongEmoji-2.2.9.js')

//初始化融云SDK
let im = RongIMib.init({
    appkey: ""//申请的key
})
Vue.prototype.$Im = im
//挂载融云到Vue原型
Vue.prototype.$RongIMib = RongIMib
Vue.prototype.$RongIMLib=RongIMLib

可以在首页打印下判断是否连接成功
我是在首页连接的融云,连接的话只一次就可以,可以在登录成功后连接,我感觉在登录成功后连接更好(刚开始就连接就好,不用监听,在会话列表里已经监听过了) 注意:连接融云需要token,这时候需要读后端的接口拿到

rongyunInit() {
            //初始化融云
            // let _that = this;
            //设置监听
            // let conversationList = []; //当前存在的会话列表
            // _that.$Im.watch({
            //  //对会话列表进行监听
            //  conversation: event => {
            //      console.log(event);
            //      let updatedConversationList = event.updatedConversationList; //更新的会话列表
            //      console.log('upload:', updatedConversationList);
            //      let sendOut = {
            //          content: event.updatedConversationList[0].latestMessage.content.content,
            //          sentTime: event.updatedConversationList[0].latestMessage.sentTime
            //      };
            //      uni.setStorageSync('sendOut', sendOut);
            //      if (event.updatedConversationList[0].latestMessage.messageDirection == 2) {
            //          this.chat.push({
            //              type: event.updatedConversationList[0].latestMessage.messageDirection,
            //              time: event.updatedConversationList[0].latestMessage.sentTime,
            //              msg: event.updatedConversationList[0].latestMessage.content.content,
            //              avatar: uni.getStorageSync('user_info').avatar
            //          });
            //      }
            //  },
            //  status: function(event) {
            //      let status = event.status;
            //      console.log('status num:', status);
            //  }
            // });
            /**
             * 3.连接融云
             *   1) 需要先调用服务端接口,获取Token 然后进行连接
             */
            //进行连接
            this.$Im
                .connect({
                    token: uni.getStorageSync('rong_token')
                })
                .then(user => {
                    console.log('success id: ', user.id);
                })
                .catch(error => {
                    console.log('error: ', error.code, error.msg);
                });
        },

聊天室代码.js文件

export default {
    name: 'index',
    data() {
        return {
            chat: [],
            sentText: '',
            doctorInfo: '',
            height: '0rpx',
            scrollTop: 0,
            count: 7,
            uuid: '',
            avatar: '',
            list: [],
            style: {
                pageHeight: 0,
                contentViewHeight: 0,
                footViewHeight: 90,
                mitemHeight: 0
            },
        };
    },
    onLoad(options) {
        this.uuid = options.uuid
        this.avatar = options.avatar
        this.rongyunInit();
        this.getlist(new Date())
        const res = uni.getSystemInfoSync(); //获取手机可使用窗口高度     api为获取系统信息同步接口
        this.style.pageHeight = res.windowHeight;
        this.style.contentViewHeight = res.windowHeight - uni.getSystemInfoSync().screenWidth / 750 * (100); //像素   因为给出的是像素高度 然后我们用的是upx  所以换算一下 
    },
    onShow() {
        this.chat = []
        this.clear()
    },
    methods: {
        read(uuid, time) {
            let conversation = this.$Im.Conversation.get({
                targetId: this.uuid,
                type: this.$RongIMib.CONVERSATION_TYPE.PRIVATE
            });
            let messageUId = uuid; // 消息唯一 Id, message 中的 messageUid
            let lastMessageSendTime = time; // 最后一条消息的发送时间
            let type = '1'; // 备用,默认赋值 1 即可
            // 以上 3 个属性在会话的最后一条消息中可以获得
            conversation.send({
                messageType: 'RC:ReadNtf',
                content: {
                    messageUId: messageUId,
                    lastMessageSendTime: lastMessageSendTime,
                    type: type
                }
            }).then((message) => {
                console.log('发送已读通知消息成功', message);
            });
        },
        scrolltoupper() {
            this.$u.throttle(this.getlist(this.chat[0].time, 1), 500)
        },
        // 清空未读数
        clear() {
            this.$Im.Conversation.getTotalUnreadCount().then(function(totalUnreadCount) {
              console.log('获取未读总数成功', totalUnreadCount);
            });
            let conversation = this.$Im.Conversation.get({
                targetId: this.uuid,
                type: this.$RongIMib.CONVERSATION_TYPE.PRIVATE
            });
            conversation.read().then(()=> {
                console.log('清除未读数成功'); // im.watch conversation 将被触发
            });
        
        },
        scrollToBottom() {
            let that = this;
            let query = uni.createSelectorQuery();
            query.selectAll('.m-item').boundingClientRect();
            query.select('#scrollview').boundingClientRect();
            query.exec((res) => {
                console.log(res)
                that.style.mitemHeight = 0;
                res[0].forEach((rect) => that.style.mitemHeight = that.style.mitemHeight + rect.height + 40) //获取所有内部子元素的高度
                // 因为vue的虚拟DOM 每次生成的新消息都是之前的,所以采用异步setTimeout    主要就是添加了这定时器
                setTimeout(() => {
                    if (that.style.mitemHeight > (that.style.contentViewHeight - 100)) { //判断子元素高度是否大于显示高度
                        console.log(3333)
                        that.scrollTop = that.style.mitemHeight - that.style.contentViewHeight //用子元素的高度减去显示的高度就获益获得序言滚动的高度
                    }
                }, 100)
            })
        },
        // #ifdef APP-PLUS
        hgit() {
            this.height = '50rpx'
        },
        // #endif
        // #ifdef H5
        hgit() {
            this.height = '500rpx'
        },
        // #endif
        blur() {
            this.height = '0rpx'
        },
        rongyunInit() {
            //初始化融云
            let _that = this;
            //设置监听
            let conversationList = []; //当前存在的会话列表
            _that.$Im.watch({
                //对会话列表进行监听
                conversation: (event) => {
                    let updatedConversationList = event.updatedConversationList; //更新的会话列表
                    console.log('upload用户端:', updatedConversationList);
                    let sendOut = {
                        content: event.updatedConversationList[0].latestMessage.content.content,
                        sentTime: event.updatedConversationList[0].latestMessage.sentTime
                    }
                    uni.setStorageSync('sendOut', sendOut)
                    if (event.updatedConversationList[0].latestMessage.messageDirection == 2) {
                        console.log('执行了')
                        this.chat.push({
                            type: event.updatedConversationList[0].latestMessage.messageDirection,
                            time: event.updatedConversationList[0].latestMessage.sentTime,
                            msg: event.updatedConversationList[0].latestMessage.content.content,
                            avatar: uni.getStorageSync('user_info').avatar
                        })
                    }
                },
                status: function(event) {
                    let status = event.status;
                    console.log('status num:', status);
                }
            });
            /**
             * 3.连接融云
             *   1) 需要先调用服务端接口,获取Token 然后进行连接
             */
            //进行连接
            // this.$Im
            //  .connect({
            //      token: uni.getStorageSync('rong_token')
            //  })
            //  .then(user => {
            //      console.log('success id: ', user.id);
            //  })
            //  .catch(error => {
            //      console.log('error: ', error.code, error.msg);
            //  });
        },
        // 获取历史信息
        getlist(time, status) {
            console.log(time, status)
            let conversation = this.$Im.Conversation.get({
                targetId: this.uuid,
                type: this.$RongIMib.CONVERSATION_TYPE.PRIVATE
            });
            let option = {
                timestrap: +time,
                count: this.count
            };
            conversation.getMessages(option).then((result) => {
                this.list = result.list; // 历史消息列表
                let hasMore = result.hasMore; // 是否还有历史消息可以获取
                console.log('获取历史消息成功', this.list, hasMore);
                // this.read(this.list.length.messageUId, this.list.length.sentTime)
                this.read(this.list[this.list.length-1].messageUId, this.list[this.list.length-1].sentTime)
                // data == 1下拉加载
                if (status == 1) {
                    let a = []
                    this.list.forEach(item => {
                        if (item.messageDirection == 1) {
                            a.push({
                                type: item.messageDirection,
                                time: item.sentTime,
                                msg: item.content.content,
                                avatar: uni.getStorageSync('user_info').avatar
                            })
                        } else {
                            a.push({
                                type: item.messageDirection,
                                time: item.sentTime,
                                msg: item.content.content,
                                avatar: this.avatar
                            })
                        }
                    })
                    console.log(2342342,a)
                    this.chat.unshift(...a)
                    console.log(this.chat)
                }else{
                    this.list.forEach(item => {
                        if (item.messageDirection == 1) {
                            this.chat.push({
                                type: item.messageDirection,
                                time: item.sentTime,
                                msg: item.content.content,
                                avatar: uni.getStorageSync('user_info').avatar
                            })
                        } else {
                            this.chat.push({
                                type: item.messageDirection,
                                time: item.sentTime,
                                msg: item.content.content,
                                avatar: this.avatar
                            })
                        }
                    })
                }
                console.log(this.chat)
            });
        },
        //融云发送消息方法
        sendMessage(type, content) {
            //4.连接融云成功后进行发送消息
            this.conversation = this.$Im.Conversation.get({
                targetId: this.uuid,
                type: this.$RongIMib.CONVERSATION_TYPE.PRIVATE
            });
            this.conversation.send({
                messageType: this.$RongIMib.MESSAGE_TYPE[type],
                content
            }).then((msg) => {
                this.scrollToBottom(); //创建后调用回到底部方法
                console.log('发送消息成功', msg);
                this.chat.push({
                    type: msg.messageDirection,
                    time: msg.sentTime,
                    msg: msg.content.content,
                    avatar: uni.getStorageSync('user_info').avatar
                })
                this.sentText = []
            }).catch(err => {
                console.log('消息发送失败', err)
            })
        },
    }
};

.vue文件

<template>
    <view class="mh100p pd20 pb100" :style="{height: 100+'%'}">
        <share title="即时通讯" />
        <scroll-view id="scrollview" @scrolltoupper='scrolltoupper' class="chat-window pb100" scroll-y="true" :style="{ height: style.contentViewHeight + 'px' }" :scroll-with-animation="true" :scroll-top="scrollTop">
            <view class="my20 m-item" v-for="(item, index) in chat" :key="index">
                <view class="cl999 ftr26 mb20 u-text-center">{{ item.time | date('yyyy.mm.dd hh:MM:ss') }}</view>
                <view class="yc" :class="item.type == 1 ? 'rever' : ''">
                    <u-avatar mode="square" :src="item.avatar"></u-avatar>
                    <view class="chat-box">{{ item.msg }}</view>
                </view>
            </view>
        </scroll-view>
        <view class="fix-wrap bgfff px30 py20 pb50" :style="{ bottom: height }">
            <u-search
                placeholder="请输入发送内容"
                search-icon="edit-pen"
                action-text="发送"
                v-model="sentText"
                @focus="hgit"
                @blur="blur"
                @custom="sendMessage('TEXT', { content: sentText })"
                @search="sendMessage('TEXT', { content: sentText })"
            ></u-search>
        </view>
    </view>
</template>

<script>
import index from './index.js';
export default index;
</script>

<style lang="scss" scope>
@import './index.scss';
</style>

.css文件(用的ui库是uview)

.chat-box {
    padding: 20upx;
    margin: 0 16upx;
    background-color: #ffffff;
    border-radius: 12upx;
}
.rever {
    flex-direction: row-reverse;
    .chat-box {
        background-color: #f8e271;
    }
}
.fix-wrap {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    height: 100upx;
}
/deep/ .u-input__input {
    background-color: #f4f4f4;
    border-radius: 20upx;
    padding: 0 20upx;
}

即时通讯接起来还是挺麻烦的,走一遍之后就还好,该有的api都有所提供,因为我是直接拿的项目里的,可能并不适用于你们

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容