目录
初始化sdk
功能描述
初始化
准备 SDKAppID
调用初始化接口
监听事件
发送消息
创建消息
创建文本消息
登录登出
功能描述
登录
登出
销毁
登录设置
获取会话列表
功能描述
获取会话列表
获取全量的会话列表
历史消息
功能描述
拉取消息列表
分页拉取指定会话的消息列表
根据指定的消息 sequence 或消息时间跳拉会话的消息列表
接收消息
功能描述
监听事件
取消监听事件
总结
初始化sdk
功能描述
在使用 IM SDK 的各项功能前,必须先进行初始化。
初始化
初始化 SDK 需要操作以下步骤:
- 准备 SDKAppID。
- 调用
TIM.create
初始化 SDK。 - 添加 SDK 事件监听器。
下面我们将分步骤依次为您详细讲解。
准备 SDKAppID
您必须拥有正确的 SDKAppID,才能进行初始化。
SDKAppID 是腾讯云 IM 服务区分客户帐号的唯一标识。我们建议每一个独立的 App 都申请一个新的 SDKAppID。不同 SDKAppID 之间的消息是天然隔离的,不能互通。
您可以在 即时通信 IM 控制台 查看所有的 SDKAppID,单击 创建新应用,可以创建新的 SDKAppID。
调用初始化接口
操作完上述步骤后,您可以调用 TIM.create 初始化 SDK。
接口
TIM.create(options);
参数 options 为 Object 类型,包含的属性值如下:
Name | Type | Description |
---|---|---|
SDKAppID | Number | 即时通信 IM 应用的 SDKAppID |
public tim: ChatSDK | undefined
private initTimSdk(SDKAppID: number) {
let options = {
SDKAppID,// 接入时需要将0替换为您的即时通信 IM 应用的 SDKAppID
};
// 创建 SDK 实例,`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
let tim = TIM.create(options); // SDK 实例通常用 tim 表示
// 设置 SDK 日志输出级别,详细分级请参见 setLogLevel https://web.sdk.qcloud.com/im/doc/zh-cn/SDK.html#setLogLevel 接口的说明</a>
tim.setLogLevel(0); // 普通级别,日志量较多,接入时建议使用
// tim.setLogLevel(1); // release 级别,SDK 输出关键信息,生产环境时建议使用
// 注册腾讯云即时通信 IM 上传插件
tim.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin })
this.tim = tim
}
监听事件
SDK 进入 ready 状态时触发,接入侧监听此事件,然后可调用 SDK 发送消息等 API,使用 SDK 的各项功能
// 监听sdk准备完成的事件
private bindTIMEvent() {
this.tim?.on(TIM.EVENT.SDK_READY, this.handleSDKReady, this)
}
SDK 收到推送的单聊、群聊、群提示、群系统通知的新消息,接入侧可通过遍历 event.data 获取消息列表数据并渲染到页面
private handleSDKReady = () => {
console.log('sdk准备完成');
this.onReady()
console.log('执行');
this.tim?.on(TIM.EVENT.MESSAGE_RECEIVED, this.handleMessageReceived, this)
}
private handleMessageReceived = (event: TextMessageEvent) => {
console.log('接收到消息', event);
this.messageReceived(event)
}
public messageReceived = (event: TextMessageEvent) => { }
发送消息
创建消息
创建文本消息
创建文本消息的接口,此接口返回一个消息实例,可以在需要发送文本消息时调用 发送消息 接口发送消息实例。
接口
tim.createTextMessage(options);
参数
参数 options 为 Object 类型,包含的属性值如下:
Name | Type | Default | Description |
---|---|---|---|
to | String | - | 消息接收方的 userID 或 groupID |
conversationType | String | - | 会话类型,取值TIM.TYPES.CONV_C2C (端到端会话)或TIM.TYPES.CONV_GROUP (群组会话) |
priority | String | TIM.TYPES.MSG_PRIORITY_NORMAL | 消息优先级 |
payload | Object | - | 消息内容的容器 |
cloudCustomData | String | '' | 消息自定义数据(云端保存,会发送到对端,程序卸载重装后还能拉取到,v2.10.2起支持) |
payload 的描述如下:
Name | Type | Description |
---|---|---|
text | String | 消息文本内容 |
返回值
消息实例 Message。
示例
private getMessageOptions = (userID: string, payload: ITextPayload) => {
return this.tim?.createTextMessage({
to: userID,
conversationType: TIM.TYPES.CONV_C2C,
// 消息优先级,用于群聊(v2.4.2起支持)。如果某个群的消息超过了频率限制,后台会优先下发高优先级的消息,详细请参考:https://cloud.tencent.com/document/product/269/3663#.E6.B6.88.E6.81.AF.E4.BC.98.E5.85.88.E7.BA.A7.E4.B8.8E.E9.A2.91.E7.8E.87.E6.8E.A7.E5.88.B6)
// 支持的枚举值:TIM.TYPES.MSG_PRIORITY_HIGH, TIM.TYPES.MSG_PRIORITY_NORMAL(默认), TIM.TYPES.MSG_PRIORITY_LOW, TIM.TYPES.MSG_PRIORITY_LOWEST
// priority: TIM.TYPES.MSG_PRIORITY_NORMAL,
payload,
// v2.20.0起支持C2C消息已读回执功能,如果您发消息需要已读回执,需购买旗舰版套餐,并且创建消息时将 needReadReceipt 设置为 true
needReadReceipt: true
// 消息自定义数据(云端保存,会发送到对端,程序卸载重装后还能拉取到,v2.10.2起支持)
// cloudCustomData: 'your cloud custom data'
})
}
public sendMessage = async (userID: string, payload: ITextPayload) => {
// 创建消息
const messOption = this.getMessageOptions(userID, payload)
await this.tim?.sendMessage(messOption!)
console.log('发送成功');
}
public sendMessage = async (userID: string, payload: ITextPayload) => {
// 创建消息
const messOption = this.getMessageOptions(userID, payload)
await this.tim?.sendMessage(messOption!)
console.log('发送成功');
}
返回 消息实例 Message。
登录登出
功能描述
用户登录 IM SDK 才能正常收发消息,登录需要用户提供 UserID、UserSig 等信息,具体含义请参见 登录鉴权。
登录
注意:
- 登录成功,需等待 sdk 处于 ready 状态后(监听事件 TIM.EVENT.SDK_READY)才能调用 sendMessage 等需要鉴权的接口。
- 如需支持多实例登录(允许在多个网页中同时登录同一帐号),请登录 即时通信 IM 控制台,找到相应 SDKAppID,选择应用配置>功能配置>登录与消息>登录设置>Web 端可同时在线个数配置实例个数。配置将在5分钟内生效。
接口
tim.login(options);
参数
参数 options 为 Object 类型,包含的属性值如下:
名称 | 类型 | 描述 |
---|---|---|
userID | String | 用户 ID。 |
userSig | String | 用户登录即时通信 IM 的密码,其本质是对 UserID 等信息加密后得到的密文。 具体生成方法请参见 生成 UserSig。 |
返回值
Promise
对象。
示例
public timLogin = async (options: TIMCoreLoginParams) => {
//第一步登录sdk
await this.tim?.login(options)
// 持久化相关密钥
localStorage.setItem('TIMCoreLoginParams', JSON.stringify(options))
this.userID = options.userID
this.bindTIMEvent()
}
实例生成后缓存登录态
private persistedLogin = () => {
console.log('缓存');
const TIMCoreLoginParams = JSON.parse(localStorage.getItem('TIMCoreLoginParams') || '{}')
if (TIMCoreLoginParams.userID) {
console.log('存在登录');
this.timLogin(TIMCoreLoginParams)
}
}
登出
登出即时通信 IM,通常在切换帐号的时候调用,清除登录态以及内存中的所有数据。
注意:
- 调用此接口的实例会发布 SDK_NOT_READY 事件,此时该实例下线,无法收、发消息。
- 如果您在即时通信 IM 控制台配置的“Web 端实例同时在线个数”大于 1,且同一帐号登录了
a1
和a2
两个实例(含小程序端),当执行a1.logout()
后,a1
会下线,无法收、发消息。而a2
实例不会受影响。- 多实例被踢:基于第 2 点,如果“Web 端实例同时在线个数”配置为 2,且您的某一帐号已经登录了
a1
,a2
两个实例,当使用此帐号成功登录第三个实例a3
时,a1
或a2
中的一个实例会被踢下线(通常是最先处在登录态的实例会触发),这种情况称之为“多实例被踢”。假设a1
实例被踢下线,a1
实例内部会执行登出流程,然后抛出KICKED_OUT事件,接入侧可以监听此事件,并在触发时跳转到登录页。此时a1
实例下线,而a2
、a3
实例可以正常运行。
接口
tim.logout();
参数
无
返回值
Promise
对象。
示例
let promise = tim.logout();
promise.then(function(imResponse) {
console.log(imResponse.data); // 登出成功
}).catch(function(imError) {
console.warn('logout error:', imError);
});
销毁
销毁 SDK 实例,包括:登出,断开长连接,并释放所有资源。
接口
tim.destroy();
参数
无
返回值
Promise
对象。
示例
tim.destroy().then(() => {
console.log('sdk destroyed');
});
关闭监听
public unBindTIMEvent = () => {
this.tim?.off(TIM.EVENT.MESSAGE_RECEIVED, () => { })
this.tim?.off(TIM.EVENT.SDK_READY, () => { })
}
登录设置
默认情况下,不支持多实例登录,即如果此帐号已在其他页面登录,若继续在当前页面登录成功,有可能会将其他页面踢下线。用户被踢下线时会触发事件TIM.EVENT.KICKED_OUT
,用户可在监听到事件后做相应处理。示例如下:
let onKickedOut = function (event) {
console.log(event.data.type);
// TIM.TYPES.KICKED_OUT_MULT_ACCOUNT(Web 端,同一帐号,多页面登录被踢)
// TIM.TYPES.KICKED_OUT_MULT_DEVICE(同一帐号,多端登录被踢)
// TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED(签名过期)
// TIM.TYPES.KICKED_OUT_REST_API(REST API kick 接口踢出。v2.20.0起支持)
};
tim.on(TIM.EVENT.KICKED_OUT, onKickedOut);
获取会话列表
功能描述
用户在登录 App 后,可以像微信或 QQ 那样展示最近会话列表,方便找到目标会话。
会话列表如下图所示:
会话列表功能主要分为获取会话列表、监听会话列表更新事件。核心数据结构 Conversation。
获取会话列表
接入侧可通过调用 getConversationList 接口主动获取会话列表。
获取全量的会话列表
// 获取会话列表
async getSessionList() {
console.log('aaaa');
const { data: { conversationList } } = await this.timeCore.tim?.getConversationList()
this.conversationList = conversationList
console.log(this.conversationList, '数据');
// 他没有回话并且不是客服
if (conversationList.length == 0 && this.timeCore.userID !== 'admin') {
this.conversationList.push({
lastMessage: {},
userProfile: {
userID: 'admin',
} as Profile
})
}
const userId = this.conversationList[0].userProfile?.userID
console.log(conversationList[0], '--------');
if (userId) {
this.selectedKeys = [userId]
this.getMessageHistoryList(userId)
}
},
历史消息
功能描述
SDK 既支持分页续拉消息列表,也支持根据指定的消息 sequence 或消息时间跳拉消息列表。
云端存储的历史消息有存储时长的限制:
- 体验版:免费存储 7 天,不支持延长
- 专业版:免费存储 7 天,支持延长
- 旗舰版:免费存储 30 天,支持延长
说明:
- 延长历史消息存储时长是增值服务,您可以登录 即时通信 IM 控制台 修改相关配置,具体计费说明请参加 增值服务资费 。
- 富媒体消息(图片、文件、语音等)对应的文件存储时长,与历史消息存储时长保持一致。
拉取消息列表
分页拉取指定会话的消息列表
分页拉取指定会话的消息列表的接口,当用户进入会话首次渲染消息列表或者用户“下拉查看更多消息”时,需调用该接口。
注意:
该接口可用于"拉取历史消息",每次调用 SDK 最多返回20条消息。
接口
tim.getMessageList(options);
参数
参数 options 为 Object 类型,包含的属性值如下:
名称 | 类型 | 描述 |
---|---|---|
conversationID | String | 会话 ID。会话 ID 组成方式:
|
nextReqMessageID | String | undefined | 用于分页续拉的消息 ID。第一次拉取时该字段不要填值,续拉时填入上次调用 getMessageList 接口返回的该字段的值。 |
返回值
Promise
对象。
示例
async getMessageHistoryList(userId: string) {
const data = await this.timeCore.tim?.getMessageList({ conversationID: `C2C${userId}` })
this.historMessage = data.data.messageList
console.log(data, '我是历史记录');
}
// 下拉查看更多消息
let promise = tim.getMessageList({conversationID: 'C2Ctest', nextReqMessageID});
promise.then(function(imResponse) {
const messageList = imResponse.data.messageList; // 消息列表。
const nextReqMessageID = imResponse.data.nextReqMessageID; // 用于续拉,分页续拉时需传入该字段。
const isCompleted = imResponse.data.isCompleted; // 表示是否已经拉完所有消息。
});
根据指定的消息 sequence 或消息时间跳拉会话的消息列表
根据指定的消息 sequence 或 消息时间拉取会话的消息列表的接口。
注意:
v2.20.0起支持。
接口
tim.getMessageListHopping(options);
参数
参数 options 为 Object 类型,包含的属性值如下:
名称 | 类型 | 描述 |
---|---|---|
conversationID | String | 会话 ID。会话 ID 组成方式:
|
sequence | Number | undefined | 用于拉群组会话漫游消息的起始 sequence。 |
time | Number | undefined | 消息的服务端时间,用于拉 C2C 会话漫游消息的起始时间。 |
direction | Number | 消息拉取方向,默认 0。
|
count | Number | undefined | 需要拉取的消息数量,默认值和最大值为15,即一次拉取至多返回15条消息。 |
返回值
Promise
对象。
示例
// 根据 sequence 拉群漫游消息,direction 0 向上拉,拉更旧的消息,direction 1 向下拉,拉更新的消息
let promise = tim.getMessageListHopping({conversationID: 'GROUPtest', sequence: xxx, count: 15, direction: 0});
promise.then(function(imResponse) {
const messageList = imResponse.data.messageList; // 消息列表。
});
// 根据时间拉 C2C 会话漫游消息,direction 0 向上拉,拉更旧的消息,direction 1 向下拉,拉更新的消息
let promise = tim.getMessageListHopping({conversationID: 'C2Ctest', time: xxx, count: 15, direction: 0});
promise.then(function(imResponse) {
const messageList = imResponse.data.messageList; // 消息列表。
});
接收消息
功能描述
接收消息需要通过事件监听实现。
监听事件
注意:
请在调用 login 接口前调用此接口监听事件,避免漏掉 SDK 派发的事件。
接口
tim.on(eventName, handler, context);
参数
名称 | 类型 | 描述 |
---|---|---|
eventName | String | 事件名称。所有的事件名称都存放在 TIM.EVENT 变量中,如需要查看可以使用 console.log(TIM.EVENT) 把所有的事件显示出来。事件列表。 |
handler | Function | 处理事件的方法,当事件触发时,会调用此 handler 进行处理。 |
context | * | undefined | 期望 handler 执行时的上下文 |
返回值
无
示例
let onMessageReceived = function(event) {
// event.data - 存储 Message 对象的数组 - [Message]
const messageList = event.data;
messageList.forEach((message) => {
if (message.type === TIM.TYPES.MSG_TEXT) {
// 文本消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.TextPayload
} else if (message.type === TIM.TYPES.MSG_IMAGE) {
// 图片消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.ImagePayload
} else if (message.type === TIM.TYPES.MSG_SOUND) {
// 音频消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.AudioPayload
} else if (message.type === TIM.TYPES.MSG_VIDEO) {
// 视频消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.VideoPayload
} else if (message.type === TIM.TYPES.MSG_FILE) {
// 文件消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.FilePayload
} else if (message.type === TIM.TYPES.MSG_CUSTOM) {
// 自定义消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.CustomPayload
} else if (message.type === TIM.TYPES.MSG_MERGER) {
// 合并消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.MergerPayload
} else if (message.type === TIM.TYPES.MSG_LOCATION) {
// 地理位置消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.LocationPayload
} else if (message.type === TIM.TYPES.MSG_GRP_TIP) {
// 群提示消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.GroupTipPayload
} else if (message.type === TIM.TYPES.MSG_GRP_SYS_NOTICE) {
// 群系统通知 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.GroupSystemNoticePayload
}
});
};
tim.on(TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived);
取消监听事件
接口
tim.off(eventName, handler, context, once);
参数
名称 | 类型 | 描述 |
---|---|---|
eventName | String | 事件名称。所有的事件名称都存放在 TIM.EVENT 变量中,如需要查看可以使用 console.log(TIM.EVENT) 把所有的事件显示出来。事件列表。 |
handler | Function | 处理事件的方法,当事件触发时,会调用此 handler 进行处理。 |
context | * | undefined | 期望 handler 执行时的上下文 |
once | Boolean | undefined | 是否只解绑一次 |
返回值
无
示例
let onMessageReceived = function(event) {
// 收到推送的单聊、群聊、群提示、群系统通知的新消息,可通过遍历 event.data 获取消息列表数据并渲染到页面
// event.name - TIM.EVENT.MESSAGE_RECEIVED
// event.data - 存储 Message 对象的数组 - [Message]
};
tim.off(TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived);
总结
- 引入pinia的聊天模块开始进行sdk初始化
- 在登录完成后 完成tim的登录 并且持久化登录
- 在顶层页面完成消息的接收,也就是监听消息的变化每次变化通知一下pina事件的分法
- 在页面收到action发过来的消息后,要把消息主动放在当前聊天记录里面
- 当选择一个新的联系人的时候要获取这个人的聊天信息
- 每次发送消息要注意清空输入框,并且把最新消息手动push到当前聊天数组中
import TIM, { ChatSDK } from 'tim-js-sdk';
import TIMUploadPlugin from 'tim-upload-plugin';
import { ChartDefineStoreOptions, ITextPayload, TextMessageEvent, TIMCoreLoginParams } from './type';
export default class TIMCore {
public tim: ChatSDK | undefined
public userID = ''
constructor(props: ChartDefineStoreOptions) {
this.initTimSdk(props.SDKAppID)
}
private initTimSdk(SDKAppID: number) {
let options = {
SDKAppID,// 接入时需要将0替换为您的即时通信 IM 应用的 SDKAppID
};
// 创建 SDK 实例,`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
let tim = TIM.create(options); // SDK 实例通常用 tim 表示
// 设置 SDK 日志输出级别,详细分级请参见 setLogLevel https://web.sdk.qcloud.com/im/doc/zh-cn/SDK.html#setLogLevel 接口的说明</a>
tim.setLogLevel(0); // 普通级别,日志量较多,接入时建议使用
// tim.setLogLevel(1); // release 级别,SDK 输出关键信息,生产环境时建议使用
// 注册腾讯云即时通信 IM 上传插件
tim.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin })
this.tim = tim
this.persistedLogin()
}
public timLoginout = () => {
//退出登录
this.tim?.logout()
}
public unBindTIMEvent = () => {
this.tim?.off(TIM.EVENT.MESSAGE_RECEIVED, () => { })
this.tim?.off(TIM.EVENT.SDK_READY, () => { })
}
private persistedLogin = () => {
console.log('缓存');
const TIMCoreLoginParams = JSON.parse(localStorage.getItem('TIMCoreLoginParams') || '{}')
if (TIMCoreLoginParams.userID) {
console.log('存在登录');
this.timLogin(TIMCoreLoginParams)
}
}
public timLogin = async (options: TIMCoreLoginParams) => {
//第一步登录sdk
await this.tim?.login(options)
// 持久化相关密钥
localStorage.setItem('TIMCoreLoginParams', JSON.stringify(options))
this.userID = options.userID
this.bindTIMEvent()
}
// 监听sdk准备完成的事件
private bindTIMEvent() {
this.tim?.on(TIM.EVENT.SDK_READY, this.handleSDKReady, this)
}
private handleSDKReady = () => {
console.log('sdk准备完成');
this.onReady()
console.log('执行');
this.tim?.on(TIM.EVENT.MESSAGE_RECEIVED, this.handleMessageReceived, this)
}
public onReady = () => {
}
private handleMessageReceived = (event: TextMessageEvent) => {
console.log('接收到消息', event);
// 接收到消息后 最好手动设置成已读
this.tim?.setMessageRead({
conversationID: event.data[0].conversationID
})
this.messageReceived(event)
}
// 对外暴露接受消息的方法
public messageReceived = (event: TextMessageEvent) => { }
// 创建对应消息类型
private getMessageOptions = (userID: string, payload: ITextPayload) => {
return this.tim?.createTextMessage({
to: userID,
conversationType: TIM.TYPES.CONV_C2C,
// 消息优先级,用于群聊(v2.4.2起支持)。如果某个群的消息超过了频率限制,后台会优先下发高优先级的消息,详细请参考:https://cloud.tencent.com/document/product/269/3663#.E6.B6.88.E6.81.AF.E4.BC.98.E5.85.88.E7.BA.A7.E4.B8.8E.E9.A2.91.E7.8E.87.E6.8E.A7.E5.88.B6)
// 支持的枚举值:TIM.TYPES.MSG_PRIORITY_HIGH, TIM.TYPES.MSG_PRIORITY_NORMAL(默认), TIM.TYPES.MSG_PRIORITY_LOW, TIM.TYPES.MSG_PRIORITY_LOWEST
// priority: TIM.TYPES.MSG_PRIORITY_NORMAL,
payload,
// v2.20.0起支持C2C消息已读回执功能,如果您发消息需要已读回执,需购买旗舰版套餐,并且创建消息时将 needReadReceipt 设置为 true
needReadReceipt: true
// 消息自定义数据(云端保存,会发送到对端,程序卸载重装后还能拉取到,v2.10.2起支持)
// cloudCustomData: 'your cloud custom data'
})
}
public sendMessage = async (userID: string, payload: ITextPayload) => {
// 创建消息
const messOption = this.getMessageOptions(userID, payload)
await this.tim?.sendMessage(messOption!)
console.log('发送成功');
}
}