基于融云即时通讯实现即时通讯,(文字发送,表情发送, 文件上传, 音视频聊天) 上

1,632 阅读3分钟

项目介绍

项目使用vue作为前端框架,融于IM SDK为即时通讯提供坚强后盾,主要功能有以下两个大点:

  1. 单聊:发送文字,图片,文件,表情,展示未读消息,音视频邀请(邀请弹框和铃声提示)
  2. 群聊:发送文字,图片,文件,表情,展示未读消息,@某人,群音视频邀请(邀请弹框和铃声提示)

简单介绍下融云的几个比较重要的sdk

  1. 文字和表情的发送首先要引入
 <script src="https://cdn.ronghub.com/RongIMLib-2.9.latest.js"></script>
 <script src="https://cdn.ronghub.com/RongEmoji-2.2.7.js"></script> -->

进行IM初始化,公有云用户的appkey,可以自己在官网申请

import { Message } from 'view-design'
import { appConfig } from '../appConfig';
export default function init(userInfo, callbacks) {
    if (!userInfo.token) {
        return false;
    }
    const options = {
        navi: appConfig.appImNav, // 私有部署配置,公有云用户可忽略
        logLevel: 0
    }
    const config = {
        size: 25,
        url: "//f2e.cn.ronghub.com/sdk/emoji-48.png",
        lang: "en",
        extension: {
          dataSource: {
            u1F914: {
              // 自定义 u1F914 对应的表情
              en: "thinking face", // 英文名称
              zh: "思考", // 中文名称
              tag: "🤔", // 原生 Emoji
              position: "0 0", // 所在背景图位置坐标
            },
          },
          url: "//cdn.ronghub.com/thinking-face.png", // 新增 Emoji 背景图 url
        },
      };
    RongIMLib.RongIMEmoji.init(config);
    //私有云初始化
    RongIMLib.RongIMClient.init(appConfig.appKey, null, options);
    var instance = RongIMClient.getInstance();
  
    //连接状态监听器
    RongIMClient.setConnectionStatusListener({
        onChanged: function (status) {
            switch (status) {
                case RongIMLib.ConnectionStatus.CONNECTED:
                    callbacks.CONNECTED && callbacks.CONNECTED(instance);
                    break;
                case RongIMLib.ConnectionStatus.CONNECTING:
                    Message.info('IM正在链接');
                    break;
                case RongIMLib.ConnectionStatus.DISCONNECTED:
                    Message.info('IM断开连接');
                    break;
                case RongIMLib.ConnectionStatus.KICKED_OFFLINE_BY_OTHER_CLIENT:
                    Message.info('其他设备登录');
                    break;
                case RongIMLib.ConnectionStatus.DOMAIN_INCORRECT:
                    Message.info('域名不正确');
                    break;
                case RongIMLib.ConnectionStatus.NETWORK_UNAVAILABLE:
                    Message.info('网络不可用');
                    break;
            }
        }
    });


    RongIMClient.setOnReceiveMessageListener({
        // 接收到的消息
        onReceived: function (message) {
            console.log('rongcloud-message'+ message)
            callbacks.Received && callbacks.Received(message);
        }
    });


    //开始链接
    RongIMClient.connect(userInfo.token, {
        onSuccess: function (id) {
            callbacks.Success && callbacks.Success(id);
        },
        onTokenIncorrect: function () {
            Message.warning('token无效');
        },
        onError: function (errorCode) {
            var info = '';
            switch (errorCode) {
                case RongIMLib.ErrorCode.TIMEOUT:
                    info = '超时';
                    break;
                case RongIMLib.ErrorCode.UNKNOWN_ERROR:
                    info = '未知错误';
                    break;
                case RongIMLib.ErrorCode.UNACCEPTABLE_PaROTOCOL_VERSION:
                    info = '不可接受的协议版本';
                    break;
                case RongIMLib.ErrorCode.IDENTIFIER_REJECTED:
                    info = 'appkey不正确';
                    break;
                case RongIMLib.ErrorCode.SERVER_UNAVAILABLE:
                    info = '服务器不可用';
                    break;
            }
            Message.warning(errorCode)
        }
    });

}

