Uniapp 快速集成环信即时通讯应用

820 阅读2分钟

创建uniapp项目

  • 通过HbuilderX可视化界面(推荐)
  • 使用vue-cli命令行创建(确保全局安装了vue-cli)
    vue create -p dcloudio/uni-preset-vue my-project (vue2)
    npx degit dcloudio/uni-preset-vue#vite my-vue3-project (vue3)

区别:
cli创建的项目,是传统的node项目结构。工程代码在src目录下,编译器在项目下,编译结果在dist目录下。
HBuilderX可视化创建的项目,是一种免node开发概念。工程代码在项目目录下,编译器在HBuilderX目录下而不是项目下,编译结果在项目的unpackage 目录下。

使用Uniapp构建环信即时通讯应用

DEMO地址

实现功能:

  • 登录
  • 注册
  • 添加好友
  • 收发图片消息

首先, 我们需要引入环信小程序sdk

import webIM from "../sdk/uniapp-sdk-4.1.2";

/**
 * 以下配置信息可从console后台管理获得 即时通讯/服务概览/域名配置
 */
 
const IM_CONFIG = {
  isHttpDNS: false, // 开启后会从服务器取连接地址,目前不支持uniapp、小程序
  appKey: "1161210719091872#demo",
  apiUrl: "https://a1.easemob.com",
  url: "ws://im-api-wechat.easemob.com/websocket"
};

const conn = new webIM.connection(IM_CONFIG);
uni.conn = conn; // 将conn挂在到全局

这样我们就完成了sdk的初始化。

在使用的过程中需要将appKey替换为你自己的appKey。

监听SDK事件, SDK事件列表

uniapp内置了vuex,使用vuex存储了uid和msglist的Map对象, 消息展示时根据当前uid获取msglist。

// 监听消息事件
conn.addEventHandler("message", {
  onTextMessage: (message) => {
    // 表示是多端同步过来的消息,收到消息push到vuex
    let uid = message.from === uni.conn.user ? message.to : message.from;
    store.commit("pushMessage", { uid, msg: message });
  },
  onImageMessage: (message) => {
    let uid = message.from === uni.conn.user ? message.to : message.from;
    store.commit("pushMessage", { uid, msg: message });
  }
});
// 监听好友事件
conn.addEventHandler("contact", {
  onContactInvited: (message) => {
    console.log(message, "contact invite msg");
    uni.showModal({
      title: `${message.from}请求添加好友`,
      content: message.status,
      cancelText: "拒绝",
      confirmText: "接受",
      success: (res) => {
        if (res.confirm === true) {
          // 接受好友申请
          conn.acceptContactInvite(message.from);
        } else {
          // 拒绝好友申请
          conn.declineContactInvite(message.from);
        }
      }
    });
  },
  onContactAgreed: (message) => {
    console.log(message, "contact agreed msg");
    uni.showToast({
      icon: "none",
      title: `${message.from}已同意你的好友申请`
    });
  },
  onContactRefuse: (message) => {
    console.log(message, "contact refuse msg");
    uni.showToast({
      icon: "none",
      title: `${message.from}已拒绝你的好友申请`
    });
  }
});

conn.addEventHandler("eventType", {}), eventType为用户自定义事件名称

登录功能

      conn
        .open({
          user: this.user,
          pwd: this.pwd
        })
        .then(() => {
          // 跳转首页
          uni.switchTab({
            url: "../contacts/index"
          });
          uni.showToast({
            icon: "none",
            title: "登录成功"
          });
        })
        .catch((e) => {
          if (e.data.data.error_description === "invalid password") {
            uni.showToast({
              icon: "none",
              title: "用户名或密码错误"
            });
          } else {
            uni.showToast({
              icon: "none",
              title: "登录失败"
            });
          }
        })
        .finally(() => {
          this.loading = false;
        });

注册功能

通过SDK注册用户,需要在Console控制台将该appKey的用户注册模式设置为 开放注册

 conn
        .registerUser({
          username: this.user,
          password: this.pwd
        })
        .then(() => {
          uni.showToast({
            icon: "none",
            title: "注册成功"
          });
          uni.redirectTo({
            url: "../index/index"
          });
        })
        .catch((e) => {
          uni.showToast({
            icon: "none",
            title: "注册失败"
          });
        })
        .finally(() => {
          this.loading = false;
        });

添加好友功能

    // this.uid为环信uid
    addContact() {
      conn.addContact(this.uid, "加个好友吧~");
    }

获取好友列表

    getContacts() {
      uni.conn.getContacts().then((res) => {
        // 展示联系人列表
        this.contacts = res.data;
        console.log(res);
      });
    },

发送文本消息

    import webIM from "../../sdk/uniapp-sdk-4.1.2";
    import { IM_CONFIG } from "../../utils/initIm";
    import { MSG_TYPE } from "../../consts";
    
    // methods 
    sendTextMsg() {
      let textMsg = webIM.message.create({
        chatType: "singleChat",
        msg: this.msg,
        to: this.to,
        type: MSG_TYPE.txt
      });
      uni.conn.send(textMsg).then((res) => {
        this.$store.commit("pushMessage", {
          uid: this.to,
          msg: textMsg
        });
        this.msg = "";
      });
    }
    

发送图片消息

发送附件消息,需要将附件上传后,拿到上传后的URL,去创建附件消息,然后发送。 如果没有自己的文件服务器,可以上传到环信的文件服务器。文档

      import webIM from "../../sdk/uniapp-sdk-4.1.2";
      import { IM_CONFIG } from "../../utils/initIm";
      import { MSG_TYPE } from "../../consts";
      
      // methods
      
      selectImg() {
      let _this = this;
      const opt = {
        count: 1, // 默认9
        sizeType: ["original", "compressed"], // 可以指定是原图还是压缩图,默认二者都有
        sourceType: ["album"], // 从相册选择
        success: function (res) {
          let tempFilePath = res.tempFilePaths[0];
          var str = IM_CONFIG.appKey.split("#");
          var token = uni.conn.context.accessToken;
          // 上传文件到环信服务器
          uni.uploadFile({
            url: `${IM_CONFIG.apiUrl}/${str[0]}/${str[1]}/chatfiles`,
            filePath: tempFilePath,
            name: "file",
            header: {
              Authorization: `Bearer ${token}`
            },
            success(res) {
              let dt = JSON.parse(res.data);
              let uuid = dt.entities[0].uuid;
              let imgUrl = `${dt.uri}/${uuid}`;
              // Web端需要在 WebIMConfig.js中 设置 useOwnUploadFun: true
              const imgMsg = webIM.message.create({
                chatType: "singleChat",
                type: MSG_TYPE.img,
                url: imgUrl,
                to: _this.to
              });
              uni.conn.send(imgMsg).then((res) => {
                _this.$store.commit("pushMessage", {
                  uid: _this.to,
                  msg: imgMsg
                });
              });
            }
          });
        }
      };

      uni.chooseImage(opt);
    },

DEMO开发完毕,我们可以将其运行到小程序、h5、APP等平台,这样你就拥有了一个自己的即时通讯APP

DEMO 演示: