React Native IMLib 快速开始
本页用 8 段完成 React Native 端接入:环境要求 → 安装 → 服务端签发 Token → 初始化 → 连接 → 监听消息 → 发送消息 → 断开/销毁。示例方法名与参数来自 SDK 包的真实公开面。
先读覆盖度
本包当前为骨架实现(12/166 方法):只有本页用到的生命周期、连接、文本消息与监听可用;其余能力未实现。
1. 环境要求
| 项 | 要求 | 检查命令 |
|---|---|---|
| Node.js | ≥ 22 | node -v |
| React Native | 0.73+(含 Android/iOS 原生工程) | npx react-native --version |
| 原生模块 | 已集成 NipaasIMNativeModule(Android Kotlin / iOS Swift 桥) | 见 SDK 包内架构说明 |
| 类型检查(可选) | 有 tsc 时执行 npm run typecheck | 无 tsc 会跳过并提示 |
2. 安装 SDK(未发布,用本地 path 依赖)
包未发布到 npm registry(private: true),npm install @ni-paas-im/react-native-im-wrapper 会 404。请用本地路径依赖:
npm(file 依赖)
# 在 React Native 应用工程根目录执行(示例假设本仓库在 ../ni-paas-im)
npm install ../ni-paas-im/sdk/rn
# 等价写法:npm install file:../ni-paas-im/sdk/rn
# yarn: yarn add file:../ni-paas-im/sdk/rn
# 验证安装结果
node -e "console.log(require('./package.json').dependencies['@ni-paas-im/react-native-im-wrapper'])"本仓库内开发
仓库内联调可直接把 SDK 包目录作为 workspace/文件依赖;在包目录执行 npm test 可无设备跑 MockBridge 单测。
3. 服务端签发 Token
Token 必须由业务服务用 AppSecret 签名后调用 Open API 签发(红线②);客户端只持有 Token,不得内置 AppSecret。
Node.js(服务端)
// 服务端签发 Token(Node.js 18+;APP_SECRET 仅服务端持有)
import { createHash, randomBytes } from 'node:crypto';
const BASE = 'http://127.0.0.1:18081';
const APP_KEY = 'demo';
const APP_SECRET = process.env.IM_APP_SECRET;
function signedHeaders() {
const nonce = randomBytes(16).toString('hex');
const timestamp = Date.now();
const signature = createHash('sha1').update(`${APP_SECRET}${nonce}${timestamp}`).digest('hex');
return { 'App-Key': APP_KEY, Nonce: nonce, Timestamp: String(timestamp), Signature: signature, 'content-type': 'application/json' };
}
async function call(path, body) {
const res = await fetch(`${BASE}/im/v2${path}`, { method: 'POST', headers: signedHeaders(), body: JSON.stringify(body) });
return res.json();
}
console.log(await call('/user/register', { userId: 'rn_alice', name: 'Alice' }));
console.log(await call('/user/token/issue', { userId: 'rn_alice' })); // data.token → connect(token, 10)不要使用未签名入口
开发模式的 /api/apps/{appkey}/users(IM_ALLOW_ANON_WRITE=true)仅限本地联调,生产必须关闭并使用上面的签名流程。
4. 初始化
TypeScript
import { RCIMIWEngine } from '@ni-paas-im/react-native-im-wrapper';
// create 具备单次初始化语义:进程内重复调用返回同一实例;destroy 后可重建。
const engine = RCIMIWEngine.create('YOUR_APP_KEY');
// 连接状态(覆盖式注册;重复调用会替换上一个监听器)
engine.setOnConnectionStatusChangedListener((status) => {
console.log('connection status:', status); // RCIMIWConnectionStatus.*
});5. 连接
TypeScript
const code = await engine.connect(
TOKEN,
10, // 超时(秒);<= 0 表示不额外限制
{
onConnected: (c, userId) => console.log('connected', c, userId),
onDatabaseOpened: (c) => console.log('db opened', c),
},
);
if (code !== 0) throw new Error(`connect failed: ${code}`); // 业务错误码原样透传(如 31004)初始化必须先于连接
未初始化直接 connect 会返回未初始化错误;本页顺序(create → connect)不可调换。
6. 监听消息
TypeScript
engine.setOnMessageReceivedListener((message) => {
console.log('收到消息', message.messageId, message.conversationType, message.targetId);
// 按会话聚合、按 messageId/clientMsgId 去重后更新未读与列表
});7. 发送文本消息
TypeScript
import { RCIMIWConversationType, RCIMIWMessageType } from '@ni-paas-im/react-native-im-wrapper';
const message = await engine.createTextMessage(
RCIMIWConversationType.PRIVATE, // 1 单聊;2 群聊;3 聊天室;4 系统;5 超级群
'user2', // 已注册的对端 userId
'', // channelId(超级群频道;单聊传空串)
'你好,NI PaaS',
);
const sent = await engine.sendMessage(message, {
onMessageSaved: (m) => console.log('saved', m.messageId),
onMessageSent: (c, m) => console.log('sent', c, m?.messageId),
});
if (sent !== 0) throw new Error(`send failed: ${sent}`);对端必须已注册
向未注册 userId 发送会返回 1004(用户不存在)并可能断开连接;收发验证需两个已注册用户(两个进程/两台设备各登一个)。
8. 断开与销毁
TypeScript
const off = await engine.disconnect(false); // receivePush=false 表示不再接收推送;返回 0 成功
await engine.destroy(); // 释放原生资源;之后可重新 create
console.log('disconnect code:', off);