vue 腾讯IM示例

最近要做一个聊天功能 以前公司是webScoket实现的聊天与推送 现在用的腾讯im

me的git仓库 感兴趣可以下载试一下 -b ceche

功能只有单对单在线聊天 离线推送需要购买 就不要买了 用的时候看文档吧 基本功能就是 发送消息给对方 知道对方是不是已读 别人发消息过来 告诉别人是不是已读

这次项目架构采用的是腾讯IM即时通讯 所以简单看一下 实现一下小功能
首先呢先注册登录腾讯云

文档使用时还是使用无ui的 有ui的成套的在发现问题和修改时候不太好改 而且项目ui都不同改的也麻烦
  1. 腾讯云地址 可以使用微信注册 然后进入个人中心实名验证一下就可以了
  2. 进入应用管理 如果找不到可以进入首页 搜素“即时通讯IM”点击就跳进去了
  3. 创建新的应用 创建完成后会有 SDKAppID密钥 后边项目需要使用的 因为我是自己用所以我注册的是个人用户
  4. 创建完成后进入 功能服务-> 账号管理 上边下拉框选择你需要的应用名称 之后点击新建账号 账号的用户名是一个唯一值 也就是在这个应用下允许搜索 添加 登录的用户 不在这个应用下是查不到用户的 还有昵称和头像链接不是必填的 这里user1 和user2就是等一下需要登录的用户在这里插入图片描述
  5. 然后 我们基本配置就结束了接下来 我们可以下载官方提供的demo 也可以自己写demo
  6. 腾讯云下载中心,找到Demo源码 gitee下载 不同系统选择不同的链接 我是window的所以我跳到7的地址
  7. 找到web文件夹下的md文件 下边有一个相关链接 打开gitee仓库clone项目
  8. 下载完成后 选中vue2 或者vue3安装 启动 这里使用刚刚创建的用户 user2就会进入聊天界面 一个在线用户就创建好了在这里插入图片描述
  9. 另一个用户 这里开始创建项目了
  10. npm create vite@latest demo npm install npm run dev启动
npm install @tencentcloud/chat    
npm install tim-upload-plugin --save
npm i pinia  // 不想用也可以自定义hooks
  1. 创建一个index 这里有一个config文件夹 这个文件夹需要在第8步骤的vue文件夹里 有一个debug文件夹 。chat-uikit-vue/Vue2/TUIKit/debug/。 里的所有文件
    ‘GenerateTestUserSig.js’ 、‘index.d.ts’、‘index.js’、‘lib-generate-test-usersig-es.min.js’
    在这里插入图片描述
    增加个添加好友和搜素用户 ---- 这个添加搜索 可以看这里的SDKapi写其他方法 这个添加 之前使用个人用户一直报错 我不确定是不是需要企业用户才能做一些别的操作 这里测试自测
