macOS IMLib 快速开始

本页用 5 个步骤完成 macOS 端 IMLib 接入:控制台取 AppKey / Token、导入 SDK、初始化、建立连接、收发消息与会话。示例方法名与参数来自冻结的 sdk-bindings.json。

  1. 控制台获取 AppKey 与 Token

    在控制台创建应用并获取 AppKey;用户 Token 由业务服务先注册用户(user.register)、再调用 user.token.issue 签发后下发到客户端(两步都需要服务端签名)。

    客户端只持有 Token,不得内置 AppSecret;Token 泄露时可调用服务端接口吊销。

  2. 导入 SDK

    按「导入 SDK」安装依赖;包名 @ni-paas-im/electron(本地包路径 sdk/electron;当前未发布到 npm)。主进程 @ni-paas-im/electron/main 提供 initService(IMLib 客户端 + 本地 SQLite + 诊断)与 @ni-paas-im/electron/main/ipc 的 registerIpc;preload 由 @ni-paas-im/electron/preload 提供,向页面暴露 window.niPaasIMBridge(imlib.* / localDb.* / onEvent / onState)。

  3. 初始化客户端

    使用 AppKey(与服务端地址)初始化;初始化幂等:同 appkey 重复调用返回同一实例,不建立连接。

  4. 建立连接并订阅事件

    使用 Token 调用 connect,成功后触发 CONNECTED;离线消息在 hello 后自动补发。

  5. 收发消息与会话

    注册对端用户后发送第一条文本消息、监听 MESSAGES 事件并拉取会话列表。

1. 控制台获取 AppKey 与 Token​

凭据获取方式使用位置
AppKey控制台 → 应用 → 基本信息初始化客户端(options.appkey)
用户 Token业务服务注册用户(user.register)后调用 user.token.issue 签发(需签名)connect(token)
AppSecret控制台 → 应用 → 密钥(仅服务端保存)服务端签发 Token / 调用 Open API
禁止硬编码

AppSecret 只能保存在业务服务端;客户端产物中不得出现 AppSecret。示例中的 TOKEN 表示服务端签发的用户 Token。

本地服务端地址

本页及后续示例统一使用 https://im.example.com(服务端缺省端口)。

示例使用占位地址 https://im.example.com;本地联调请替换为你实际启动的服务端地址与端口(客户端与服务端必须指向同一地址)。

2. 导入 SDK​

npm
# SDK 当前未发布到 npm(@0.1.0 远程命令 404),从仓库本地安装:
npm install @ni-paas-im/electron@file:../sdk/electron

# 主进程入口:@ni-paas-im/electron/main(initService)
# IPC 注册:@ni-paas-im/electron/main/ipc(registerIpc)
# preload 桥:@ni-paas-im/electron/preload(window.niPaasIMBridge)
# 类型声明:@ni-paas-im/electron/types/index.d.ts

3. 初始化​

JavaScript (ESM)
// 主进程 main.js:本地 SQLite 单写者 + IMLib 客户端(macOS 11+,x64 / arm64)
import { app } from 'electron';
import { initService } from '@ni-paas-im/electron/main';

const service = initService({
  appkey: 'YOUR_APP_KEY',
  serverUrl: 'https://im.example.com',
  dbPath: app.getPath('userData'),   // 目录:库文件在 <dbPath>/im-electron/<appkey>/<userId>.db
});
const client = service.client;        // 主进程唯一的 IMLib 客户端(renderer 通过 preload 桥调用)

4. 建立连接​

JavaScript (ESM)
// 主进程:注册 SDK 的 IPC 桥;连接与重连都由主进程持有
import { ipcMain } from 'electron';
import { initService, Events } from '@ni-paas-im/electron/main';
import { registerIpc } from '@ni-paas-im/electron/main/ipc';

const service = initService({ appkey: 'YOUR_APP_KEY', serverUrl: 'https://im.example.com', dbPath: app.getPath('userData') });
const bridge = registerIpc({ ipcMain, service });   // service 传 initService() 的返回包装对象
service.client.addEventListener(Events.CONNECTED, (payload) => console.log('connected', payload.userId));

const res = await service.client.connect(TOKEN);
if (res.code !== 0) {
  // 1002 INVALID_TOKEN(无效/过期/签名不对)与 1003 FORBIDDEN 不自动重连;
  // 3001/3002 属传输层,SDK 自动重连。排障见「错误码」页。
  console.warn('connect failed', res.code, res.msg);
}

5. 收发消息与会话​

收发验证需要两个已注册用户:先注册对端(例如 user2)并签发它的 Token,再用对端账号建连接收。示例中的 user2 是“已存在的另一个用户”,不是任意字符串。

JavaScript (ESM)
// 渲染进程:通过 preload 白名单桥调用(主进程持有连接与本地库)
const sent = await window.niPaasIMBridge.imlib.sendTextMessage(1, 'user2', '你好,NI PaaS');
if (sent.code !== 0) throw new Error(sent.msg);

const conversations = await window.niPaasIMBridge.imlib.getConversationList(); // 冷启动离线可读
const off = window.niPaasIMBridge.onEvent(({ event, payload, seq, ts }) => {
  if (event === 'MESSAGES') render(payload.messages);
});
发送给未注册用户会断开连接

单聊发送给不存在的用户时,服务端返回 1004(用户不存在),当前连接可能因此被断开,随后发送调用返回 3001(连接已中断)。

这不是网络故障:注册对端用户(user.register)并重连后即可正常发送。排查时先确认两个 userId 都已注册且属于同一个 appkey。

响应不是 JSON / 404?

如果脚本报 Unexpected token '<' 或看到 HTML,通常是服务端地址或端口不对(示例使用占位地址;本地联调要替换为实际端口)。

先用浏览器或 curl 访问服务端根路径确认可达,再检查 serverUrl 是否与启动参数一致。

双端验证:两个进程 / 两个浏览器 profile

同一进程内对同一个 appkey 初始化只会得到一个客户端实例(初始化幂等):把两个账号塞进同一个实例会互相覆盖登录态,典型报错是 “cannot send to self”。

实测:同一进程内建两个客户端实例(不同 appkey 或先 destroy 再 create)可以互发;同 origin 的两个浏览器标签共享 deviceId,第二个客户端可能收不到投递。

因此本机验证“收发”请开两个进程,或开两个浏览器 profile(各自独立 localStorage/deviceId),每个进程/Profile 只登录一个用户。

下一步​