Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
uni-im
比较版本
71ecac6a1e1e661e1573a2e0403f6f9ec04a4fdb...80436324e2657606eabef5c4ffb1b93da5133147
U
uni-im
项目概览
DCloud
/
uni-im
通知
3
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-im
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
源分支
80436324e2657606eabef5c4ffb1b93da5133147
选择Git版本
...
目标分支
71ecac6a1e1e661e1573a2e0403f6f9ec04a4fdb
选择Git版本
比较
Commits (8)
https://gitcode.net/dcloud/uni-im/-/commit/c820842ef2d980af627f438de2ccf9a49a4c1627
新增 客户端错误日志收集功能
2024-11-15T15:27:31+08:00
linju
linju@dcloud.io
https://gitcode.net/dcloud/uni-im/-/commit/23078bb8dcbf8d04e60a97ab3ad783c1db27b1d7
更新 捕获ConversationItem创建错误,并上报
2024-11-15T15:27:31+08:00
linju
linju@dcloud.io
https://gitcode.net/dcloud/uni-im/-/commit/08210daa865bdba940d86cf52e2bffa41a52c5bd
Update msg.js
2024-11-15T15:27:31+08:00
linju
linju@dcloud.io
https://gitcode.net/dcloud/uni-im/-/commit/dc6475c54ce3677654c76c8f2a442214794fbfcd
更新 新增监听错误并上报
2024-11-15T15:27:31+08:00
linju
linju@dcloud.io
https://gitcode.net/dcloud/uni-im/-/commit/2089ffcd0d238970c794baf6132d9b824064708e
更新 解决 web-pc 端退出登录后,补充oauthToken重定向后也会跳转到登录页面的问题
2024-11-15T15:27:31+08:00
linju
linju@dcloud.io
https://gitcode.net/dcloud/uni-im/-/commit/a77462d77a4c788c1be5f9f842638edc2de48a91
更新 修复由3.4.37更新引起的解散群功能出错的问题
2024-11-15T15:27:31+08:00
linju
linju@dcloud.io
https://gitcode.net/dcloud/uni-im/-/commit/5ee53bf6c43c2910fa5a56b068af5fb44f847fcf
更新 拦截异常继续执行
2024-11-15T15:27:32+08:00
linju
linju@dcloud.io
https://gitcode.net/dcloud/uni-im/-/commit/80436324e2657606eabef5c4ffb1b93da5133147
Update readme.md
2024-11-15T15:29:21+08:00
linju
linju@dcloud.io
隐藏空白更改
内联
并排
Showing
9 changed file
with
150 addition
and
31 deletion
+150
-31
readme.md
readme.md
+46
-17
sdk/ext/CloudData.class.js
sdk/ext/CloudData.class.js
+1
-0
sdk/init/index.js
sdk/init/index.js
+7
-1
sdk/state/Conversation.class.js
sdk/state/Conversation.class.js
+10
-6
sdk/state/ConversationItem.class.js
sdk/state/ConversationItem.class.js
+5
-4
sdk/utils/index.js
sdk/utils/index.js
+26
-0
uniCloud/cloudfunctions/uni-im-co/msg.js
uniCloud/cloudfunctions/uni-im-co/msg.js
+7
-2
uniCloud/database/uni-im-error-log.schema.json
uniCloud/database/uni-im-error-log.schema.json
+47
-0
uniCloud/database/uni-im-group.schema.ext.js
uniCloud/database/uni-im-group.schema.ext.js
+1
-1
未找到文件。
readme.md
浏览文件 @
80436324
**uni-im 已开放需求征集和投票**
[
点此前往
](
https://vote.dcloud.net.cn/#/?name=uni-im
)
**uni-im 已开放需求征集和投票**
[
点此前往
](
https://vote.dcloud.net.cn/#/?name=uni-im
)
# 简介
# 简介
uni-im
是云端一体的、全平台的、免费的、开源即时通讯系统。
uni-im
是一款云端一体、全平台、免费且开源的即时通讯系统
-
基于uni-app,App、小程序、web全端兼容
-
基于uni-app,App、小程序、web全端兼容
-
基于uniCloud,前后端都使用js开发
-
基于uniCloud,前后端都使用js开发
-
基于
[
uni-push2
](
https://uniapp.dcloud.net.cn/unipush-v2.html
)
,专业稳定的全端
推送系统
-
基于
[
uni-push2
](
https://uniapp.dcloud.net.cn/unipush-v2.html
)
,专业稳定的全端
消息推送系统(聚合多个手机厂商推送通道,App关闭后也能收到消息)
-
基于
[
uni-id
](
https://uniapp.dcloud.net.cn/uniCloud/uni-id/summary.html
)
,完善的账户体系
-
开放性高,支持非uniCloud(即支持服务端是php、java、go、.net、python、c#等开发语言的项目),甚至非uni-app开发的项目都可以接入使用
-
支持服务端为非uniCloud(比如:应用服务端的开发语言是php、java、go、.net、python、c#等)或 不基于uni-id-pages 开发的项目接入
-
性价比高,前后端代码均免费开源,与同类产品相比,使用uni-im仅需支付因托管在 uniCloud(serverless 服务器)而产生的少量费用,详情可查看文末
`费用说明`
部分
案例:
##
案例:
1.
应用名称:DCloud,该 App 的内置聊天模块,即基于 uni-im 开发。下载地址为:
[
https://im.dcloud.net.cn/uni-portal.html
](
https://im.dcloud.net.cn/uni-portal.html
)
应用名称:DCloud。此 App 的内置聊天模块即是基于 uni-im 开发的。
2.
如图:在插件市场任意插件详情页面,点击“进入交流群”按钮,即可看到基于uni-im搭建的客服系统。
web端网址(支持PC宽屏和移动端):
[
https://im.dcloud.net.cn
](
https://im.dcloud.net.cn
)
<img
width=
"600px"
src=
"https://web-ext-storage.dcloud.net.cn/unicloud/uni-im/img/17198039234743b6c4dd0-27b8-11eb-9e1d-136fabf12402.png"
>
下载地址:
[
https://ext.dcloud.net.cn/plugin?name=uni-im
](
https://ext.dcloud.net.cn/plugin?name=uni-im
)
扫码体验: !
[](
https://web-ext-storage.dcloud.net.cn/doc/im/download.png
)
## 特点优势
下载地址为:
[
https://im.dcloud.net.cn/uni-portal.html
](
https://im.dcloud.net.cn/uni-portal.html
)
-
性价比高;前后端代码均免费开源,相比同类产品使用uni-im仅需花费极少的托管在uniCloud(serverless服务器)产生的费用
[
详情查看
](
#cost
)
-
全端可用
-
App端支持nvue,更好的长列表性能。list组件性能优势
[
详情参考
](
https://uniapp.dcloud.net.cn/component/list.html
)
-
中心化响应式数据管理,切换会话无需重新加载数据,更流畅的体验
-
App端聚合多个手机厂商推送通道,app不在线也可以收到消息
优先开发哪些,取决于开发者的反馈。同时也欢迎开发者共建这个开源项目。
> uni-im相关功能建议或问题,可以加入由uni-im(本插件)搭建的交流群[点此加入](https://im.dcloud.net.cn/#/?joinGroup=63ef49711d358337456f4d67)
> uni-im相关功能建议或问题,可以加入由uni-im(本插件)搭建的交流群[点此加入](https://im.dcloud.net.cn/#/?joinGroup=63ef49711d358337456f4d67)
# 快速部署体验
## 前提条件
1.
获取运行uni-im服务端代码的云服务环境
注意:这里和你自己项目服务端代码是什么语言开发的,以及运行在什么服务器环境无关。uni-im运行在专有的运行环境uniCloud(一种[serverless 服务器](https://uniapp.dcloud.net.cn/uniCloud/#%E4%BB%80%E4%B9%88%E6%98%AFserverless))下。
你的项目服务端和uni-im的服务端之间分别“独立部署”,二者通过发送 http 请求并借助事件进行通讯。
当然,如果你的项目服务端也是基于uniCloud开发的,就可以部署在同一个服务空间内;通过云函数互调通讯。
-
公有云
开通地址:
[
https://unicloud.dcloud.net.cn/
](
https://unicloud.dcloud.net.cn/
)
服务商推荐选择“支付宝云”,性能更好。
-
私有云
普通中小企业项目使用公有云即可,但如果的项目存在特殊需求,例如:政务类、对信息保密性要求较高、用户都在海外的项目,这种情况下则需要进行私有化部署,详情可点击
[
此处
](
https://doc.dcloud.net.cn/uniCloud/software/#uni%E4%BA%91%E5%BC%80%E5%8F%91%E8%BD%AF%E4%BB%B6%E7%89%88
)
。
2.
开通可实时发送消息的推送服务
这里我们需要开通
`uni-push`
,它是基于个推封装的服务;个推是A股上市公司,专业性在推送领域领先。
开通指南:
[
点此打开
](
https://uniapp.dcloud.net.cn/unipush-v2.html#%E7%AC%AC%E4%B8%80%E6%AD%A5-%E5%BC%80%E9%80%9A
)
## 体验步骤
1.
下载示例项目
打开
`uni-im`
插件下载地址:
[
https://ext.dcloud.net.cn/plugin?name=uni-im
](
https://ext.dcloud.net.cn/plugin?name=uni-im
)
点击
`使用HBuilderX导入示例项目`
2.
绑定项目的服务空间
在项目根目录uniCloud右键选择“关联云服务空间或项目”(注意:选择关联的服务空间,需在项目的 uni-push2.0的
[
web控制台
](
https://dev.dcloud.net.cn/pages/app/push2/info
)
被关联)
3.
运行项目
在菜单
`运行`
->
`运行到浏览器`
选择要运行的浏览器
这里需要运行到两个不同的浏览器(避免同一浏览器打开多个uni-im页面,引起socket占线),
`注册账号并登录`
2个账号,体验对话效果
5.
向指定用户发起会话
通过访问路径:
`/uni_modules/uni-im/pages/chat/chat?user_id=`
+
`指定用户的id`
即可。
如果你不知道用户的id,可通过在浏览器控制台执行
`uni.imObservableData.currentUser._id`
可获取当前登录的账号id
注意:以上为连接本地云函数体验,如果要发行为正式项目,需要把uniCloud内的文件部署到云端。操作方式为:对项目根目录uniCloud点右键选择“云服务空间初始化向导”界面按提示部署项目
## 部署到自己的项目
[
详情查看
](
https://doc.dcloud.net.cn/uniCloud/uni-im.html#%E9%83%A8%E7%BD%B2%E5%88%B0%E8%87%AA%E5%B7%B1%E7%9A%84%E9%A1%B9%E7%9B%AE
)
## 使用uniCloud产生的费用说明@cost
## 使用uniCloud产生的费用说明@cost
uni-im本身并不收费,实际使用中需要依赖uniCloud云服务,会产生费用;而uniCloud的价格很实惠:
uni-im本身并不收费,实际使用中需要依赖uniCloud云服务,会产生费用;而uniCloud的价格很实惠:
-
调用10000次云函数仅需0.0133元
-
调用10000次云函数仅需0.0133元
-
调用10000次数据库查询仅需0.015元
-
调用10000次数据库查询仅需0.015元
> 更多计费参考:[
阿里云版uniCloud按量计费文档](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-post
pay)
> 更多计费参考:[
支付宝云版uniCloud按量计费文档](https://doc.dcloud.net.cn/uniCloud/price.html#ali
pay)
### 举例说明:
### 举例说明:
-
单聊场景,向用户发送一条消息的过程:
-
单聊场景,向用户发送一条消息的过程:
...
...
sdk/ext/CloudData.class.js
浏览文件 @
80436324
...
@@ -193,6 +193,7 @@ export default class CloudData {
...
@@ -193,6 +193,7 @@ export default class CloudData {
return
param
==
undefined
?
datas
:
datas
[
0
]
return
param
==
undefined
?
datas
:
datas
[
0
]
}
}
set
(
data
){
set
(
data
){
if
(
!
data
)
return
// 先判断是否存在
// 先判断是否存在
let
item
=
this
.
find
(
data
.
id
||
data
.
_id
||
Object
.
keys
(
data
)[
0
])
let
item
=
this
.
find
(
data
.
id
||
data
.
_id
||
Object
.
keys
(
data
)[
0
])
if
(
item
){
if
(
item
){
...
...
sdk/init/index.js
浏览文件 @
80436324
...
@@ -61,6 +61,12 @@ export default async function (initParam) {
...
@@ -61,6 +61,12 @@ export default async function (initParam) {
});
});
}
}
// 监听所有错误并上报
window
.
addEventListener
(
'
error
'
,
function
(
e
)
{
console
.
error
(
'
监听所有错误并准备上报 error
'
,
e
)
$utils
.
reportError
(
e
.
error
)
});
$state
.
networkConnected
=
navigator
.
onLine
;
$state
.
networkConnected
=
navigator
.
onLine
;
window
.
addEventListener
(
'
online
'
,
function
()
{
window
.
addEventListener
(
'
online
'
,
function
()
{
$state
.
networkConnected
=
true
;
$state
.
networkConnected
=
true
;
...
@@ -186,7 +192,7 @@ export default async function (initParam) {
...
@@ -186,7 +192,7 @@ export default async function (initParam) {
// 第二次 activate 之后开始 检查token是否已经过期,如果已经过期则重定向至登录页面
// 第二次 activate 之后开始 检查token是否已经过期,如果已经过期则重定向至登录页面
const
{
tokenExpired
}
=
$state
.
currentUser
const
{
tokenExpired
}
=
$state
.
currentUser
if
(
!
isLoginPage
&&
count
>
1
&&
tokenExpired
<
Date
.
now
())
{
if
(
!
currentPage
?.
options
?.
oauthToken
&&
!
isLoginPage
&&
count
>
1
&&
tokenExpired
<
Date
.
now
())
{
console
.
info
(
'
uni-im检测到,当前用户登录过且当前登录状态已过期,将自动跳转至登录页面。
'
)
console
.
info
(
'
uni-im检测到,当前用户登录过且当前登录状态已过期,将自动跳转至登录页面。
'
)
uni
.
reLaunch
({
uni
.
reLaunch
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withpwd
'
,
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withpwd
'
,
...
...
sdk/state/Conversation.class.js
浏览文件 @
80436324
...
@@ -129,12 +129,16 @@ export default class Conversation extends CloudData {
...
@@ -129,12 +129,16 @@ export default class Conversation extends CloudData {
// console.log('新增会话', item)
// console.log('新增会话', item)
// 插入客户端创建此会话的时间
// 插入客户端创建此会话的时间
item
.
client_create_time
=
Date
.
now
()
item
.
client_create_time
=
Date
.
now
()
let
conversation
=
new
ConversationItem
(
item
)
try
{
// console.log('新增会话', conversation)
let
conversation
=
new
ConversationItem
(
item
)
const
usersInfo
=
conversation
.
getUsersInfo
()
// console.log('新增会话', conversation)
// 把会话相关的用户信息合并到 $users
const
usersInfo
=
conversation
.
getUsersInfo
()
$users
.
merge
(
usersInfo
)
// 把会话相关的用户信息合并到 $users
resList
.
push
(
conversation
)
$users
.
merge
(
usersInfo
)
resList
.
push
(
conversation
)
}
catch
(
e
){
$utils
.
reportError
(
e
)
}
return
resList
return
resList
},
[])
},
[])
}
}
...
...
sdk/state/ConversationItem.class.js
浏览文件 @
80436324
...
@@ -11,8 +11,9 @@ class ConversationItem {
...
@@ -11,8 +11,9 @@ class ConversationItem {
constructor
(
data
)
{
constructor
(
data
)
{
// 检查是否关联用户/群被删除
// 检查是否关联用户/群被删除
if
(
!
data
.
group_id
&&
!
data
.
user_info
)
{
if
(
!
data
.
group_id
&&
!
data
.
user_info
)
{
console
.
error
(
JSON
.
stringify
(
data
));
// 删除本地生成的 data.client_create_time 避免错误重复上报
throw
new
Error
(
'
会话列表失效,疑似关联用户/群被删除(请改为软删除避免系统异常)
'
);
delete
data
.
client_create_time
throw
new
Error
(
'
会话列表失效,疑似关联用户/群被删除(请改为软删除避免系统异常)data:
'
+
JSON
.
stringify
(
data
));
}
}
// 对话框消息内容
// 对话框消息内容
this
.
chatInputContent
=
""
this
.
chatInputContent
=
""
...
@@ -38,8 +39,8 @@ class ConversationItem {
...
@@ -38,8 +39,8 @@ class ConversationItem {
// 群聊
// 群聊
this
.
group
=
$state
.
group
.
find
(
this
.
group_id
)
this
.
group
=
$state
.
group
.
find
(
this
.
group_id
)
if
(
!
this
.
group
)
{
if
(
!
this
.
group
)
{
console
.
error
(
'
群聊
本地不存在 this.group_id
'
,
this
.
group_id
);
console
.
error
(
'
群聊
不存在
'
,
this
)
//
throw new Error('群聊不存在')
throw
new
Error
(
'
群聊不存在
'
)
}
}
// 2. 设置群tag
// 2. 设置群tag
...
...
sdk/utils/index.js
浏览文件 @
80436324
...
@@ -271,4 +271,30 @@ export default {
...
@@ -271,4 +271,30 @@ export default {
showCancel
:
false
showCancel
:
false
});
});
},
},
async
reportError
(
error
){
// 上报错误
const
dbJQL
=
uniCloud
.
databaseForJQL
()
let
content
=
{
stack
:
error
.
stack
,
message
:
error
.
message
,
code
:
error
.
code
}
content
=
JSON
.
stringify
(
content
)
const
content_md5
=
md5
(
error
.
message
)
// 查询是否已经上报过
let
res
=
await
dbJQL
.
collection
(
'
uni-im-error-log
'
).
where
({
content_md5
}).
get
()
if
(
res
.
data
.
length
===
0
){
res
=
await
dbJQL
.
collection
(
'
uni-im-error-log
'
).
add
({
content
,
content_md5
})
}
else
{
res
=
await
dbJQL
.
collection
(
'
uni-im-error-log
'
).
doc
(
res
.
data
[
0
].
_id
).
update
({
count
:
(
res
.
data
[
0
]?.
count
||
1
)
+
1
})
}
console
.
warn
(
'
【bug已上报】uni-im-sdk error has reported
'
,
res
,{
error
})
}
}
}
uniCloud/cloudfunctions/uni-im-co/msg.js
浏览文件 @
80436324
...
@@ -133,7 +133,11 @@ async function sendMsg(params) {
...
@@ -133,7 +133,11 @@ async function sendMsg(params) {
nickname
=
userInfo
.
nickname
nickname
=
userInfo
.
nickname
avatar_file
=
userInfo
.
avatar_file
avatar_file
=
userInfo
.
avatar_file
}
else
{
}
else
{
console
.
error
(
'
用户信息不存在
'
,
from_uid
);
return
{
"
code
"
:
30202
,
"
errCode
"
:
"
uni-id-check-token-failed
"
,
"
errMsg
"
:
"
请重新登录
"
}
}
}
}
}
...
@@ -425,6 +429,7 @@ async function _createOrUpdateConversation(conversation_id, msgData, chat_source
...
@@ -425,6 +429,7 @@ async function _createOrUpdateConversation(conversation_id, msgData, chat_source
name
:
true
name
:
true
})
})
.
get
()
.
get
()
console
.
error
(
'
groupInfo------
'
,
res
.
data
[
0
]);
groupInfo
=
res
.
data
[
0
]
groupInfo
=
res
.
data
[
0
]
}
}
...
@@ -732,7 +737,7 @@ async function _processPush({ msgData, isMute, appId,groupInfo }) {
...
@@ -732,7 +737,7 @@ async function _processPush({ msgData, isMute, appId,groupInfo }) {
const
{
nickname
,
avatar_file
}
=
msgData
const
{
nickname
,
avatar_file
}
=
msgData
let
title
let
title
let
content
let
content
if
(
msgData
.
group_id
){
if
(
groupInfo
){
title
=
groupInfo
.
name
title
=
groupInfo
.
name
content
=
nickname
.
slice
(
0
,
20
)
+
'
:
'
+
(
msgData
.
type
==
'
text
'
?
msgData
.
body
:
'
[多媒体]
'
)
content
=
nickname
.
slice
(
0
,
20
)
+
'
:
'
+
(
msgData
.
type
==
'
text
'
?
msgData
.
body
:
'
[多媒体]
'
)
}
else
{
}
else
{
...
...
uniCloud/database/uni-im-error-log.schema.json
0 → 100644
浏览文件 @
80436324
//
文档教程:
https://uniapp.dcloud.net.cn/uniCloud/schema
{
"bsonType"
:
"object"
,
"required"
:
[],
"permission"
:
{
"read"
:
false
,
"create"
:
"auth.uid != null"
,
"update"
:
false
,
"delete"
:
false
},
"properties"
:
{
"_id"
:
{
"description"
:
"ID,系统自动生成"
},
"user_id"
:
{
"bsonType"
:
"string"
,
"description"
:
"反馈用户ID"
,
"foreignKey"
:
"uni-id-users._id"
,
"forceDefaultValue"
:
{
"$env"
:
"uid"
}
},
"create_time"
:
{
"bsonType"
:
"timestamp"
,
"forceDefaultValue"
:
{
"$env"
:
"now"
}
},
"content"
:
{
"bsonType"
:
"string"
,
"title"
:
"内容"
},
"count"
:
{
"bsonType"
:
"int"
,
"description"
:
"反馈次数"
},
"content_md5"
:
{
"bsonType"
:
"string"
,
"description"
:
"内容MD5,用于防止重复插入重复的信息"
},
"is_fixed"
:
{
"bsonType"
:
"bool"
,
"description"
:
"是否已修复"
,
"forceDefaultValue"
:
false
}
}
}
\ No newline at end of file
uniCloud/database/uni-im-group.schema.ext.js
浏览文件 @
80436324
...
@@ -111,12 +111,12 @@ module.exports = {
...
@@ -111,12 +111,12 @@ module.exports = {
groupName
:
triggerContext
.
groupInfo
.
name
,
groupName
:
triggerContext
.
groupInfo
.
name
,
}
}
}
}
await
uniImCo
.
sendMsg
(
msgData
,
userInfo
.
uid
)
// 临时方案 加一条被软删除的群记录
// 临时方案 加一条被软删除的群记录
await
db
.
collection
(
'
uni-im-group
'
).
add
({
await
db
.
collection
(
'
uni-im-group
'
).
add
({
...
triggerContext
.
groupInfo
,
...
triggerContext
.
groupInfo
,
is_delete
:
true
is_delete
:
true
})
})
await
uniImCo
.
sendMsg
(
msgData
,
userInfo
.
uid
)
}
}
}
}
}
}