2026-05-02 22:57:55 +08:00
|
|
|
|
# React Native IM 接入
|
|
|
|
|
|
|
|
|
|
|
|
基于 `@xuqm/rn-im` 模块实现即时通讯功能,使用 WatermelonDB 进行本地消息存储。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 初始化与登录
|
|
|
|
|
|
|
|
|
|
|
|
### 初始化
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
import { XuqmSDK } from '@xuqm/rn-common'
|
|
|
|
|
|
|
|
|
|
|
|
await XuqmSDK.initialize({
|
|
|
|
|
|
appKey: 'your_app_key',
|
|
|
|
|
|
logLevel: __DEV__ ? 'debug' : 'warn',
|
|
|
|
|
|
})
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 登录
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
import { XuqmSDK } from '@xuqm/rn-common'
|
|
|
|
|
|
|
|
|
|
|
|
await XuqmSDK.login({
|
|
|
|
|
|
userId: 'user_001',
|
|
|
|
|
|
userSig: 'your_user_sig_jwt',
|
|
|
|
|
|
})
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-03 00:11:06 +08:00
|
|
|
|
> 如果集成了 `rn-im`,`XuqmSDK.login` 会自动触发 `ImSDK` 连接,业务侧无需单独调用 `ImSDK.login`。
|
2026-05-02 22:57:55 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 消息收发
|
|
|
|
|
|
|
|
|
|
|
|
### 监听实时消息
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
import { ImSDK } from '@xuqm/rn-im'
|
|
|
|
|
|
|
|
|
|
|
|
ImSDK.addEventListener('message', (msg) => {
|
|
|
|
|
|
console.log('收到消息:', msg.msgType, msg.content)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
ImSDK.addEventListener('read', (msg) => {
|
|
|
|
|
|
console.log('已读回执:', msg.id)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
ImSDK.addEventListener('revoke', (data) => {
|
|
|
|
|
|
console.log('消息被撤回:', data.msgId)
|
|
|
|
|
|
})
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 发送文本消息
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
const msg = await ImSDK.sendMessage(
|
|
|
|
|
|
'user_002', // toId
|
|
|
|
|
|
'SINGLE', // chatType: 'SINGLE' | 'GROUP'
|
|
|
|
|
|
'TEXT', // msgType
|
|
|
|
|
|
'Hello!' // content
|
|
|
|
|
|
)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 发送图片
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
const msg = await ImSDK.sendImageMessage(
|
|
|
|
|
|
'user_002',
|
|
|
|
|
|
'SINGLE',
|
|
|
|
|
|
'/path/to/image.jpg', // 本地 URI
|
|
|
|
|
|
800, // 宽
|
|
|
|
|
|
600 // 高
|
|
|
|
|
|
)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 获取历史消息
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
// 单聊历史
|
|
|
|
|
|
const history = await ImSDK.fetchHistory('user_002', page, size)
|
|
|
|
|
|
|
|
|
|
|
|
// 群历史
|
|
|
|
|
|
const groupHistory = await ImSDK.fetchGroupHistory('group_xxx', page, size)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## WatermelonDB 本地存储
|
|
|
|
|
|
|
|
|
|
|
|
`rn-im` 使用 WatermelonDB(SQLite)存储本地消息,按 `appKey + userId` 自动隔离。
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
import { ImDatabase } from '@xuqm/rn-im'
|
|
|
|
|
|
|
|
|
|
|
|
// 消息搜索(本地)
|
|
|
|
|
|
const params: MessageSearchParams = {
|
|
|
|
|
|
keyword: '会议',
|
|
|
|
|
|
toId: 'user_002',
|
|
|
|
|
|
chatType: 'SINGLE',
|
|
|
|
|
|
msgTypes: ['TEXT'],
|
|
|
|
|
|
limit: 20,
|
|
|
|
|
|
}
|
|
|
|
|
|
const results = await ImSDK.searchMessages(params)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 群聊
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
// 创建群
|
|
|
|
|
|
const group = await ImSDK.createGroup('项目讨论', ['user_002', 'user_003'])
|
|
|
|
|
|
|
|
|
|
|
|
// 群列表
|
|
|
|
|
|
const groups = await ImSDK.listGroups()
|
|
|
|
|
|
|
|
|
|
|
|
// 添加成员
|
|
|
|
|
|
await ImSDK.addGroupMember('group_xxx', 'user_004')
|
|
|
|
|
|
|
|
|
|
|
|
// 移除成员
|
|
|
|
|
|
await ImSDK.removeGroupMember('group_xxx', 'user_004')
|
|
|
|
|
|
|
|
|
|
|
|
// 退出群聊
|
|
|
|
|
|
await ImSDK.leaveGroup('group_xxx')
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
详见 [RN 群聊文档 →](./group)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 会话列表
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
// 订阅会话变化
|
|
|
|
|
|
const unsub = ImSDK.subscribeConversations((conversations) => {
|
|
|
|
|
|
console.log(conversations)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 置顶
|
|
|
|
|
|
await ImSDK.setConversationPinned('user_002', 'SINGLE', true)
|
|
|
|
|
|
|
|
|
|
|
|
// 免打扰
|
|
|
|
|
|
await ImSDK.setConversationMuted('group_xxx', 'GROUP', true)
|
|
|
|
|
|
|
|
|
|
|
|
// 标记已读
|
|
|
|
|
|
await ImSDK.markRead('user_002')
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 离线消息同步
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
// 查询离线消息数量(示例)
|
|
|
|
|
|
const count = await ImSDK.offlineMessageCount()
|
|
|
|
|
|
|
|
|
|
|
|
// 同步离线消息(示例)
|
|
|
|
|
|
const messages = await ImSDK.syncOfflineMessages()
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 断开连接
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
ImSDK.disconnect()
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 类型参考
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ImMessage {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
fromId: string
|
|
|
|
|
|
toId: string
|
|
|
|
|
|
chatType: 'SINGLE' | 'GROUP'
|
|
|
|
|
|
msgType: 'TEXT' | 'IMAGE' | 'AUDIO' | 'VIDEO' | 'FILE' |
|
|
|
|
|
|
'LOCATION' | 'NOTIFY' | 'CUSTOM' | 'RICH_TEXT' |
|
|
|
|
|
|
'CALL_AUDIO' | 'CALL_VIDEO' | 'FORWARD' | 'REVOKED'
|
|
|
|
|
|
content: string
|
|
|
|
|
|
status: 'SENDING' | 'SENT' | 'DELIVERED' | 'READ' | 'FAILED' | 'REVOKED'
|
|
|
|
|
|
createdAt: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface ConversationData {
|
|
|
|
|
|
targetId: string
|
|
|
|
|
|
chatType: 'SINGLE' | 'GROUP'
|
|
|
|
|
|
lastMsgContent: string
|
|
|
|
|
|
lastMsgType: string
|
|
|
|
|
|
lastMsgTime: number
|
|
|
|
|
|
unreadCount: number
|
|
|
|
|
|
isMuted: boolean
|
|
|
|
|
|
isPinned: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|