更新记录

1.0.0(2025-10-23) 下载此版本

首次发布。支持私聊、历史消息存储。支持除H5之外的全平台


平台兼容性

uni-app x(3.6.11)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × √ √ √ √

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × × √

产品简介

wenruoIM是专门为UniappX开发人员打造的IM产品,致力于打造一款高性能、简单、安全可靠的IM

wenruoIM支持IM聊天,同时也支持Websocket推送(仅支持单向)

目前支持:Android、iOS、小程序、鸿蒙。H5暂不支持(有需要的话后续会增加H5)

功能支持情况

功能 支持
私聊 √
websocket √
图片、视频、文件 √
自定义消息 √
消息已读未读 √
群聊 开发中
音视频通话 看市场反应决定是否开发

wenruoIm版权归作者所有,目前已在公司产品中投入使用,因此不用担心后续不维护,或者作者跑路问题

作者在此承诺,即便官方出了IM,wenruoIM也会持续维护,直到真的没人再用了

开发文档

wenruoIM开发文档

应用场景

站内私信、在线交友、在线招聘、办公交流、婚恋交友、用户咨询、技术支持、在线客服

优势

  • 对接简单:总共十来个API,参数很少,喝喝咖啡摸摸鱼就能对接完毕
  • 成本低:最低288元/月起
  • 技术支持:技术人员长期在线,一对一技术支持
  • 性能高:支持海量用户同时在线,支持每秒百万级消息
  • 私有化:wenruoIM默认提供云服务版本,用户也可以选择私有化部署或者二开版本

SDK集成

下载与导入

下载

加作者联系方式获取SDK

导入

import { getImInstance } from '@/uni_modules/wenruo-im'

初始化连接

方法定义

getInstance(param : InstanceParam): Im;

参数

参数名 数据类型 是否必传 描述
host string √ 接口地址
appKey string √ wenruoIM为开发者分配的应用id
appSecret string √ 秘钥
module string √ 初始化模块,可选值为:im、ws。注意大小写。如果都需要,则用逗号隔开

示例

const im = getImInstance({
  host: '192.168.0.103:8080',
  appKey: 'jqn',
  appSecret: 'jqn',
  module: 'im,ws'
})

:::info 为了防止多次初始化,建议将初始化之后的im对象挂载为全局对象

:::

建立连接

方法定义

connect(param : ImConnectParam) : void;

参数

参数名 数据类型 是否必传 描述
userId string number √ 本次开启链接的用户id
onSuccess ()=>void × 链接成功后的回调
onError (e: string)=>void × 链接失败时的回调。e:链接失败原因
param UTSJSONObject × 额外参数,预留字段,暂时没用

示例

im.connect({
  userId: "1",
  onSuccess() {
    console.log('链接成功');
  },
  onError(e) {
    console.log('链接失败:' + e);
  }
})

:::info 建立连接时传递的userId,会在sdk中保留下来,用户调用API时,如果接口需要使用到当前用户id,会在sdk中进行填充,因此后续调用接口传递的参数中,不会再有发送者的用户id

强烈不建议用户重复开启链接,对于重复的链接,会占用系统资源。当然,在断开连接之前,开发者也无法重复建立连接。

对于微信小程序,如果需要使用wenruoIm,则需要登录微信公众平台->小程序开发设置->服务器域名,把wenruoIm的host加入到socket合法域名中

:::

监听关闭与异常

方法定义

/**
 * 关闭链接回调
 */
onClose(res : (e: any) => void): void;
/**
 * 链接异常回调
 * GeneralCallbackResult:
 */
onError(res : (e: GeneralCallbackResult) => void): void;

type GeneralCallbackResult = {
    errMsg: string;
}

GeneralCallbackResult

参数名 数据类型 是否必传 描述
errMsg string × 错误文本

示例

im.onClose(e => {
  console.log('链接已断开!', e);
})
im.onError(e => {
  console.log('链接异常!', e);
})

:::info 正常关闭连接时,都会走onClose方法,但是对于APP异常关闭链接,走的是onError方法。开发者需要自行处理业务逻辑,当e.errMsg='Connection reset'时为链接异常关闭

:::

发起会话

调用该方法,用来发起聊天。目前仅支持私聊,群聊功能开发中。

方法定义

openChat(param: CreateImChatParam, callable: HttpCallableModel) : void;

示例

