2026-07-29 02:43:17 +08:00
|
|
|
# IM 接入
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
`@xuqm/rn-im` 提供单聊、群聊、会话、好友关系、黑名单和离线消息能力。宿主仍然只通过
|
|
|
|
|
Common 同步一次登录状态。
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
## 安装
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
```bash
|
|
|
|
|
pnpm add @xuqm/rn-common @xuqm/rn-im @nozbe/watermelondb
|
|
|
|
|
```
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
## 登录与连接
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
import { XuqmSDK } from '@xuqm/rn-common'
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
await XuqmSDK.login({
|
|
|
|
|
userId: 'user-001',
|
|
|
|
|
accessToken: 'host-access-token',
|
|
|
|
|
userSig: 'im-user-signature',
|
2026-05-02 22:57:55 +08:00
|
|
|
})
|
|
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
安装 IM 后,公共会话会自动建立连接。不要再调用第二套 IM 登录方法。
|
|
|
|
|
|
|
|
|
|
连接状态:
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
import { ImSDK } from '@xuqm/rn-im'
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
if (!ImSDK.isConnected()) {
|
|
|
|
|
await ImSDK.reconnect()
|
|
|
|
|
}
|
2026-05-02 22:57:55 +08:00
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
## 事件监听
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
```ts
|
|
|
|
|
const listener = {
|
|
|
|
|
onConnected() {
|
|
|
|
|
console.log('IM 已连接')
|
|
|
|
|
},
|
|
|
|
|
onDisconnected(reason?: string) {
|
|
|
|
|
console.log('IM 已断开', reason)
|
|
|
|
|
},
|
|
|
|
|
onMessage(message) {
|
|
|
|
|
appendMessage(message)
|
|
|
|
|
},
|
|
|
|
|
onGroupMessage(message) {
|
|
|
|
|
appendGroupMessage(message)
|
|
|
|
|
},
|
|
|
|
|
onRead(message) {
|
|
|
|
|
markMessageRead(message.id)
|
|
|
|
|
},
|
|
|
|
|
onRevoke({ msgId }) {
|
|
|
|
|
markMessageRevoked(msgId)
|
|
|
|
|
},
|
|
|
|
|
onError(error) {
|
|
|
|
|
console.warn(error)
|
|
|
|
|
},
|
|
|
|
|
}
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
ImSDK.addListener(listener)
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
// 页面或服务销毁时
|
|
|
|
|
ImSDK.removeListener(listener)
|
|
|
|
|
```
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
同一个 listener 对象用于添加和移除。
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
## 发送消息
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
文本:
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
```ts
|
|
|
|
|
const message = await ImSDK.sendTextMessage(
|
|
|
|
|
'user-002',
|
|
|
|
|
'SINGLE',
|
|
|
|
|
'你好',
|
|
|
|
|
)
|
2026-05-02 22:57:55 +08:00
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
群聊:
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
await ImSDK.sendTextMessage('group-001', 'GROUP', '大家好')
|
2026-05-02 22:57:55 +08:00
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
图片:
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
await ImSDK.sendImageMessage(
|
|
|
|
|
'user-002',
|
2026-05-02 22:57:55 +08:00
|
|
|
'SINGLE',
|
2026-07-29 02:43:17 +08:00
|
|
|
imageUri,
|
|
|
|
|
imageWidth,
|
|
|
|
|
imageHeight,
|
2026-05-02 22:57:55 +08:00
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
文件、音频和视频使用对应方法:
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
await ImSDK.sendFileMessage(
|
|
|
|
|
'user-002',
|
|
|
|
|
'SINGLE',
|
|
|
|
|
fileUri,
|
|
|
|
|
'report.pdf',
|
|
|
|
|
fileSize,
|
|
|
|
|
)
|
|
|
|
|
await ImSDK.sendAudioMessage('user-002', 'SINGLE', audioUri, durationSeconds)
|
|
|
|
|
await ImSDK.sendVideoMessage(
|
|
|
|
|
'user-002',
|
|
|
|
|
'SINGLE',
|
|
|
|
|
videoUri,
|
|
|
|
|
thumbnailUri,
|
|
|
|
|
durationSeconds,
|
|
|
|
|
)
|
2026-05-02 22:57:55 +08:00
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
自定义、位置、富文本、通知、引用、合并转发和音视频通话信令也有对应的类型化方法。消息
|
|
|
|
|
业务内容由双方约定,不要在普通文本字段中拼接不可验证的脚本。
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
撤回与编辑:
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
```ts
|
|
|
|
|
await ImSDK.revokeMessage(message.id)
|
|
|
|
|
await ImSDK.editMessage(message.id, '修改后的内容')
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 历史和离线消息
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
const history = await ImSDK.fetchHistory(
|
|
|
|
|
'user-002',
|
|
|
|
|
0,
|
|
|
|
|
20,
|
|
|
|
|
'SINGLE',
|
|
|
|
|
)
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
const filtered = await ImSDK.fetchHistoryWithFilters('user-002', {
|
2026-05-02 22:57:55 +08:00
|
|
|
keyword: '会议',
|
2026-07-29 02:43:17 +08:00
|
|
|
msgType: 'TEXT',
|
|
|
|
|
startTime: '2026-07-01 00:00:00',
|
|
|
|
|
endTime: '2026-07-31 23:59:59',
|
|
|
|
|
page: 0,
|
|
|
|
|
size: 20,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const offlineCount = await ImSDK.offlineMessageCount()
|
|
|
|
|
const offlineMessages = await ImSDK.syncOfflineMessages(100)
|
2026-05-02 22:57:55 +08:00
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
SDK 负责当前登录用户的本地消息缓存与同步,宿主不需要依赖其内部存储结构。
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
## 会话列表
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
const conversations = await ImSDK.listConversations()
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
const unsubscribe = ImSDK.subscribeConversations((next) => {
|
|
|
|
|
setConversations(next)
|
|
|
|
|
})
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
await ImSDK.markRead('user-002', 'SINGLE')
|
|
|
|
|
await ImSDK.setConversationPinned('user-002', 'SINGLE', true)
|
|
|
|
|
await ImSDK.setConversationMuted('user-002', 'SINGLE', true)
|
|
|
|
|
await ImSDK.setDraft('user-002', 'SINGLE', '稍后继续')
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
unsubscribe()
|
2026-05-02 22:57:55 +08:00
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
还可以隐藏、删除会话或将会话加入自定义分组。
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
## 群聊
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
const group = await ImSDK.createGroup(
|
|
|
|
|
'项目讨论',
|
|
|
|
|
['user-002', 'user-003'],
|
|
|
|
|
'WORK',
|
|
|
|
|
)
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
const groups = await ImSDK.listGroups()
|
|
|
|
|
const detail = await ImSDK.getGroupInfo(group.id)
|
|
|
|
|
const members = await ImSDK.listGroupMembers(group.id)
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
await ImSDK.addGroupMember(group.id, 'user-004')
|
|
|
|
|
await ImSDK.removeGroupMember(group.id, 'user-004')
|
|
|
|
|
await ImSDK.leaveGroup(group.id)
|
2026-05-02 22:57:55 +08:00
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
管理员能力包括群资料、角色、禁言、群主转让、入群申请和解散群聊。调用失败时使用服务端
|
|
|
|
|
返回的权限错误,不要仅靠前端角色隐藏来替代服务端校验。
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
## 好友和黑名单
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
const friends = await ImSDK.listFriends()
|
|
|
|
|
await ImSDK.addFriend('user-002')
|
|
|
|
|
await ImSDK.removeFriend('user-002')
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
const incoming = await ImSDK.listFriendRequests('incoming')
|
|
|
|
|
const request = await ImSDK.sendFriendRequest('user-003', '我是张医生')
|
|
|
|
|
await ImSDK.acceptFriendRequest(request.id)
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
await ImSDK.addToBlacklist('user-004')
|
|
|
|
|
const blocked = await ImSDK.checkBlacklist('user-004')
|
|
|
|
|
await ImSDK.removeFromBlacklist('user-004')
|
|
|
|
|
```
|
2026-05-02 22:57:55 +08:00
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
## 用户与消息搜索
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
const users = await ImSDK.searchUsers('张医生')
|
|
|
|
|
const groups = await ImSDK.searchGroups('项目')
|
|
|
|
|
const messages = await ImSDK.searchMessages({
|
|
|
|
|
keyword: '会议',
|
|
|
|
|
chatType: 'SINGLE',
|
|
|
|
|
toId: 'user-002',
|
|
|
|
|
msgTypes: ['TEXT'],
|
|
|
|
|
limit: 20,
|
|
|
|
|
})
|
2026-05-02 22:57:55 +08:00
|
|
|
```
|
|
|
|
|
|
2026-07-29 02:43:17 +08:00
|
|
|
## 登出
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
```ts
|
2026-07-29 02:43:17 +08:00
|
|
|
await XuqmSDK.logout()
|
2026-05-02 22:57:55 +08:00
|
|
|
```
|
2026-07-29 02:43:17 +08:00
|
|
|
|
|
|
|
|
公共登出会自动断开 IM。`ImSDK.disconnect()` 仅用于 IM 专用诊断或明确的临时断开场景。
|