uni-app对接腾讯即时通讯 IM


准备工作
我这用的是无UI集成,可以自己在控制室配置用户模拟测试

参考手册
https://cloud.tencent.com/document/product/269/117335

npm 集成

复制代码
npm install @tencentcloud/lite-chat

index.ts

javascript 复制代码
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-restricted-globals */
/* eslint-disable no-bitwise */
/* eslint-disable no-unused-vars */
import TencentCloudChat from '@tencentcloud/lite-chat'

// 配置项
const options = {
  SDKAppID: 0,// 你的key
}

// 会话类型
const typeArr = [
  TencentCloudChat.TYPES.CONV_C2C,
  TencentCloudChat.TYPES.CONV_GROUP,
]

const chat = TencentCloudChat.create(options) // SDK 实例通常用 chat 表示

/**
 * @name  获取token-登录IM-创建连接
 */
let connectSuccess:any // 连接成功/失败回调
let connectReject:any // 失败回调
let loginResult:any = null // 登录状态
/** 连接登入 */
const loginIm = async () => {
  const loginObj = {
    userID: '生成签名userID',
    userSig: '控制室生成的签名',
  }
  // 先给一个承诺,避免重复调用
  if (loginResult) return loginResult
  loginResult = new Promise((resolve, reject) => {
    connectSuccess = resolve
    connectReject = reject
  })

  // 连接IM
  const connectIm = async () => {
    console.log('%c 开始连接IM', 'color:red')
    const promise = chat.login(loginObj)
    promise.then((imResponse) => {
      console.log('IM:登录成功', imResponse.data)
      if (imResponse.data.repeatLogin) console.log('重复登录。', imResponse.data.errorInfo)
    }).catch((imError) => {
      loginResult = null
      console.warn('IM:登录失败ERR', imError) // 登录失败的相关信息
      connectReject()
    })
  }
  connectIm()

  return loginResult
}

/**
 * @name  为需要登录的方法提供统一的前置检查
 * @param fn
 */
const withLoginCheck = <T extends (...args: any[]) => any>(fn: T): T => ((async (...args: any[]) => {
  await loginIm()
  return fn(...args)
}) as unknown) as T

/**
 * @name  发送私聊|群聊(文本)消息
 * @param {string} o.to     目标用户ID
 * @param {string} o.text   消息内容
 * @param {number} index    消息类型 0-私聊 1-群聊
 */
const sendTextMsg = withLoginCheck(async (o:any, index = 0) => {
  const messages = chat.createTextMessage({
    to: o.to,
    conversationType: typeArr[index],
    payload: {
      text: o.text,
    },
    // 如果您发消息需要已读回执,需购买旗舰版或企业版套餐,并且创建消息时将 needReadReceipt 设置为 true
    needReadReceipt: true,
  })
  const sendRes = await chat.sendMessage(messages)
  console.log('发送成功', sendRes)
  return sendRes
})

/**
 * @name  获取会话列表
 */
const getConversationList = withLoginCheck(async () => {
  const res = await chat.getConversationList({
    type: TencentCloudChat.TYPES.CONV_C2C,
  })
  console.log('拉取会话列表:', res)
  if (res.code === 0) return res.data.conversationList
  return []
})

/**
 * @name  获取未读总数
 * @returns {number} 未读消息总数
 */
const getUnreadMsgCount = withLoginCheck(async () => {
  const res = chat.getTotalUnreadMessageCount()
  console.log('未读消息总数:', res)
  return res
})

/**
 * @name  删除会话
 * C2C${userID}(单聊)
 * GROUP{groupID}(群聊)
 * @TIM#SYSTEM(系统通知会话)
 * 删除单一会话, 并清空会话历史消息
 */
const delConversation = withLoginCheck(async (id:string) => {
  const res = await chat.deleteConversation(id)
  console.log('删除会话', res)
})

/* ====================================
                监听相关
  ======================================== */

// 监听链接
chat.on(TencentCloudChat.EVENT.SDK_READY, () => {
  console.log('%c 链接成功IM', 'color:#39b54a')
  connectSuccess()
})