然后可以在主页面中引入init方法,并且传入callback

    let callbacks = {
      CONNECTED: function () { 
         console.log('im链接') // 此处可以获取会话列表
      },
      Success: function (id) {
         console.log('IM连接成功') // 
      },
      Received: async function (message) {
       console.log('接收到新消息') // 接收到消息的时候进行相关逻辑处理
      },
    };
    init(userInfo, callbacks);
  1. 发送文字消息或者表情 (代码大致罗列,不是完整代码,其他逻辑可以自己整理)
// 关于表情包,引入上述sdk之后,在页面中可以直接拿到表情包列表,然后再html中进行渲染就行
<div
  class="emoji-item"
  v-for="(item, index) in emojList"
  :key="index"
  v-html="item.node.outerHTML"
  @click="checkedEmoji(item.symbol)"
></div>

// 初始化中获取emojiList
this.emojList = RongIMLib.RongIMEmoji.list
// 点击表情包获取表情元素
checkedEmoji(symbol) {
  this.stat.sendMsgVal += RongIMLib.RongIMEmoji.symbolToEmoji(symbol); // 表情包需要RongIMLib.RongIMEmoji.symbolToEmoji解析
  this.emojiShow = false;
},
// 发送文字消息或者表情消息
const text = '这里是输入的表情或者文字' // 上文中提到的this.state.sendMsgVal
let msg = new RongIMLib.TextMessage({
      content: RongIMLib.RongIMEmoji.symbolToEmoji(text),
      extra: "附加信息",
});
 RongIMClient.getInstance().sendMessage(
        conversationType, // 会话类型 1单聊 3私聊
        targetId, // 发送的目标
        msg, // 发送的内容
        {
          onSuccess: async function (message) {
           console.log('发送成功')
          },
        },
 );
  1. 上传图片或者文件(需要单独引入上传sdk,我是私有云,公有云可以看相应文档)
    <script src="./js/up/rc.js"></script>
    <script src="./js/up/upload.js"></script>
    <script src="./js/up/init.js"></script>

上传文件的方法 file是上传的二进制文件流 type是区分图片还是文件

    uploadFile(file, type) {
      let _this = this;
      let fileType,
        size = 0;
      if (type === "img") {
        fileType = RongIMLib.FileType.IMAGE;
      } else if (type === "file") {
        fileType = RongIMLib.FileType.FILE;
        size = file.size;
      }

      let config = {
        domain: `${appConfig.appImUpload}`, // 上传文件的服务地址 公有云是七牛云
        fileType,
        getToken: function (callback) {
          let caback = {
            onSuccess: function (data) {
              console.log(data, 'data token')
              callback(data.token);
            },
            onError: function (error) {
              _this.$Message.warning("get file token error");
            },
          };
          RongIMClient.getInstance().getFileToken(fileType, caback, undefined);
        },
      };

      let uploadCallbacks = {
        onProgress: function (loaded, total) {
           // 上传进度
        },
        // 上传完毕
        onCompleted: function (data) {
          if (type === "img") {
            // 发送图片消息
            let msg = new RongIMLib.ImageMessage({
              content: data.thumbnail,
              imageUri: `${appConfig.appImUpload}${data.rc_url.path}`,
              extra: "",
            });
            _this.sendMsg(msg);
          } else if (type === "file") {
            // 我是私有云 所以这样取name和type 公有云可以看文档
            let dataArr = data.rc_url.path && data.rc_url.path.split("/");
            const name = dataArr[dataArr.length - 1];
            const type = dataArr[dataArr.length - 1].split(".")[1];
            let fileContent = {
              name: decodeURI(name),
              size: (size / 1024).toFixed(1) + "kB",
              type: type,
              fileUrl: `${appConfig.appImUpload}${data.rc_url.path}`,
            };
            // 发送文件消息
            let msg = new RongIMLib.FileMessage(fileContent);
            _this.sendMsg(msg);
          }
  
        },
        onError: function (error) {
          // 上传失败
        },
      };
      if (type === "img") {
        UploadClient.initImage(config, function (uploadFile) {
          uploadFile.upload(file, uploadCallbacks);
        });
      } else if (type === "file") {
        UploadClient.initFile(config, function (uploadFile) {
          uploadFile.upload(file, uploadCallbacks);
        });
      }
    },

至此,实现一个简单的聊天已经可行,剩下的有空再写吧,有疑问可以私聊我或者评论。