main.ts
import { ref } from 'vue';
import { createPinia, defineStore } from 'pinia';
import tim from '@tencentcloud/chat';
import TIMUploadPlugin from 'tim-upload-plugin';
import { genTestUserSig } from './config/index'
export type timLoginType = { userID: string }
export type sendType = { toWHom: string, msgType?: 'text' | 'data', msgValue: any, conversationType?: 'C2C' | 'GROUP' | 'ROOM' }
export type messageType = { name: string, data: any[] }
export type searchUserId = { userId: string }
export type addFirendType = { toId: string, AddType?: 'Request' | 'Confirm', remark?: string, groupName?: string }
const win = window as any
// 添加好友参数格式
function addFirendOptionData(param: addFirendType) {
    return {
        wording: TIMOption.value.userID,
        to: param?.toId || '',
        type: param?.AddType || 'Request',
        source: 'AddSource_Type_Web',
        groupName: param?.groupName || '',
        remark: param?.remark || ''
    };
}
// 项目实例的id和key 用户必须在统一的项目管理下才会查到用户 实行方案 在注册用户时就调用接口向腾讯im管理添加用户名
export const TIMOption = ref<any>({
    SDKAppID: 0,
    secretKey: '',
})
export const useTIMStore = defineStore('useTIMStore', () => {
    // 可发送状态
    const isPrepare = ref<boolean>(false)
    const onPrepare = () => {
        const { TIM, CHAT } = win?.timObj
        let onSdkReady = function () {
            isPrepare.value = true
        };
        CHAT.on(TIM.EVENT.SDK_READY, onSdkReady);
    }
    // 初始化
    const createTIM = () => {
        let chat = tim.create(TIMOption.value);
        chat.setLogLevel(2);
        chat.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin });
        win.timObj = { TIM: tim, CHAT: chat }
        onPrepare()
    }
    // 登录
    const isLogin = ref<boolean>(false)
    const onLogin = async ({ userID }: timLoginType) => {
        const { CHAT } = win?.timObj
        const signoptions = { SDKAppID: TIMOption.value.SDKAppID, secretKey: TIMOption.value.secretKey, userID: userID }
        const { userSig } = genTestUserSig(signoptions)
        TIMOption.value.userID = userID
        try {
            TIMOption.value.userID = userID
            await CHAT.login({ userID: userID, userSig: userSig });
            isLogin.value = true
        } catch (e) {
            isLogin.value = false
        }
        return isLogin.value
    }
    // 登出
    const onLogout = async () => {
        try {
            const { CHAT } = win?.timObj
            await CHAT.logout();
            isLogin.value = false
        } catch { }
    }
    // 发送消息
    const onSend = async ({ toWHom, msgType = 'text', msgValue, conversationType = 'C2C' }: sendType) => {
        if (isPrepare.value) {
            if (!msgValue) {
                return { code: 99999, message: '不能是空', data: null, problem: 'customLog-onSend::: 空值' }
            }
            const { CHAT } = win?.timObj
            let res = null
            console.log(msgType);
            
            if (msgType === 'data') {
                let message = CHAT.createCustomMessage({
                    to: toWHom,
                    conversationType: conversationType,
                    payload: {
                        [msgType]: JSON.stringify(msgValue),
                        description: '自定义消息说明',
                        extension: ''
                    }
                });
                res = await CHAT.sendMessage(message)
            }
            if (msgType === 'text') {
                let message = CHAT.createTextMessage({
                    to: toWHom,
                    conversationType: conversationType,
                    payload: { [msgType]: msgValue }
                });
                res = await CHAT.sendMessage(message)
            }
            if (res?.code === 0) {
                return res
            } else {
                return false
            }
        } else {
            return false
        }
    }
    // 发送消息对方已阅
    const onMessageRead = (callback: Function) => {
        const { TIM, CHAT } = win?.timObj
        if (callback && typeof callback === 'function') {
            const onMessageReadByPeer = function (e: messageType) {
                callback(e?.data || [])
            };
            CHAT.on(TIM.EVENT.MESSAGE_READ_BY_PEER, onMessageReadByPeer);
            return true
        } else {
            return false
        }
    }
    // 接收消息
    const onMessage = (callback: Function) => {
        const { TIM, CHAT } = win?.timObj
        if (callback && typeof callback === 'function') {
            let onMessageReceived = function (e: messageType) {
                callback(e?.data || [])
            };
            CHAT.on(TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived);
            return true
        } else {
            return false
        }
    }
    // 接收消息返回已阅
    const onReceipt = (item: any) => {
        const { CHAT } = win?.timObj;
        const msg = { conversationID: item.conversationID, messageID: item.ID };
        CHAT.setMessageRead(msg)
    }
    // 搜索用户
    const onSearchUser = async ({ userId }: searchUserId) => {
        const { CHAT } = win.timObj
        try {
            const { data } = await CHAT.getUserProfile({ userIDList: [userId] })
            return data
        } catch (e) {
            return []
        }
    }

    // 申请添加好友
    const onAddFirend = async ({ toId }: addFirendType) => {
        const { CHAT } = win.timObj
        try {
            const param = addFirendOptionData({ toId: toId, AddType: 'Request' })
            const { data } = await CHAT.addFriend(param)
            return data
        } catch (e) {
            return false
        }
    }
    // 确认添加好友
    const onConfirmAddFirend = async ({ userId }: searchUserId) => {
        const { CHAT } = win.timObj
        try {
            const param = addFirendOptionData({ toId: userId, AddType: 'Confirm' })
            const { data } = await CHAT.addFriend(param)
            return data
        } catch (e) {
            return false
        }
    }
    // 查询好友列表
    const onSearchFirendList = async () => {
        const { CHAT } = win.timObj
        try {
            const res = await CHAT.getFriendList()
            return res?.data
        } catch {
            return []
        }
    }
    return {
        TIMOption,
        isPrepare,
        createTIM,
        onLogin,
        onLogout,
        onSend,
        onMessage,
        onReceipt,
        onMessageRead,
        onSearchFirendList,
        onAddFirend,
        onConfirmAddFirend,
        onSearchUser
    }
})
export {
    createPinia
}
vue文件 简单看一下效果 这里登录就是user1了