im.openChat({
  userId2: "2"
}, {
  success(e) {
    console.log('会话开启:', e);
  }
})

CreateImChatParam

参数名 数据类型 是否必传 描述
userId2 string number √ 消息接收者用户ID

HttpCallableModel

参数名 数据类型 是否必传 描述
success (e: ImResponse)=>void × 接口调用成功回调
fail (e: RequestFail)=>void × 接口调用失败回调
complete (e: any)=>void × 不管成功或者失败都会回调

该类型在后续的接口中也会使用到,后续不会再重复说明

ImResponse

参数名 数据类型 是否必传 描述
code number √ 状态码,20000为正常
msg string × 提示文本,状态码非20000时会有
data UTSJSONObject Array × 接口返回数据。不同的接口返回格式不同。文档中的ImResponse.data只是为了方便开发者查阅文档,实际开发时直接无脑点出来属性就像

ImResponse.data(聊天对象)

参数名 数据类型 是否必传 描述
id string √ 聊天id
appKey string √ 对接appKey
chatType string √ 聊天类型,private私聊,group群聊。暂时只支持私聊
userId1 string √ 发起聊天用户
userId2 string × 接收聊天用户。私聊时必有
createTime string √ 聊天创建时间
isTop number √ 置顶状态,1置顶,0不置顶
unreadCount number √ 未读消息数
messageList Array × 从最早的一条未读消息开始,往后的所有消息列表

ImMessage(消息对象)

参数名 数据类型 是否必传 描述
id string √ 消息id
appKey string √ 应用id
chatId string √ 聊天id
sendType string √ private私聊,group群聊
msgType string √ 消息类型, text:文字 radio:音频 img:图片 video:视频 此外用户还可以自定义消息类型。消息类型字段暂时服务端不做任何额外处理,用户传递什么值,查询出来就是什么值,只是为了方便用户开发时判断消息类型
isPush boolean √ 消息是否已推送
senderId string √ 发送者id
senderMeta MetaData √ 发送者元数据
-header string √ 发送者头像
-nickName string √ 发送者昵称
receiverId string √ 接收者id
receiverMeta MetaData √ 接收者元数据
-header string √ 接收者头像
-nickName string √ 接收者昵称
content string √ 消息内容。json字符串 文本消息:{text: 文本内容} 视频音频图片:{url: 内容地址},文件上传需要用户自行实现 自定义消息:格式自定义但必须是json字符串
messageTime string √ 消息时间
readList Array √ 是否已读
-userId string √ 用户id
-nickName string √ 用户昵称
-read boolean √ 是否已读,true已读,false未读

:::info 发起会话时,当前用户的id已在sdk中传递,因此参数只需要传递userId2即可

发起回话接口,在正常进入会话时,也需要调用

消息对象ImMessage在后续发送消息、查询历史消息都会用到,后续遇到不再重复说明

对于聊天对象,userId1为发送者,userId2为接收者。但是在实际调用时,假设userId1=1,userId2=2,对于id为1和2的用户都会查询到该聊天,但是两个字段的值是不变的。因此开发者需要自行区分谁是发送者,谁是接收者

由于wenruoIm不提供用户注册功能,因此在发送消息时需要携带用户的头像、昵称信息。当开发者的产品中用户信息更新时,历史消息中的用户头像和昵称不会实时更新。

消息本身是支持任何类型的消息的,只要满足json字符串即可。甚至你可以以 {text: json字符串} 的形式来传递文本消息,方便自己去发送图文消息。对于图片、音频、视频消息,需要用户自行处理文件上传逻辑,然后把url按照一定的格式传递(毕竟把七牛云、oss的appKey和appSecret放到作者的平台,很多开发者都会觉得不安全)

:::

监听消息

方法定义

    /**
     * 监听IM消息
     */
    onImMessage(res : (data : UTSJSONObject) => void) : void;
    /**
     * 监听Websocket消息
     */
    onWsMessage(res : (data : UTSJSONObject) => void) : void;

IM消息回调参数

ImMessage格式,具体参考发起会话章节

WebSocket消息回调参数

