@unrealknight/cocos-sdk
v1.0.4
Published
OpenIM SDK for Cocos Creator without local storage
Maintainers
Readme
OpenIM SDK for Cocos Creator
纯 TypeScript 实现的 OpenIM SDK,专为 Cocos Creator 优化,无需本地存储依赖,所有数据仅保存在内存中。
特性
- ✅ 纯 TypeScript 实现,无需 WASM 依赖
- ✅ 无本地存储,所有数据保存在内存中
- ✅ 支持完整的 IM 功能(消息、会话、群组、好友等)
- ✅ 专为 Cocos Creator 优化
- ✅ WebSocket 自动重连
- ✅ 内置消息缓存管理
- ✅ TypeScript 类型支持
安装
npm install @unrealknight/cocos-sdk快速开始
1. 初始化 SDK
import { getSDK, Platform, LogLevel } from '@openim/cocos-sdk';
const openIM = getSDK();
// 监听连接状态
openIM.on('OnConnectSuccess', (data) => {
console.log('连接成功');
});
openIM.on('OnConnectFailed', (data) => {
console.log('连接失败:', data.errMsg);
});
// 监听新消息
openIM.on('OnRecvNewMessage', (data) => {
console.log('收到新消息:', data.data);
});2. 登录
const config = {
userID: 'your_user_id',
token: 'your_token',
platformID: Platform.Web,
apiAddr: 'http://your-server:10002',
wsAddr: 'ws://your-server:10001',
logLevel: LogLevel.Debug,
isLogStandardOutput: true
};
const result = await openIM.login(config);
if (result.errCode === 0) {
console.log('登录成功');
} else {
console.error('登录失败:', result.errMsg);
}3. 发送消息
// 创建文本消息
const textMsg = openIM.createTextMessage('Hello, OpenIM!');
// 发送消息
const sendResult = await openIM.sendMessage({
message: textMsg.data,
recvID: 'receiver_user_id',
groupID: '', // 如果是群聊,填写群ID
offlinePushInfo: {
title: '你有新消息',
desc: 'Hello, OpenIM!',
ex: '',
iOSPushSound: '+1',
iOSBadgeCount: true
}
});
if (sendResult.errCode === 0) {
console.log('消息发送成功');
}4. 获取会话列表
const conversations = await openIM.getAllConversationList();
console.log('会话列表:', conversations.data);5. 获取历史消息
const history = await openIM.getAdvancedHistoryMessageList({
conversationID: 'conversation_id',
count: 20,
startClientMsgID: '', // 为空表示获取最新的消息
userID: '',
groupID: ''
});
console.log('历史消息:', history.data.messageList);在 Cocos Creator 中使用
1. 创建一个 IM 管理器组件
import { _decorator, Component } from 'cc';
import { getSDK, Platform, LogLevel, CbEvents } from '@openim/cocos-sdk';
const { ccclass, property } = _decorator;
@ccclass('IMManager')
export class IMManager extends Component {
private openIM = getSDK();
async start() {
// 设置事件监听
this.setupEventListeners();
// 登录
await this.login();
}
private setupEventListeners() {
// 连接状态
this.openIM.on(CbEvents.OnConnectSuccess, () => {
console.log('IM 连接成功');
});
this.openIM.on(CbEvents.OnConnectFailed, (data) => {
console.error('IM 连接失败:', data.errMsg);
});
// 消息接收
this.openIM.on(CbEvents.OnRecvNewMessage, (data) => {
console.log('收到新消息:', data.data);
// 处理新消息,更新 UI 等
});
// 会话变更
this.openIM.on(CbEvents.OnConversationChanged, (data) => {
console.log('会话变更:', data.data);
// 更新会话列表 UI
});
}
private async login() {
const result = await this.openIM.login({
userID: 'test_user',
token: 'test_token',
platformID: Platform.Web,
apiAddr: 'http://your-server:10002',
wsAddr: 'ws://your-server:10001',
logLevel: LogLevel.Debug
});
if (result.errCode === 0) {
console.log('登录成功');
// 获取会话列表
await this.loadConversations();
} else {
console.error('登录失败:', result.errMsg);
}
}
private async loadConversations() {
const result = await this.openIM.getAllConversationList();
if (result.errCode === 0) {
console.log('会话列表:', result.data);
// 更新 UI
}
}
public async sendTextMessage(text: string, recvID: string) {
const msg = this.openIM.createTextMessage(text);
if (msg.errCode !== 0) {
console.error('创建消息失败');
return;
}
const result = await this.openIM.sendMessage({
message: msg.data,
recvID: recvID,
groupID: ''
});
if (result.errCode === 0) {
console.log('消息发送成功');
} else {
console.error('消息发送失败:', result.errMsg);
}
}
onDestroy() {
// 退出登录
this.openIM.logout();
}
}2. 创建聊天界面组件
import { _decorator, Component, EditBox, ScrollView, Node, Label, instantiate, Prefab } from 'cc';
import { getSDK, MessageItem } from '@openim/cocos-sdk';
const { ccclass, property } = _decorator;
@ccclass('ChatView')
export class ChatView extends Component {
@property(EditBox)
inputBox: EditBox = null!;
@property(ScrollView)
messageScrollView: ScrollView = null!;
@property(Node)
messageContent: Node = null!;
@property(Prefab)
messagePrefab: Prefab = null!;
private openIM = getSDK();
private currentConversationID = '';
private currentRecvID = '';
start() {
// 监听新消息
this.openIM.on('OnRecvNewMessage', (data) => {
const message = data.data as MessageItem;
// 如果是当前会话的消息,添加到界面
if (this.isCurrentConversationMessage(message)) {
this.addMessageToView(message);
}
});
}
// 加载会话消息
async loadConversation(conversationID: string, recvID: string) {
this.currentConversationID = conversationID;
this.currentRecvID = recvID;
// 清空当前消息
this.messageContent.removeAllChildren();
// 获取历史消息
const result = await this.openIM.getAdvancedHistoryMessageList({
conversationID: conversationID,
count: 50,
startClientMsgID: '',
userID: '',
groupID: ''
});
if (result.errCode === 0) {
// 显示历史消息
result.data.messageList.forEach(msg => {
this.addMessageToView(msg);
});
// 滚动到底部
this.scrollToBottom();
}
}
// 发送消息
async onSendButtonClick() {
const text = this.inputBox.string;
if (!text || !this.currentRecvID) return;
// 创建消息
const msgResult = this.openIM.createTextMessage(text);
if (msgResult.errCode !== 0) return;
// 发送消息
const sendResult = await this.openIM.sendMessage({
message: msgResult.data,
recvID: this.currentRecvID,
groupID: ''
});
if (sendResult.errCode === 0) {
// 添加到界面
this.addMessageToView(sendResult.data);
// 清空输入框
this.inputBox.string = '';
// 滚动到底部
this.scrollToBottom();
}
}
// 添加消息到界面
private addMessageToView(message: MessageItem) {
const msgNode = instantiate(this.messagePrefab);
const label = msgNode.getComponentInChildren(Label);
if (label) {
label.string = this.formatMessage(message);
}
this.messageContent.addChild(msgNode);
}
// 格式化消息显示
private formatMessage(message: MessageItem): string {
const isSelf = message.sendID === this.openIM.getLoginUserID().data;
const sender = isSelf ? '我' : message.senderNickname || message.sendID;
let content = '';
switch (message.contentType) {
case 101: // 文本消息
content = message.textElem?.content || message.content;
break;
case 102: // 图片消息
content = '[图片]';
break;
case 103: // 音频消息
content = '[语音]';
break;
case 104: // 视频消息
content = '[视频]';
break;
case 105: // 文件消息
content = '[文件]';
break;
default:
content = message.content;
}
return `${sender}: ${content}`;
}
// 判断是否是当前会话的消息
private isCurrentConversationMessage(message: MessageItem): boolean {
// 这里需要根据消息的 sessionType、sendID、recvID、groupID 等判断
// 简化示例,实际需要更复杂的判断逻辑
return message.sendID === this.currentRecvID || message.recvID === this.currentRecvID;
}
// 滚动到底部
private scrollToBottom() {
this.scheduleOnce(() => {
this.messageScrollView.scrollToBottom(0.1);
}, 0.1);
}
}API 文档
核心方法
登录/登出
login(config)- 登录logout()- 登出getLoginStatus()- 获取登录状态getLoginUserID()- 获取登录用户ID
用户相关
getSelfUserInfo()- 获取自己的用户信息setSelfInfo(userInfo)- 设置自己的用户信息getUsersInfo(userIDList)- 获取用户信息
消息相关
createTextMessage(text)- 创建文本消息createImageMessageByURL(params)- 创建图片消息createCustomMessage(params)- 创建自定义消息sendMessage(params)- 发送消息revokeMessage(conversationID, clientMsgID)- 撤回消息getAdvancedHistoryMessageList(params)- 获取历史消息
会话相关
getAllConversationList()- 获取所有会话getOneConversation(params)- 获取单个会话markConversationMessageAsRead(conversationID)- 标记会话已读deleteConversation(conversationID)- 删除会话setConversationDraft(params)- 设置会话草稿getTotalUnreadMsgCount()- 获取总未读数
好友相关
getFriendList()- 获取好友列表addFriend(params)- 添加好友deleteFriend(userID)- 删除好友
群组相关
getJoinedGroupList()- 获取加入的群组列表createGroup(params)- 创建群组joinGroup(params)- 加入群组quitGroup(groupID)- 退出群组getGroupMemberList(params)- 获取群成员列表
搜索相关
searchLocalMessages(params)- 搜索本地消息searchFriends(keyword)- 搜索好友searchGroups(keyword)- 搜索群组
事件监听
SDK 支持以下事件:
- 连接状态:
OnConnectSuccess,OnConnectFailed,OnConnecting - 消息:
OnRecvNewMessage,OnRecvMessageRevoked - 会话:
OnConversationChanged,OnTotalUnreadMessageCountChanged - 好友:
OnFriendAdded,OnFriendDeleted,OnFriendInfoChanged - 群组:
OnGroupInfoChanged,OnGroupMemberAdded,OnGroupMemberDeleted
注意事项
- 无本地存储:所有数据仅保存在内存中,应用重启后需要重新同步数据
- 自动重连:WebSocket 连接断开后会自动重连,默认最多重试 5 次
- 消息缓存:消息默认缓存在内存中,可通过搜索功能快速查找
- 类型安全:完整的 TypeScript 类型定义,提供良好的开发体验
License
MIT