登录传入username 调用index里的 GenerateTestUserSig.js 里抛出的genTestUserSig方法返回sig值 然后进行登录

<template>
  <div style="width: 100%;height:100%">
    <!-- 登录 -->
    <div><input type="text" v-model="username"><button @click="login">login</button></div>
    <!-- 搜索用户信息 -->
    <div><span>搜索用户:</span>{{ searchUserData?.nick }} <span v-if="searchUserData?.nick" @click="addFirend">添加</span>
    </div>
    <div style="display: flex;">
      <div style="flex: 1;border: 1px solid #000;">
        <!-- 搜索用户 -->
        <div style="border: 1px solid #000;">
          <input type="text" v-model="firendValue"> <span @click="handlAddFirend">搜索</span>
        </div>
        <div>
          <!-- 好友列表 -->
          <div>好友</div>
          <div v-for="(item, index) in firendList" :key="index">
            <div v-html="item"></div>
          </div>
        </div>
      </div>
      <div style="flex: 2;">
        <div style="height: 200px;overflow-y: auto; display: flex; border: 1px solid #000;">
          <!-- 消息信息 -->
          <div v-for="(item, index) in list" :key="index">
            {{ JSON.stringify(item) }}
          </div>
        </div>
        <!-- 发送 -->
        <div style="display: flex; border: 1px solid #000;">
          <input style="flex:1" type="text" v-model="mesValue">
          <span @click="send">send</span>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useTIMStore, type messageType } from './index'
const TIMStore = useTIMStore()
const username = ref<string>('user1039' || 'user1') // 本人用户名
const firendValue = ref<string>("user1011" || 'user1') // 添加好友的用户名
const firendList = ref<any>([]) // 好友列表
const mesValue = ref<string>('') // 发送的消息
const list = ref<any>([]) // 消息列表
const searchUserData = ref<any>({}) // 搜索用户结果
const login = async () => {
  const res = await TIMStore.onLogin({ userID: username.value })
  if (res) {
    setTimeout(async () => {
      firendList.value = await TIMStore.onSearchFirendList()
    }, 100);
  }
}
login()
// 接收消息
TIMStore.onMessage((e: messageType['data']) => {
  list.value.push(e[0].payload.text)
  setTimeout(() => {
    // 发送我已阅读
    TIMStore.onReceipt(e[0])
  }, 1000);
})
// 接收已经对方阅读的消息
TIMStore.onMessageRead(() => {
})
// 发送
const send = async () => {
  const { data }: any = await TIMStore.onSend({ toWHom: '', msgType: 'text', msgValue: mesValue.value })
  list.value.push(data?.message?.payload.text)
}
// 查找用户
const handlAddFirend = async () => {
  const res = await TIMStore.onSearchUser({ userId: firendValue.value })
  searchUserData.value = res?.[0]
}
// 添加
const addFirend = async () => {
  const res = await TIMStore.onAddFirend({ toId: searchUserData.value?.userID })

}
</script>

<style scoped></style>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值