npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@unrealknight/cocos-sdk

v1.0.4

Published

OpenIM SDK for Cocos Creator without local storage

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

注意事项

  1. 无本地存储:所有数据仅保存在内存中,应用重启后需要重新同步数据
  2. 自动重连:WebSocket 连接断开后会自动重连,默认最多重试 5 次
  3. 消息缓存:消息默认缓存在内存中,可通过搜索功能快速查找
  4. 类型安全:完整的 TypeScript 类型定义,提供良好的开发体验

License

MIT