// 监听消息
chat.on(TencentCloudChat.EVENT.MESSAGE_RECEIVED, (event:any) => {
  // event.data - 存储 Message 对象的数组 - [Message]
  const messageList = event.data
  messageList.forEach((message:any) => {
    if (message.type === TencentCloudChat.TYPES.MSG_TEXT) {
      // 文本消息 - https://web.sdk.qcloud.com/im/doc/v3/zh-cn/Message.html#.TextPayload
      console.log('收到文本消息:', message)
    } else if (message.type === TencentCloudChat.TYPES.MSG_IMAGE) {
      // 图片消息 - https://web.sdk.qcloud.com/im/doc/v3/zh-cn/Message.html#.ImagePayload
      console.log('图片消息:', message)
    } else if (message.type === TencentCloudChat.TYPES.MSG_GRP_TIP) {
      // 群提示消息 - https://web.sdk.qcloud.com/im/doc/v3/zh-cn/Message.html#.GroupTipPayload
      console.log('群提示消息:', message)
    } else if (message.type === TencentCloudChat.TYPES.MSG_GRP_SYS_NOTICE) {
      // 群系统通知 - https://web.sdk.qcloud.com/im/doc/v3/zh-cn/Message.html#.GroupSystemNoticePayload
      const { operationType, userDefinedField } = message.payload
      console.log('群系统通知', operationType, userDefinedField)
    }
  })
})

// 监听会话列表更新事件
chat.on(TencentCloudChat.EVENT.CONVERSATION_LIST_UPDATED, (event:any) => {
  console.log('监听会话列表更新事件', event.data)
})

export const im = {
  loginIm,
  sendTextMsg,
  getConversationList,
  getUnreadMsgCount,
  delConversation,
}

index.vue

bash 复制代码
<template>
  <view class="wxy-page nav">
    <wxy-nav-back :isBack="false" des="即时通讯" />
    <view class="margin-top-md">
      <view class="nav-btn flex-center wxy-btn" @click="im.loginIm()">登录</view>
      <input v-model="content" type="text" class="nav-input margin-top-md" placeholder="请输入消息内容">
      <view class="nav-btn margin-top-md flex-center wxy-btn" @click="sendMsg">发送消息</view>
      <view class="nav-btn margin-top-md flex-center wxy-btn" @click="im.getConversationList()">会话列表</view>
      <view class="nav-btn margin-top-md flex-center wxy-btn" @click="im.getUnreadMsgCount()">未读消息</view>
      <view class="nav-btn margin-top-md flex-center wxy-btn" @click="im.delConversation('C2C1')">删除会话</view>
    </view>
  </view>
</template>

<script setup lang='ts'>
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ref } from 'vue'
import { im } from '@/IM/index'

const content = ref('Hello world!')

const sendMsg = () => {
  const params = {
    to: '2',
    text: content.value,
  }
  im.sendTextMsg(params).then((data) => {
    if (data) {
      console.log('发送成功')
    }
  })
}
</script>

<style lang='scss' scoped>
.nav{
  &-input{
    flex: 1;
    height: 36px;
    margin: 0 10px;
    padding: 0 15px;
    font-size: 16px;
    background-color: #F0F2F7;
    border: 1px solid transparent;
    border-radius: 4px;
  }

  &-btn{
    width: 300rpx;
    height: 80rpx;
    margin: 30rpx auto;
    background: var(--white);
    border-radius: 12rpx;
  }
}
</style>

遇到问题可以看我主页加我,很少看博客,对你有帮助别忘记点赞收藏。

相关推荐
前端Hardy43 分钟前
前端如何防止用户重复提交表单?4 种可靠方案(附防坑指南)
前端·javascript·面试
前端Hardy43 分钟前
用户真的关掉页面了吗?前端精准检测页面卸载的 4 种方法(附避坑指南)
前端·javascript·面试
yangyanping201081 小时前
Vue入门到精通七之关键字const
前端·javascript·vue.js
姝然_95271 小时前
Jetpack Compose 绘制流程与自定义布局
前端
姝然_95271 小时前
Jetpack Compose Brush 渐变
前端
阿鑫_9961 小时前
通用-ESLint+Prettier基础知识
前端·后端
ai超级个体1 小时前
金三银四,一个面试官连连夸赞的个人网页技术分享
前端·面试·three.js·threejs·网页设计·网页灵感·网页分享
Oneslide1 小时前
块级元素竖向堆叠且宽度默认会撑满其父容器的可用宽度
前端
i建模1 小时前
npm使用大全
前端·npm·node.js
李剑一1 小时前
Cesium 实现园区水景!3 种水面效果,Water 材质 5 分钟搞定
前端·vue.js·cesium