参数名 数据类型 是否必传 描述
code number √ 消息编码,1000为正常
type string × 消息类型,开发者可以根据不同的type去处理不同的逻辑。当code为1000时必有
msg string × 错误提示文本,当code为非1000时必有
data UTSJSONObject × 消息对象。当code为1000时必有。用户推送ws消息时为什么格式,接收到消息时就是什么格式。根据type的类型去操作data。注意,哪怕是推送普通的消息通知,用户接收到也是在data中,以JSON格式存储的,msg字段不用于推送消息,仅用于系统异常时给出错误提示

示例

im.onImMessage((e) => {
  console.log(e);
})
im.onWsMessage((e) => {
  console.log(e);
})

:::info wenruoIM提供了推送消息的接口。开发者在服务端处理完业务后,根据自己的业务需求决定是否推送通知消息。推送消息时,消息以JSON格式传递,前端监听接收到消息时,data即为用户传递的数据格式,因此data的结构是由用户决定的,不是由wenruoIM决定的

:::

发送消息

方法定义

send(data : UTSJSONObject) : void;

ImMessage

参数格式与发起会话章节一致,而发送消息时,像 isPush这类字段是不需要传递的,因此这里重新列出发送消息时需要传递的参数。ImMessage完整格式请查看发起会话章节

参数名 数据类型 是否必传 描述
chatId string √ 聊天id
sendType string √ private私聊,group群聊
msgType string √ 消息类型, text:文字 radio:音频 img:图片 video:视频 此外用户还可以自定义消息类型。消息类型字段暂时服务端不做任何额外处理,用户传递什么值,查询出来就是什么值,只是为了方便用户开发时判断消息类型
senderMeta MetaData √ 发送者元数据
-header string √ 发送者头像
-nickName string √ 发送者昵称
receiverId string √ 接收者id
receiverMeta MetaData √ 接收者元数据
-header string √ 接收者头像
-nickName string √ 接收者昵称
content string √ 消息内容。json字符串 文本消息:{text: 文本内容} 视频音频图片:{url: 内容地址},文件上传需要用户自行实现 自定义消息:格式自定义但必须是json字符串

示例

const msg = {
  sendType: 'private',
  msgType: 'text',
  receiverId: userId2,
  content: '{"text": "哈哈哈哈哈"}',
  chatId: chatId,
  senderMeta: {
    header: 'http://123123',
    nickName: '张三'
  },
  receiverMeta: {
    header: 'http://123123',
    nickName: '李四'
  }
}
im.send(msg)

:::info 目前消息发送仅支持私聊。群聊功能、通知栏推送开发中。

wenruoIM是作者公司产品需要使用,因此公司产品没有用到的功能,目前没有开发,后续会不断完善,请关注更新日志。

:::

关闭链接

方法定义

disconnect(res : () => void) : void;

参数

参数名 数据类型 是否必传 描述
res () => void √ 关闭成功后的回调

示例

im.disconnect(()=>{
  console.log('关闭链接成功');
})

查询会话列表

查询用户所有的会话列表,目前没有提供分页功能,正常情况下一个人聊天会话不会太多,一百多个顶天了,所以方便起见就直接全拉下来。该方法会查询用户的所有聊天列表,以及每个聊天的最后一条消息,以及未读消息数。

方法定义

getChatList(callable: HttpCallableModel) : void;

HttpCallableModel与发起会话章节一致。这里只列出接口调用成功时的返回值

ImResponse.data

格式为数组,数组中对象结构如下

参数名 数据类型 是否必传 描述
id string √ 聊天id
appKey string √ 对接appKey
chatType string √ 聊天类型,private私聊,group群聊。暂时只支持私聊
userId1 string √ 发起聊天用户
userId2 string × 接收聊天用户。私聊时必有
createTime string √ 聊天创建时间
isTop number √ 置顶状态,999置顶,0不置顶
unreadCount number √ 未读消息数
messageList Array × 最后一条消息

示例

im.getChatList({
  success(e) {
    console.log('会话列表:', e);
  }
})

:::info 请确保首次调用该接口在监听消息之前,这样能保证未读消息数和最后一条消息的准确性。之后监听消息,收到最新消息推送时,开发者需要自行处理未读消息数的增加,和最后一条消息的变更(如果有对应的需求的话)

关于置顶状态的细节,请参考 切换会话置顶状态 章节

:::

删除会话

当会话太多时,用户可以自行删除会话

方法定义

deleteChat(param: DeleteChatParam, callable: HttpCallableModel) : void;

其中,HttpCallableModel.sucess回调的data字段没有返回结果,只要回调成功,用户就可以处理后续逻辑

