最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue集成融云实现即时通讯聊天室

    正文概述 掘金(凉城a)   2021-04-28   555

    前言

    最近把Vue+Element二次封装持续完善了,然后开始着手处理即时通讯这一块了。

    之前的老代码用的是融云2.x版本,现在4.x了,自然要更新下,融云4.x变化还是挺大的,很多API都换掉了,但是相对来讲还是比较简单上手的。

    由于没有原型图,我直接边设计办coding,对于这种自己发挥的需求,我仍然保持微笑。(这应该是对我审美的肯定吧!)先整了个样图出来如下

    Vue集成融云实现即时通讯聊天室

    接下来咱们步入正题

    分析需求

    项目是一个社交APP的后台管理项目,项目中有个模块是关于聊天室的,链接APP内的聊天大厅,如果有用户发布不良信息,可以禁言用户,同时也可以发布公告消息。

    任务

    1. 获取token,链接融云
    2. 获取历史消息并模拟聊天展示出来
    3. 发送消息,这个是由后端完成,我发送消息就请求接口
    4. 可以禁言用户,这个也是由后端来统一完成

    关于融云

    融云提供的即时通讯服务,不需要在 App 之外建立并行的用户体系,不用同步 App 下用户信息到融云,不影响 App 现有的系统架构与帐号体系,与现有业务体系能够实现完美融合。

    兼容说明

    ChromeFirefoxSafariIEEdgeQQ 浏览器微信 浏览器Android
    9+

    导入 SDK

    NPM 引入(推荐)

    1. 依赖安装
    npm install @rongcloud/imlib-v4
    
    1. 代码集成
    // 非 ESModule
    const RongIMLib = require('@rongcloud/imlib-v4')
    // ESModule
    import * as RongIMLib from '@rongcloud/imlib-v4'
    

    CDN 引入

    • index.html
    <script src="https://cdn.ronghub.com/RongIMLib-4.3.latest.js"></script>
    

    App Key

    App Key 是使用 IMLib 进行即时通讯功能开发的必要条件,也是应用的唯一性标识。在集成使用 IMLib 之前,请务必先通过 融云开发者后台 (opens new window)注册并获取开发者的专属 App Key

    只有在 App Key 相同的情况下,不同用户之间的消息才有可能互通。

    初始化

    IMLib 提供的所有能力基于 IMLib 初始化后获取的实例对象,因此在使用 IMLib 的能力之前,必须先调用 IMLib 的初始化接口,且务必保证该接口在应用全生命周期内仅被调用一次。

    // 应用初始化以获取 RongIMLib 实例对象,请务必保证此过程只被执行一次
    const im = RongIMLib.init({ appkey: '<Your-App-Key>' });
    

    设置监听

    初始化完成后,应在建立连接之前对 im 对象添加事件监听器,及时获取相关事件通知。

    // 添加事件监听
    im.watch({
      // 监听会话列表变更事件
      conversation (event) {
        // 假定存在 getExistedConversationList 方法,以获取当前已存在的会话列表数据
        const conversationList = getExistedConversationList()
        // 发生变更的会话列表
        const updatedConversationList = event.updatedConversationList;
        // 通过 im.Conversation.merge 计算最新的会话列表
        const latestConversationList = im.Conversation.merge({ conversationList, updatedConversationList })
      },
      // 监听消息通知
      message (event) {
        // 新接收到的消息内容
        const message = event.message;
      },
      // 监听 IM 连接状态变化
      status (event) {
        console.log('connection status:', event.status);
      },
      // 监听聊天室 KV 数据变更
      chatroom (event) {
        /**
         * 聊天室 KV 存储数据更新
         * @example
         * [
         *  {
         *    "key": "name",
         *    "value": "我是小融融",
         *    "timestamp": 1597591258338, 
         *    "chatroomId": "z002", 
         *    "type": 1 // 1: 更新( 含:修改和新增 )、2: 删除
         *  },
         * ]
         */
        const updatedEntries = event.updatedEntries
      },
      expansion (event) {
        /**
         * 更新的消息拓展数据
         * @example {
         *    expansion: { key: 'value' },      // 设置或更新的扩展值
         *    messageUId: 'URIT-URIT-ODMF-DURR' // 设置或更新扩展的消息 uid
         * }
         */
        const updatedExpansion = event.updatedExpansion;
        /**
         * 删除的消息拓展数据
         * @example {
         *    deletedKeys: ['key1', 'key2'],    // 设置或更新的扩展值
         *    messageUId: 'URIT-URIT-ODMF-DURR' // 设置或更新扩展的消息 uid
         * }
         */
        const deletedExpansion = event.deletedExpansion;
    });
    
    

    建立 IM 连接

    App Key 是应用的唯一性标识,Token 则是用户的唯一性标识,是用户连接融云 IM 服务所必需的身份凭证。Token 一般由开发者的应用服务器调用融云 Server API 获取 Token 接口获取之后,由应用服务器下发到应用客户端。

    我的这个token是从后端获取的,然后存储到本地,用的时候看看过期没,过期了就重新获取。相当于前端只进行部分交互。

    • 获取token
        // 获取token
        getIMToken() {
          getIMToken().then(res => {
            var time = new Date().getTime()
            res.time = time
            // 将token保存下来
            this.gobalToken = res
            var tokenStr = JSON.stringify(res)
            localStorage.setItem('token', tokenStr)
            // 初始化融云
            this.linkToRongs(res.data)
          })
        },
        // 判断token是否过期
        isToken() {
          var now = new Date().getTime()
          // 获取上一次存储的token
          var oldToken = JSON.parse(localStorage.getItem('token'))
          // 判断之前获取的token
          if (oldToken) {
            var tokenTime = oldToken.time
            // 判断时间是否过期了
            if (now - tokenTime > 29 * 24 * 60 * 60 * 1000) {
              this.getIMToken()
            } else {
              this.gobalToken = JSON.parse(localStorage.getItem('token'))
              this.linkToRongs(this.gobalToken.data)
              return
            }
          }
          this.getIMToken()
        }
    
    • 建立连接
    im.connect({ token: '<Your-Token>' }).then(user => {
      console.log('链接成功, 链接用户 id 为: ', user.id);
    }).catch(error => {
      console.log('链接失败: ', error.code, error.msg);
    });
    

    获取会话列表

    IMLib 通过会话数据中的 conversationTypetargetId 两个属性值来标识会话的唯一性,对于两个属性的定义如下:

    1. conversationType 用来标识会话类型(如:单聊、群聊...),其值为 RongIMLib.CONVERSATION_TYPE 中的常量定义
    2. targetId 用来标识与本端进行对话的人员或群组 Id:
    • conversationType 值为 RongIMLib.CONVERSATION_TYPE.PRIVATE,targetId 为对方用户 Id
    • conversationType 值为 RongIMLib.CONVERSATION_TYPE.GROUP,targetId 为当前群组 Id
    • conversationType 值为 RongIMLib.CONVERSATION_TYPE.CHATROOM,targetId 为聊天室 Id
    // 获取会话列表
    im.Conversation.getList().then(conversationList => {
      console.log('获取会话列表成功', conversationList);
    }).catch(error => {
      console.log('获取会话列表失败: ', error.code, error.msg);
    });
    
    

    发送消息

    // 获取指定会话的抽象实例,对于会话的操作基于此实例完成
    const conversation = im.Conversation.get({
      // targetId
      targetId: '<TargetId>',
      // 会话类型:RongIMLib.CONVERSATION_TYPE.PRIVATE | RongIMLib.CONVERSATION_TYPE.GROUP
      type: '<Conversation-Type>'
    });
    // 向会话内发消息
    conversation.send({
      // 消息类型,其中 RongIMLib.MESSAGE_TYPE 为 IMLib 内部的内置消息类型常量定义
      messageType: RongIMLib.MESSAGE_TYPE.TEXT, // 'RC:TxtMsg'
      // 消息内容
      content: {
        content: 'Hello RongCloud' // 文本内容
      }
    }).then(function(message){
      console.log('发送文字消息成功', message);
    }).catch(error => {
      console.log('发送文字消息失败', error.code, error.msg);
    });
    
    

    接收消息

    当本端作为消息接收的一方,所接收的消息将通过 im.watch() 注册的消息监听向业务层抛出。具体可参考上述 设置监听 部分

    获取历史消息

    const conversation = im.Conversation.get({
      targetId: '<TargetId>',
      type: '<Conversation-Type>'
    });
    const option = {
      // 获取历史消息的时间戳,默认为 0,表示从当前时间获取
      timestamp: +new Date(),
      // 获取条数,有效值 1-20,默认为 20
      count: 20,
    };
    conversation.getMessages(option).then(result => {
      const list = result.list;       // 获取到的消息列表
      const hasMore = result.hasMore; // 是否还有历史消息可获取
      console.log('获取历史消息成功', list, hasMore);
    }).catch(error => {
      console.log('发送文字消息失败', error.code, error.msg);
    });
    
    

    断开连接

    im.disconnect().then(() => console.log('断开链接成功'));
    

    实战运用

    token拿到手,往前走一走

    created() {
        this.isToken()
     }
     methods:{
    // 获取token
        getIMToken() {
          getIMToken().then(res => {
            var time = new Date().getTime()
            res.time = time
            // 将token保存下来
            this.gobalToken = res
            var tokenStr = JSON.stringify(res)
            localStorage.setItem('token', tokenStr)
            // 初始化融云
            this.linkToRongs(res.data)
          })
        },
        // 判断token是否过期
        isToken() {
          var now = new Date().getTime()
          // 获取上一次存储的token
          var oldToken = JSON.parse(localStorage.getItem('token'))
          // 判断之前获取的token
          if (oldToken) {
            var tokenTime = oldToken.time
            // 判断时间是否过期了
            if (now - tokenTime > 29 * 24 * 60 * 60 * 1000) {
              this.getIMToken()
            } else {
              this.gobalToken = JSON.parse(localStorage.getItem('token'))
              this.linkToRongs(this.gobalToken.data)
              return
            }
          }
          this.getIMToken()
        },
    }
    

    init初始化,话话道心好好听

    一般测试服一个appkey,正式服一个appkey。这个appkey需要自己去申请

     // 链接融云
     linkToRongs(token) {
        const that = this
        let RongClientKey
        if (process.env.VUE_APP_BASE_API2 === '') {//测试服
        RongClientKey = '4215151sadasas'
        } else {//正式服
        RongClientKey = 'adsada12asda1a'
        }
        // 应用初始化以获取 RongIMLib 实例对象,请务必保证此过程只被执行一次
        // eslint-disable-next-line no-undef
        that.rongyun = RongIMLib.init({ appkey: RongClientKey })
    }
    

    监听先行开路,链接随后就到

    初始化完成后,应在建立连接之前对 im 对象添加事件监听器,及时获取相关事件通知。

     // 链接融云
     linkToRongs(token) {
        const that = this
        let RongClientKey
        if (process.env.VUE_APP_BASE_API2 === '') {//测试服
        RongClientKey = '4215151sadasas'
        } else {//正式服
        RongClientKey = 'adsada12asda1a'
        }
        // 应用初始化以获取 RongIMLib 实例对象,请务必保证此过程只被执行一次
        // eslint-disable-next-line no-undef
        that.rongyun = RongIMLib.init({ appkey: RongClientKey })
        const im = that.rongyun
        // 添加事件监听
          im.watch({
            // 监听会话列表变更事件
            conversation(event) {
              // 假定存在 getExistedConversationList 方法,以获取当前已存在的会话列表数据
              const conversationList = that.getExistedConversationList(im)
              // 发生变更的会话列表
              const updatedConversationList = event.updatedConversationList
              // 通过 im.Conversation.merge 计算最新的会话列表
              const latestConversationList = im.Conversation.merge({ conversationList, updatedConversationList })
              console.log(latestConversationList)
            },
            // 监听消息通知
            message(event) {
              //初始化消息都在这
              // 新接收到的消息内容
              const message = event.message
              console.log(message)
            },
            // 监听 IM 连接状态变化
            status(event) {
              console.log('connection status:', event.status)
            },
            // 监听聊天室 KV 数据变更
            chatroom(event) {
              const updatedEntries = event.updatedEntries
              console.log('聊天室 KV 存储数据更新', updatedEntries)
            }
          })
    }
    

    链接融云先用key,长驱直入无人拦

     // 链接融云
     linkToRongs(token) {
        const that = this
        let RongClientKey
        if (process.env.VUE_APP_BASE_API2 === '') {//测试服
        RongClientKey = '4215151sadasas'
        } else {//正式服
        RongClientKey = 'adsada12asda1a'
        }
        // 应用初始化以获取 RongIMLib 实例对象,请务必保证此过程只被执行一次
        // eslint-disable-next-line no-undef
        that.rongyun = RongIMLib.init({ appkey: RongClientKey })
        const im = that.rongyun
        // 添加事件监听
          im.watch({
            // 监听会话列表变更事件
            conversation(event) {
              // 假定存在 getExistedConversationList 方法,以获取当前已存在的会话列表数据
              const conversationList = that.getExistedConversationList(im)
              // 发生变更的会话列表
              const updatedConversationList = event.updatedConversationList
              // 通过 im.Conversation.merge 计算最新的会话列表
              const latestConversationList = im.Conversation.merge({ conversationList, updatedConversationList })
              console.log(latestConversationList)
            },
            // 监听消息通知
            message(event) {
              //初始化消息都在这
              // 新接收到的消息内容
              const message = event.message
              console.log(message)
            },
            // 监听 IM 连接状态变化
            status(event) {
              console.log('connection status:', event.status)
            },
            // 监听聊天室 KV 数据变更
            chatroom(event) {
              const updatedEntries = event.updatedEntries
              console.log('聊天室 KV 存储数据更新', updatedEntries)
            }
          })
          // 建立 IM 连接
          const chatRoomId = '627865222'
          var count = 50 // 数量
          im.connect({ token: token }).then(user => {
            this.$message.success('加入聊天室成功')
            console.log('链接成功, 链接用户 id 为: ', user.id)
            var chatRoom = im.ChatRoom.get({
              id: chatRoomId
            })
            chatRoom.join({
              count: count // 进入后, 自动拉取 20 条聊天室最新消息
            }).then(function() {
              console.log('加入聊天室成功')
              chatRoom.getInfo().then(function(result) {
                var userCount = result.userCount
                var user = that.uniq(that.messageList)
                // 刷选用户
                user.map(item => {
                  that.list.push(item.user)
                })
                that.num = userCount
              })
            })
          }).catch(error => {
            this.$message.success('加入聊天室失败')
            console.log('链接失败: ', error.code, error.msg)
          })
    }
    

    最后一步最重要,退出聊天要及时

    切换页面时,一定要退出聊天厅,不然下次加入聊天厅无法获取之前的消息。当然你也可以获取历史消息,我尝试获取历史消息一直报错,所以才选择打开页面加入,结束就离开。(不退出的话会一直保持连接)

    destroyed() {
        var chatRoom = this.rongyun.ChatRoom.get({
          id: '聊天室id'
        })
        chatRoom.quit().then(function() {
          console.log('退出聊天室成功')
        })
      }
    

    结尾

    即时通讯这一块做起来还是蛮有意思的,总有一些意料之外的事情发生。

    最后把源码放在了github

    融云官方文档


    起源地下载网 » Vue集成融云实现即时通讯聊天室

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元