DeleteChatParam

参数名 数据类型 是否必传 描述
chatId string √ 聊天id

示例

im.deleteChat({
  chatId: chatId
}, {
  success(e) {
    console.log('删除聊天:', e);
  }
})

:::info 对于回话,服务端的处理逻辑是,给会话绑定用户id,删除会话其实是删除这个绑定关系,当用户A向用户B创建会话,发送消息,后续用户B删除会话,用户A依然能够看到会话,当二者重新聊天时(不管是哪一方发起的),都会重新绑定会话,且之前的聊天记录并不会丢失。只有当两个用户都把会话删除时,才会真正删除会话和该会话的全部聊天记录

:::

切换会话置顶状态

方法定义

toggleTop(param: UserChatParam, callable: HttpCallableModel) : void;

其中,HttpCallableModel.sucess回调的data字段没有返回结果,只要回调成功,用户就可以处理后续逻辑

UserChatParam

参数名 数据类型 是否必传 描述
chatId string √ 聊天id
isTop number √ 置顶状态,0未置顶,999置顶

示例

im.toggleTop({
  chatId: chatId,
  isTop: 999
}, {
  success(e) {
    console.log('切换置顶:', e);
  }
})

:::info isTop仅是一个状态值,服务端没有做任何校验,仅根据isTop的值倒序排序,为的是给用户足够灵活的操作空间,比如你可以使用666作为VIP群的标识,也可以使用该方法来切换VIP标识。使用999的目的是保证置顶的消息永远在最上面,毕竟一个聊天功能不可能有1000个聊天状态吧hhhhhh。

:::

查询历史聊天记录

分页查询指定会话已推送的聊天记录,未推送的消息不会查询。

方法定义

getHistoryMessageList(param: getMessageListParam, callable: HttpCallableModel) : void;

其中,HttpCallableModel.sucess回调的data字段没有返回结果,只要回调成功,用户就可以处理后续逻辑

getMessageListParam

参数名 数据类型 是否必传 描述
chatId string √ 聊天id
limit number √ 每页查询条数
totalMessageCount number √ 当前聊天页面已经展示多少条消息,有新消息时需要自行增加
lastMessageId number string × 最顶部的消息id

示例

im.getHistoryMessageList({
  chatId: chatId,
  // 当前聊天总消息数
  totalMessageCount: 0,
  limit: 10
}, {
  success(e) {
    console.log('聊天记录:', e);
  }
})

:::info 注意,聊天记录的查询与传统的分页查询不同。聊天记录的交互是上拉加载,因此分页是倒着分页的。为了方便前端开发者数据处理,参数会与传统的分页不同。

比如目前数据库中消息如下表

:::

ID 消息 已读
1 唱 √
2 跳 √
3 rap √
4 篮球 √
5 鸡 √
6 你 √
7 太 √
8 美 √
9 baby ×
10 music ×
11 你干嘛 ×

:::info 当发起回话的时候,会查询出第一条未读消息,以及之后所有的消息,因此9、10、11被查出

后续调用时,limit=4, totalMessageCount=3, lastMessageId=9,服务端就会查出5、6、7、8四条消息。之后用户需要把totalMessageCount变更为7,lastMessageId变更为5。

在查询下一页之前,如果有一条消息推送过来,id=12,用户需要更新totalMessageCount为4,才能正常查出下一页的消息。如果没有更新,下一页会查询出重复数据。因此用户必须要根据逻辑去实时更新totalMessageCount

:::

推送websocket消息

该接口为服务端调用接口。开发者根据自己的业务逻辑,调用接口,为前端推送相应的数据

推送到个人

接口地址:/wsSend/sendMessage

参数

参数名 数据类型 是否必传 描述
userId string √ 用户id
type string √ 消息类型
appKey string √ 给开发者分配的应用id
data Object √ 消息内容

返回值

参数名 数据类型 是否必传 描述
code number √ 状态码,20000为正常
msg string √ 提示文本,状态码非20000则有

推送到全部用户

接口地址:/wsSend/sendAllMessage

参数

参数名 数据类型 是否必传 描述
type string √ 消息类型
appKey string √ 给开发者分配的应用id
data Object √ 消息内容

返回值

参数名 数据类型 是否必传 描述
code number √ 状态码,20000为正常
msg string √ 提示文本,状态码非20000则有

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议