fix:update docs

This commit is contained in:
SL 2024-10-18 18:27:14 +08:00
commit 21d7fa3a59
54 changed files with 3720 additions and 1860 deletions

View File

@ -1 +1 @@
node_modules/
node_modules

View File

@ -20,13 +20,13 @@ export const navbar: DefaultTheme.NavItem[] = [
text: "SDK文档",
activeMatch: "^/sdk",
items: [
{ text: "iOS", link: "/sdk/ios" },
{ text: "iOS", link: "/sdk/iossdk/intro" },
{ text: "Android", link: "/sdk/android" },
{ text: "Javascript", link: "/sdk/jssdk/intro" },
{ text: "Flutter", link: "/sdk/flutter" },
{ text: "Uniapp", link: "/sdk/uniapp" },
{ text: "微信小程序", link: "/sdk/smallprogram" },
{ text: "harmonyOS", link: "/sdk/harmonyos" },
{ text: "HarmonyOS", link: "/sdk/harmonyos" },
],
},
{
@ -42,9 +42,9 @@ export const navbar: DefaultTheme.NavItem[] = [
// link: "https://gitee.com/WuKongDev/WuKongIM/releases",
// },
{
"text": "v2.0.1 (beta)",
"text": "v2",
items: [
{text: "v1.2.5 (stable)", link: "/1.0/"},
{text: "v1", link: "https://v1.githubim.com/guide/guide.html"},
],
},
];

View File

@ -88,10 +88,10 @@ export const sidebar: DefaultTheme.Sidebar = {
{ text: "多节点模式扩容", link: "/install/k8s/multinode-scale" },
],
},
{
text: "升级",
link: "/install/k8s/upgrade",
},
// {
// text: "升级",
// link: "/install/k8s/upgrade",
// },
],
},
@ -129,7 +129,6 @@ export const sidebar: DefaultTheme.Sidebar = {
],
"/sdk": [
{ text: "概述", link: "/sdk/" },
{ text: "iOS", link: "/sdk/ios" },
{
text: "Android",
collapsed: true,
@ -148,6 +147,46 @@ export const sidebar: DefaultTheme.Sidebar = {
{ text: "示例代码", link: "https://github.com/WuKongIM/WuKongIMAndroidSDK" },
]
},
{
text: "iOS",
collapsed: true,
items: [
{ text: "说明", link: "/sdk/iossdk/intro" },
{ text: "集成", link: "/sdk/iossdk/integration" },
{ text: "连接管理", link: "/sdk/iossdk/connection" },
{ text: "聊天管理", link: "/sdk/iossdk/chat" },
{ text: "最近会话管理", link: "/sdk/iossdk/conversation" },
{ text: "频道管理", link: "/sdk/iossdk/channel" },
{ text: "多媒体管理", link: "/sdk/iossdk/media" },
{
text: "高级功能",
items: [
{
text: "自定义消息",
link: "/sdk/iossdk/advance/custommessage"
},
{
text: "消息编辑",
link: "/sdk/iossdk/advance/messageEdit"
},
{
text: "消息点赞",
link: "/sdk/iossdk/advance/messageReaction"
},
{
text: "消息已读",
link: "/sdk/iossdk/advance/messageReaded"
},
{
text: "会话提醒",
link: "/sdk/iossdk/advance/reminder"
},
]
},
{ text: "示例代码", link: "https://github.com/WuKongIM/WuKongIMiOSSDK/tree/main/Example" },
]
},
{
text: "Javascript",
collapsed: true,

3207
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@ title: 介绍
| WuKongIMJSSDK | [Github](https://github.com/WuKongIM/WuKongIMJSSDK) | [Example](https://github.com/WuKongIM/WuKongIMJSSDK/tree/main/examples) | [文档](https://githubim.com/sdk/javascript.html) | WuKongIM的 JS SDK |
| WuKongIMFlutterSDK | [Github](https://github.com/WuKongIM/WuKongIMFlutterSDK) | [Example](https://github.com/WuKongIM/WuKongIMFlutterSDK/tree/master/example) |[文档](https://githubim.com/sdk/flutter.html) | WuKongIM的 Flutter SDK |
| WuKongIMReactNativeDemo | [Github](https://github.com/wengqianshan/WuKongIMReactNative) | 无 | 无 | WuKongIM的 React Native Demo(由贡献者 [wengqianshan](https://github.com/wengqianshan) 提供) |
| WuKongIMHarmonyOSSDK | [Github](https://github.com/WuKongIM/WuKongIMHarmonyOSSDK) | [Example](https://github.com/WuKongIM/WuKongIMHarmonyOSSDK/tree/main/entry) | [文档](https://githubim.com/sdk/harmonyos.html) | WuKongIM的纯血鸿蒙OS SDK |
有需要加微信群交流:

View File

@ -44,7 +44,7 @@
0⃣ **易用性**
不依任何第三方中间件,部署简单,一条命令即可启动。
不依任何第三方中间件,部署简单,一条命令即可启动。
采用频道订阅发布的设计理念,容易理解,容易上手。

View File

@ -35,7 +35,7 @@ cd ~/wukongim
version: '3.7'
services:
wukongim: # WuKongIM服务
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2.0.1-beta-20240715
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2
environment:
- "WK_CLUSTER_NODEID=1004"
- "WK_CLUSTER_APIURL=http://10.206.0.6:5001" # 节点内部通信api url地址这里ip换成自己节点实际node2的内网ip

View File

@ -12,7 +12,7 @@ WuKongIM集群符合 `2n+1` 原则n表示宕机数量比如允许1台机
## 环境要求
- 机器数量:3台或以上
- 机器数量:4台或以上
- Linux系统推荐Ubuntu(推荐配置 2核4G或4核8G)
@ -20,14 +20,203 @@ WuKongIM集群符合 `2n+1` 原则n表示宕机数量比如允许1台机
假设三台服务器,信息如下
| 名称 | 内网IP | 外网IP |
| --- | --- | --- |
| node1(1001) | 10.206.0.13 | 119.45.229.172 |
| node2(1002) | 10.206.0.14 | 129.211.213.76 |
| node3(1003) | 10.206.0.8 | 1.13.191.138 |
| 角色 | 说明 | 内网IP | 外网IP |
| --- | --- | --- | --- |
| 负载均衡和监控 | gateway | 10.206.0.2 | 119.45.33.109 |
| WuKongIM节点 |node1(ID: 1) | 10.206.0.10 | 146.56.249.208 |
| WuKongIM节点 |node2(ID: 2) | 10.206.0.12 | 129.211.171.99 |
| WuKongIM节点 |node3(ID: 3) | 10.206.0.5 | 119.45.175.82 |
## 安装
## 安装负载均衡和监控
#### 1. 创建安装目录(`gateway`
`gateway`节点创建目录
```bash
mkdir ~/gateway
```
#### 2. 在安装目录创建docker-compose.yml文件
`gateway`节点的安装目录(`~/gateway`)里创建`docker-compose.yml`文件,内容如下:
```yaml
version: '3.7'
services:
prometheus: # 监控服务
image: registry.cn-shanghai.aliyuncs.com/wukongim/prometheus:v2.53.1
volumes:
- "./prometheus.yml:/etc/prometheus/prometheus.yml"
ports:
- "9090:9090"
nginx: # 负载均衡
image: registry.cn-shanghai.aliyuncs.com/wukongim/nginx:1.27.0
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- "15001:15001"
- "15100:15100"
- "15200:15200"
- "15300:15300"
- "15172:15172"
```
#### 3. 配置负载均衡
`gateway`节点的安装目录(`~/gateway`)里创建`nginx.conf`文件,内容如下:
```nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# api负载均衡
upstream wukongimapi {
server 10.206.0.10:5001;
server 10.206.0.12:5001;
server 10.206.0.5:5001;
}
# demo负载均衡
upstream wukongimdemo {
server 10.206.0.10:5172;
server 10.206.0.12:5172;
server 10.206.0.5:5172;
}
# manager负载均衡
upstream wukongimanager {
server 10.206.0.10:5300;
server 10.206.0.12:5300;
server 10.206.0.5:5300;
}
# ws负载均衡
upstream wukongimws {
server 10.206.0.10:5200;
server 10.206.0.12:5200;
server 10.206.0.5:5200;
}
# http api转发
server {
listen 15001;
location / {
proxy_pass http://wukongimapi;
proxy_connect_timeout 20s;
proxy_read_timeout 60s;
}
}
# demo
server {
listen 15172;
location / {
proxy_pass http://wukongimdemo;
proxy_connect_timeout 20s;
proxy_read_timeout 60s;
}
location /login {
rewrite ^ /chatdemo?apiurl=http://119.45.33.109:15001;
proxy_pass http://wukongimdemo;
proxy_connect_timeout 20s;
proxy_read_timeout 60s;
}
}
# manager
server {
listen 15300;
location / {
proxy_pass http://wukongimanager;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
}
}
# ws
server {
listen 15200;
location / {
proxy_pass http://wukongimws;
proxy_redirect off;
proxy_http_version 1.1;
# nginx接收upstream server数据超时, 默认120s, 如果连续的120s内没有收到1个字节, 连接关闭
proxy_read_timeout 120s;
# nginx发送数据至upstream server超时, 默认120s, 如果连续的120s内没有发送1个字节, 连接关闭
proxy_send_timeout 120s;
# nginx与upstream server的连接超时时间
proxy_connect_timeout 4s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
# tcp
stream {
# tcp负载均衡
upstream wukongimtcp {
server 10.206.0.10:5100;
server 10.206.0.12:5100;
server 10.206.0.5:5100;
}
server {
listen 15100;
proxy_connect_timeout 4s;
proxy_timeout 120s;
proxy_pass wukongimtcp;
}
}
```
#### 4. 配置监控
`gateway`节点的安装目录(`~/gateway`)里创建`prometheus.yml`文件,内容如下:
```yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: wukongim1-trace-metrics
static_configs:
- targets: ['10.206.0.10:5300']
labels:
id: "1"
- job_name: wukongim2-trace-metrics
static_configs:
- targets: ['10.206.0.12:5300']
labels:
id: "2"
- job_name: wukongim3-trace-metrics
static_configs:
- targets: ['10.206.0.5:5300']
labels:
id: "3"
```
## 安装WuKongIM节点
#### 1. 创建安装目录(`所有节点`
@ -39,8 +228,6 @@ mkdir ~/wukongim
```
#### 2. 在安装目录创建docker-compose.yml文件
`node1`节点上的安装目录(`~/wukongim`)里创建`docker-compose.yml`文件,内容如下:
@ -49,17 +236,17 @@ mkdir ~/wukongim
version: '3.7'
services:
wukongim: # WuKongIM服务
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2.0.1-beta-20240715
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2
environment:
- "WK_MODE=release" # release模式
- "WK_CLUSTER_NODEID=1001"
- "WK_EXTERNAL_IP=119.45.229.172" # 当前节点外网ip
- "WK_CLUSTER_APIURL=http://10.206.0.13:5001" # 节点内部通信api url地址这里ip换成自己节点实际node2的内网ip
- "WK_CLUSTER_SERVERADDR=10.206.0.13:11110" # 节点内部通信请求地址
- "WK_EXTERNAL_WSADDR=ws://119.45.229.172:15200" # web端访问的ws长连接地址这里设置负载均衡的地址即可这样让负载均衡来分配WuKongIM
- "WK_EXTERNAL_TCPADDR=119.45.229.172:15100" # app端访问的tcp长连接地址这里设置负载均衡的地址即可这样让负载均衡来分配WuKongIM
- "WK_TRACE_PROMETHEUSAPIURL=http://10.206.0.13:9090" # 监控地址
- "WK_CLUSTER_INITNODES=1001@10.206.0.13 1002@10.206.0.14 1003@10.206.0.8" # 集群节点列表
- "WK_CLUSTER_NODEID=1" # 节点id不能大于等于1024
- "WK_EXTERNAL_IP=146.56.249.208" # 当前节点外网ip
- "WK_CLUSTER_APIURL=http://10.206.0.10:5001" # 节点内部通信api url地址这里ip换成自己节点实际的内网ip
- "WK_CLUSTER_SERVERADDR=10.206.0.10:11110" # 节点内部通信请求地址
- "WK_EXTERNAL_WSADDR=ws://119.45.33.109:15200" # web端访问的ws长连接地址这里设置负载均衡的地址即可这样让负载均衡来分配WuKongIM节点
- "WK_EXTERNAL_TCPADDR=119.45.33.109:15100" # app端访问的tcp长连接地址这里设置负载均衡的地址即可这样让负载均衡来分配WuKongIM节点
- "WK_TRACE_PROMETHEUSAPIURL=http://10.206.0.2:9090" # 监控内网地址
- "WK_CLUSTER_INITNODES=1@10.206.0.10 2@10.206.0.12 3@10.206.0.5" # 集群初始节点列表
healthcheck:
test: "wget -q -Y off -O /dev/null http://localhost:5001/health > /dev/null 2>&1"
interval: 10s
@ -75,22 +262,6 @@ services:
- 5200:5200 # websocket端口
- 5300:5300 # 管理端端口
- 5172:5172 # demo端口
prometheus: # 监控服务
image: registry.cn-shanghai.aliyuncs.com/wukongim/prometheus:v2.53.1
volumes:
- "./prometheus.yml:/etc/prometheus/prometheus.yml"
ports:
- "9090:9090"
nginx: # 负载均衡
image: registry.cn-shanghai.aliyuncs.com/wukongim/nginx:1.27.0
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- "15001:5001"
- "15100:5100"
- "15200:5200"
- "15300:5300"
- "15172:5172"
```
@ -102,17 +273,17 @@ services:
version: '3.7'
services:
wukongim: # WuKongIM服务
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2.0.1-beta-20240715
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2
environment:
- "WK_MODE=release" # release模式
- "WK_CLUSTER_NODEID=1002"
- "WK_EXTERNAL_IP=129.211.213.76" # 当前节点外网ip
- "WK_CLUSTER_APIURL=http://10.206.0.14:5001" # 节点内部通信api url地址这里ip换成自己节点实际node2的内网ip
- "WK_CLUSTER_SERVERADDR=10.206.0.14:11110" # 节点内部通信请求地址
- "WK_EXTERNAL_WSADDR=ws://129.211.213.76:15200" # web端访问的ws长连接地址
- "WK_EXTERNAL_TCPADDR=129.211.213.76:15100" # app端访问的tcp长连接地址
- "WK_TRACE_PROMETHEUSAPIURL=http://10.206.0.13:9090" # 监控地址
- "WK_CLUSTER_INITNODES=1001@10.206.0.13 1002@10.206.0.14 1003@10.206.0.8" # 集群节点列表
- "WK_MODE=release"
- "WK_CLUSTER_NODEID=2"
- "WK_EXTERNAL_IP=129.211.171.99"
- "WK_CLUSTER_APIURL=http://10.206.0.12:5001"
- "WK_CLUSTER_SERVERADDR=10.206.0.12:11110"
- "WK_EXTERNAL_WSADDR=ws://119.45.33.109:15200"
- "WK_EXTERNAL_TCPADDR=119.45.33.109:15100"
- "WK_TRACE_PROMETHEUSAPIURL=http://10.206.0.2:9090"
- "WK_CLUSTER_INITNODES=1@10.206.0.10 2@10.206.0.12 3@10.206.0.5" # 集群节点列表
healthcheck:
test: "wget -q -Y off -O /dev/null http://localhost:5001/health > /dev/null 2>&1"
interval: 10s
@ -140,17 +311,17 @@ services:
version: '3.7'
services:
wukongim: # WuKongIM服务
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2.0.1-beta-20240715
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2
environment:
- "WK_MODE=release" # release模式
- "WK_CLUSTER_NODEID=1003"
- "WK_EXTERNAL_IP=1.13.191.138" # 当前节点外网ip
- "WK_CLUSTER_APIURL=http://10.206.0.8:5001" # 节点内部通信api url地址这里ip换成自己节点实际node2的内网ip
- "WK_CLUSTER_SERVERADDR=10.206.0.8:11110" # 节点内部通信请求地址
- "WK_EXTERNAL_WSADDR=ws://119.45.229.172:15200" # web端访问的ws长连接地址
- "WK_EXTERNAL_TCPADDR=119.45.229.172:15100" # app端访问的tcp长连接地址
- "WK_TRACE_PROMETHEUSAPIURL=http://10.206.0.13:9090" # 监控地址
- "WK_CLUSTER_INITNODES=1001@10.206.0.13 1002@10.206.0.14 1003@10.206.0.8" # 集群节点列表
- "WK_MODE=release"
- "WK_CLUSTER_NODEID=3"
- "WK_EXTERNAL_IP=119.45.175.82"
- "WK_CLUSTER_APIURL=http://10.206.0.5:5001"
- "WK_CLUSTER_SERVERADDR=10.206.0.5:11110"
- "WK_EXTERNAL_WSADDR=ws://119.45.33.109:15200"
- "WK_EXTERNAL_TCPADDR=119.45.33.109:15100"
- "WK_TRACE_PROMETHEUSAPIURL=http://10.206.0.2:9090"
- "WK_CLUSTER_INITNODES=1@10.206.0.10 2@10.206.0.12 3@10.206.0.5"
healthcheck:
test: "wget -q -Y off -O /dev/null http://localhost:5001/health > /dev/null 2>&1"
interval: 10s
@ -169,168 +340,10 @@ services:
```
#### 3. 配置监控(`node1`节点)
在node1节点上的安装目录`~/wukongim`)里创建`prometheus.yml`文件,内容如下:
```yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: wukongim1-trace-metrics
static_configs:
- targets: ['10.206.0.13:5300']
labels:
id: "1001"
- job_name: wukongim2-trace-metrics
static_configs:
- targets: ['10.206.0.14:5300']
labels:
id: "1002"
- job_name: wukongim3-trace-metrics
static_configs:
- targets: ['10.206.0.8:5300']
labels:
id: "1003"
```
#### 4. 配置负载均衡(`node1`节点)
在node1节点上的安装目录`~/wukongim`)里创建`nginx.conf`文件,内容如下:
```nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
# api负载均衡
upstream wukongimapi {
server 10.206.0.13:5001;
server 10.206.0.14:5001;
server 10.206.0.8:5001;
}
# demo负载均衡
upstream wukongimdemo {
server 10.206.0.13:5172;
server 10.206.0.14:5172;
server 10.206.0.8:5172;
}
# manager负载均衡
upstream wukongimanager {
server 10.206.0.13:5300;
server 10.206.0.14:5300;
server 10.206.0.8:5300;
}
# ws负载均衡
upstream wukongimws {
server 10.206.0.13:5200;
server 10.206.0.14:5200;
server 10.206.0.8:5200;
}
# http api转发
server {
listen 5001;
location / {
proxy_pass http://wukongimapi;
proxy_connect_timeout 20s;
proxy_read_timeout 60s;
}
}
# demo
server {
listen 5172;
location / {
proxy_pass http://wukongimdemo;
proxy_connect_timeout 20s;
proxy_read_timeout 60s;
}
location /login {
rewrite ^ /chatdemo?apiurl=http://119.45.229.172:15001;
proxy_pass http://wukongimdemo;
proxy_connect_timeout 20s;
proxy_read_timeout 60s;
}
}
# manager
server {
listen 5300;
location / {
proxy_pass http://wukongimanager;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
}
}
# ws
server {
listen 5200;
location / {
proxy_pass http://wukongimws;
proxy_redirect off;
proxy_http_version 1.1;
# nginx接收upstream server数据超时, 默认120s, 如果连续的120s内没有收到1个字节, 连接关闭
proxy_read_timeout 120s;
# nginx发送数据至upstream server超时, 默认120s, 如果连续的120s内没有发送1个字节, 连接关闭
proxy_send_timeout 120s;
# nginx与upstream server的连接超时时间
proxy_connect_timeout 4s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
# tcp
stream {
# tcp负载均衡
upstream wukongimtcp {
server 10.206.0.13:5100;
server 10.206.0.14:5100;
server 10.206.0.8:5100;
}
server {
listen 5100;
proxy_connect_timeout 4s;
proxy_timeout 120s;
proxy_pass wukongimtcp;
}
}
```
## 启动
在所有节点下执行如下命令
在所有`WuKongIM`节点和`gateway`的安装目录下执行如下命令启动服务
```bash
sudo docker-compose up -d
@ -360,6 +373,6 @@ sudo docker-compose up -d
## 验证
1. 访问`http://119.45.229.172:15172/login`,随便输入用户名和密码,登录后可以聊天,说明部署成功。
1. 访问`http://119.45.33.109:15172/login`,随便输入用户名和密码,登录后可以聊天,说明部署成功。
2. 访问 ` http://119.45.229.172:15300/web` 可以进入后台管理系统 默认系统内置的guest只有读权限如果需要操作权限请看[授权的配置](/server/config/auth) 。
2. 访问 ` http://119.45.33.109:15300/web` 可以进入后台管理系统 默认系统内置的guest只有读权限如果需要操作权限请看[授权的配置](/server/config/auth) 。

View File

@ -46,7 +46,7 @@ cd ~/wukongim
version: '3.7'
services:
wukongim: # WuKongIM服务
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2.0.1-beta-20240715
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2
environment:
- "WK_MODE=release" # release模式
- "WK_CLUSTER_NODEID=1002"

View File

@ -46,7 +46,7 @@ cd ~/wukongim
version: '3.7'
services:
wukongim: # WuKongIM服务
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2.0.1-beta-20240715
image: registry.cn-shanghai.aliyuncs.com/wukongim/wukongim:v2
environment:
- "WK_CLUSTER_NODEID=1001"
- "WK_CLUSTER_SERVERADDR=xx.xx.xx.xx:11110" # 节点内部通信请求地址

View File

@ -1 +1,20 @@
教程制作中
# 多节点扩容
## 说明
适用场景:对数据安全要求高的应用,大型应用。
优点:高可用,容灾性强,支持在线扩容,多副本之间实时自动备份,负载均衡, 无需手动配置, 快速伸缩
> 注意当前悟空IM支持热扩容,暂不支持热缩!,暂不支持热缩!,暂不支持热缩!
#### 1. 扩容
```bash
# 可选参数
# 1.副本数量 replicaCount=1 默认为2
# 2.外部IP externalIP=
helm upgrade wkim wukongim/wukongim -n wukomgim --create-namespace --version 0.1.0 --set replicaCount=3
```

View File

@ -1 +1,46 @@
教程制作中
# 多节点点部署
## 说明
适用场景:对数据安全要求高的应用,大型应用。
优点:高可用,容灾性强,支持在线扩容,多副本之间实时自动备份,负载均衡, 无需手动配置, 快速伸缩
> 注意当前悟空IM支持热扩容,暂不支持热缩!,暂不支持热缩!,暂不支持热缩!
#### 1. 添加Helm仓库
```bash
helm repo add wukongim https://wukongim.github.io/helm/
```
#### 2. 更新Helm仓库
```bash
helm repo update
```
#### 3. 搜索可用的 Chart
```bash
helm search repo wukongim
```
#### 4. 部署
```bash
# 可选参数
# 1.副本数量 replicaCount=1 默认为2
# 2.外部IP externalIP=
helm install wkim wukongim/wukongim -n wukomgim --create-namespace --version 0.1.0 --set replicaCount=3
```
#### 5. 查看安装状态
```bash
helm status wkim
```
#### 6. 卸载
```bash
helm uninstall wkim
```

View File

@ -1 +1,21 @@
教程制作中
# 单节点扩容
## 说明
适用场景:对数据安全要求高的应用,大型应用。
优点:高可用,容灾性强,支持在线扩容,多副本之间实时自动备份,负载均衡, 无需手动配置, 快速伸缩
> 注意当前悟空IM支持热扩容,暂不支持热缩!,暂不支持热缩!,暂不支持热缩!
#### 1. 扩容
```bash
# 可选参数
# 1.副本数量 replicaCount=1 默认为2
# 2.外部IP externalIP=
helm upgrade wkim wukongim/wukongim -n wukomgim --create-namespace --version 0.1.0 --set replicaCount=3
```

View File

@ -1 +1,45 @@
教程制作中
# 单节点部署
## 说明
适用场景:对数据安全要求高的应用,大型应用。
优点:高可用,容灾性强,支持在线扩容,多副本之间实时自动备份,负载均衡, 无需手动配置, 快速伸缩
> 注意当前悟空IM支持热扩容,暂不支持热缩!
#### 1. 添加Helm仓库
```bash
helm repo add wukongim https://wukongim.github.io/helm/
```
#### 2. 更新Helm仓库
```bash
helm repo update
```
#### 3. 搜索可用的 Chart
```bash
helm search repo wukongim
```
#### 4. 部署
```bash
# 可选参数
# 1.副本数量 replicaCount=1 默认为2
# 2.外部IP externalIP=
helm install wkim wukongim/wukongim -n wukomgim --create-namespace --version 0.1.0 --set replicaCount=1
```
#### 5. 查看安装状态
```bash
helm status wkim
```
#### 6. 卸载
```bash
helm uninstall wkim
```

View File

@ -1 +1,14 @@
教程制作中
#### 1. 更新Helm仓库
```bash
helm repo update
```
### 2. 搜索新的版本 Chart
```bash
helm search repo wukongim
```
### 3. 更新
```bash
helm upgrade wkim wukongim/wukongim -n wukomgim --create-namespace --version 版本号
```

View File

@ -22,11 +22,11 @@
::: code-group
``` bash [amd64]
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.1-beta-20240715/wukongim-linux-amd64
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.5-20240925/wukongim-linux-amd64
```
``` bash [arm64]
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.1-beta-20240715/wukongim-linux-arm64
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.5-20240925/wukongim-linux-arm64
```
:::

View File

@ -39,11 +39,11 @@ WuKongIM集群符合 `2n+1` 原则n表示宕机数量比如允许1台机
::: code-group
``` bash [amd64]
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.1-beta-20240715/wukongim-linux-amd64
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.5-20240925/wukongim-linux-amd64
```
``` bash [arm64]
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.1-beta-20240715/wukongim-linux-arm64
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.5-20240925/wukongim-linux-arm64
```
:::
@ -106,8 +106,8 @@ cluster:
mode: "release"
external: # 公网配置
ip: "1.13.191.138" # 节点外网IP客户端能够访问到的IP地址。
tcpAddr: "129.211.213.76:15100" # app访问的长连接地址, 注意这里是负载均衡服务器的ip和端口不是本机的
wsAddr: "ws://129.211.213.76:15200" # web访问的长连接地址注意这里是负载均衡服务器的ip和端口不是本机的
tcpAddr: "119.45.229.172:15100" # app访问的长连接地址, 注意这里是负载均衡服务器的ip和端口不是本机的
wsAddr: "ws://119.45.229.172:15200" # web访问的长连接地址注意这里是负载均衡服务器的ip和端口不是本机的
cluster:
nodeId: 1003 # 节点id
apiUrl: "http://10.206.0.8:5001" # 当前节点内网的api地址
@ -176,7 +176,7 @@ http {
}
# http api转发
server {
listen 5001;
listen 15001;
location / {
proxy_pass http://wukongimapi;
proxy_connect_timeout 20s;
@ -185,7 +185,7 @@ http {
}
# demo
server {
listen 5172;
listen 15172;
location / {
proxy_pass http://wukongimdemo;
proxy_connect_timeout 20s;
@ -200,7 +200,7 @@ http {
}
# manager
server {
listen 5300;
listen 15300;
location / {
proxy_pass http://wukongimanager;
proxy_connect_timeout 60s;
@ -209,7 +209,7 @@ http {
}
# ws
server {
listen 5200;
listen 15200;
location / {
proxy_pass http://wukongimws;
proxy_redirect off;
@ -236,7 +236,7 @@ stream {
server 10.206.0.8:5100;
}
server {
listen 5100;
listen 15100;
proxy_connect_timeout 4s;
proxy_timeout 120s;
proxy_pass wukongimtcp;

View File

@ -20,11 +20,11 @@
::: code-group
``` bash [amd64]
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.1-beta-20240715/wukongim-linux-amd64
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.5-20240925/wukongim-linux-amd64
```
``` bash [arm64]
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.1-beta-20240715/wukongim-linux-arm64
curl -L -o wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v2.0.5-20240925/wukongim-linux-arm64
```
:::

View File

@ -167,9 +167,12 @@ WKIM.getInstance().getMsgManager().registerContentMsg(WKCardContent.class);
对此通过这三步自定义普通消息就已完成。在收到消息时`WKMsg`中的type为3就表示该消息是名片消息其中`baseContentMsgModel`则为自定义的`WKCardContent`,这时可将`baseContentMsgModel`强转为`WKCardContent`并渲染到UI上
完整代码 [名片消息](https://github.com/TangSengDaoDao/TangSengDaoDaoAndroid/blob/master/wkuikit/src/main/java/com/chat/uikit/chat/msgmodel/WKCardContent.java "名片消息")
#### 自定义附件消息
我们在发送消息的时候有时需发送带附件的消息。WuKongIM 也提供自定义附件消息,自定义附件消息和普通消息区别不大。下面我们已地理位置消息举例
我们在发送消息的时候有时需发送带附件的消息。WuKongIM 也提供自定义附件消息,自定义附件消息和普通消息区别不大。下面我们地理位置消息举例
##### 第一步 定义消息

View File

@ -13,12 +13,6 @@
```java
// 获取channel信息 先获取内存 如果没有再从数据库获取
WKIM.getInstance().getChannelManager().getChannel(String channelID, byte channelType)
// 从远程服务器获取channel信息
WKIM.getInstance().getChannelManager().fetchChannelInfo(String channelID, byte channelType)
// 批量导入频道信息 该方法会触发channel刷新事件
WKIM.getInstance().getChannelManager().addOrUpdateChannels(List<WKChannel> list);
```
`Kotlin`
@ -26,12 +20,6 @@ WKIM.getInstance().getChannelManager().addOrUpdateChannels(List<WKChannel> list)
```kotlin
// 获取channel信息 先获取内存 如果没有再从数据库获取
WKIM.getInstance().channelManager.getChannel(channelID,channelType)
// 从远程服务器获取channel信息
WKIM.getInstance().channelManager.fetchChannelInfo(channelID,channelType)
// 批量导入频道信息 该方法会触发channel刷新事件
WKIM.getInstance().channelManager.addOrUpdateChannels(list)
```
#### 强制刷新频道资料
@ -62,6 +50,7 @@ WKIM.getInstance().getChannelManager().addOnRefreshChannelInfo("key", new IRefre
//
}
});
// 移除监听
WKIM.getInstance().getChannelManager().removeRefreshChannelInfo("key");
```

View File

@ -8,7 +8,7 @@
WKIM.getInstance().getChannelMembersManager().getMembers(channelId,channelType);
// 单个频道成员
WKIM.getInstance().getChannelMembersManager().getMembers(channelId,channelType,uid);
WKIM.getInstance().getChannelMembersManager().getMember(channelId,channelType,uid);
```
`kotlin`
```kotlin
@ -16,7 +16,7 @@ WKIM.getInstance().getChannelMembersManager().getMembers(channelId,channelType,u
WKIM.getInstance().channelMembersManager().getMembers(channelId,channelType);
// 单个频道成员
WKIM.getInstance().channelMembersManager().getMembers(channelId,channelType,uid);
WKIM.getInstance().channelMembersManager().getMember(channelId,channelType,uid);
```
#### 搜索成员

View File

@ -21,6 +21,7 @@ WKIM.getInstance().conversationManager.getAll()
`Java`
```java
// 监听刷新最近会话消息
WKIM.getInstance().getConversationManager().addOnRefreshMsgListener("key", new IRefreshConversationMsg() {
@Override
public void onRefreshConversationMsg(WKUIConversationMsg wkUIConversationMsg, boolean isEnd) {
@ -28,17 +29,24 @@ WKIM.getInstance().conversationManager.getAll()
// isEnd 为了防止频繁刷新UI当isEnd为true可刷新UI
}
});
// 退出页面时移除监听
WKIM.getInstance().getConversationManager().removeOnRefreshMsgListener("key");
```
`Kotlin`
```kotlin
// 监听刷新最近会话消息
WKIM.getInstance().conversationManager.addOnRefreshMsgListener(
"key"
) { wkUIConversationMsg, isEnd ->
// wkUIConversationMsg 最近会话消息内容 UI上已有该会话需进行更新反之添加到UI上
// isEnd 为了防止频繁刷新UI当isEnd为true可刷新UI
}
// 退出页面时移除监听
WKIM.getInstance().conversationManager.removeOnRefreshMsgListener("key")
```
### 移除最近会话
@ -63,6 +71,7 @@ WKIM.getInstance().conversationManager.deleteWitchChannel(channelId, channelType
`Java`
```java
// 监听删除最近会话消息
WKIM.getInstance().getConversationManager().addOnDeleteMsgListener("key", new IDeleteConversationMsg() {
@Override
public void onDelete(String channelID, byte channelType) {
@ -70,17 +79,24 @@ WKIM.getInstance().getConversationManager().addOnDeleteMsgListener("key", new ID
// channelType 聊天频道类型
}
});
// 退出页面时移除监听
WKIM.getInstance().getConversationManager().removeOnDeleteMsgListener("key");
```
`Kotlin`
```kotlin
// 监听删除最近会话消息
WKIM.getInstance().conversationManager.addOnDeleteMsgListener(
"key"
) { channelID, channelType ->
// channelID 聊天频道ID
// channelType 聊天频道类型
}
// 退出页面时移除监听
WKIM.getInstance().conversationManager.removeOnDeleteMsgListener("key")
```
### 常用方法

View File

@ -125,10 +125,12 @@ WKIM.getInstance().channelManager.addOnGetChannelInfoListener { channelID, chann
- <font color='#999' size=2>SDK 内置频道类型 可通过 `WKChannelType` 查看</font>
也可以批量保存频道资料信息
`java`
```java
// 批量保存频道资料信息
WKIM.getInstance().getChannelManager().saveOrUpdateChannels(channels);
```
`kotlin`
```kotlin
// 批量保存频道资料信息
WKIM.getInstance().channelManager.saveOrUpdateChannels(channels)

View File

@ -18,82 +18,52 @@ WKIM.getInstance().getMsgManager().sendMessage(textContent,channelID, channelTyp
`Kotlin`
```kotlin
WKIM.getInstance().msgManager.sendMessage(textContent,channelID, channelType)
WKIM.getInstance().msgManager.send(textContent,channel)
```
- <font size=2 color="#999">sdk 内置频道类型可通过`WKChannelType`查看</font>
如给用户`A`发送一条文本消息。构建文本消息正文
`Java`
```java
WKTextContent textContent = new WKTextContent("你好,悟空");
```
`Kotlin`
```kotlin
val textContent = WKTextContent("你好,悟空")
```
将消息发送给用户`A`
`Java`
```java
WKIM.getInstance().getMsgManager().sendMessage(textContent,"A",WKChannelType.PERSONAL);
```
`Kotlin`
```kotlin
WKIM.getInstance().msgManager.sendMessage(textContent,"A",WKChannelType.PERSONAL)
```
#### 文本消息
`Java`
```java
public class WKTextContent extends WKMessageContent {
// 定义文本消息
WKTextContent textContent = new WKTextContent("你好,悟空");
// 发送消息
WKIM.getInstance().msgManager.send(textContent,channel)
```
`Kotlin`
public WKTextContent(String content) {
this.content = content;
this.type = WKMsgContentType.WK_TEXT;
}
}
```kotlin
// 定义文本消息
val textContent = WKTextContent("你好,悟空")
// 发送消息
WKIM.getInstance().msgManager.send(textContent,channel)
```
#### 图片消息
```java
public class WKImageContent extends WKMediaMessageContent {
public int width; // 宽度
public int height; // 高度
public WKImageContent(String localPath) {
this.localPath = localPath;
this.type = WKMsgContentType.WK_IMAGE;
}
}
// 定义图片消息
WKImageContent imageContent = new WKImageContent(localPath);
// 发送消息
WKIM.getInstance().msgManager.send(imageContent,channel);
```
`Kotlin`
```kotlin
// 定义图片消息
val imageContent = WKImageContent(localPath)
// 发送消息
WKIM.getInstance().msgManager.send(imageContent,channel)
```
- <font color="#999" size=2>在构建图片消息正文时无需传递图片的高宽。sdk 会自动获取图片高宽</font>
#### 语音消息
#### 自定义消息
```java
public class WKVoiceContent extends WKMediaMessageContent {
public int timeTrad; // 语音时长
public String waveform; // 音频波浪数据 (可选参数)
参考自定义消息: [自定义消息](/sdk/android/advance.html#自定义消息)
public WKVoiceContent(String localPath, int timeTrad) {
this.type = WKMsgContentType.WK_VOICE;
this.timeTrad = timeTrad;
this.localPath = localPath;
}
}
```
### 消息入库返回(并不是消息发送状态)
在发送消息时sdk 将消息保存在本地数据库后就会触发入库回调。此时消息并未进行发送,可在此监听中将消息展示在 UI 上
@ -125,20 +95,27 @@ WKIM.getInstance().msgManager.addOnSendMsgCallback("key") { wkMsg ->
`Java`
```java
// 添加监听
WKIM.getInstance().getMsgManager().addOnNewMsgListener("key", new INewMsgListener() {
@Override
public void newMsg(List<WKMsg> list) {
// list:接收到的消息
}
});
// 退出页面时移除监听
WKIM.getInstance().getMsgManager().removeNewMsgListener("key");
```
`Kotlin`
```kotlin
// 添加监听
WKIM.getInstance().msgManager.addOnNewMsgListener("key") { list ->
// list:接收到的消息
}
// 退出页面时移除监听
WKIM.getInstance().msgManager.removeNewMsgListener("key")
```
- <font color='#999' size=2>如果在聊天页面内收到新消息时需判断该消息是否属于当前会话,可通过消息对象`WKMsg``channelID``channelType`判断</font>
@ -150,6 +127,7 @@ WKIM.getInstance().msgManager.addOnNewMsgListener("key") { list ->
`Java`
```java
// 添加刷新监听
WKIM.getInstance().getMsgManager().addOnRefreshMsgListener("key", new IRefreshMsg() {
@Override
public void onRefresh(WKMsg wkMsg, boolean isEnd) {
@ -157,15 +135,22 @@ WKIM.getInstance().getMsgManager().addOnRefreshMsgListener("key", new IRefreshMs
// isEnd为了避免频繁刷新UI导致卡顿当isEnd为true时在刷新UI
}
});
// 退出页面时移除刷新监听
WKIM.getInstance().getMsgManager().removeRefreshMsgListener("key");
```
`Kotlin`
```kotlin
// 添加刷新监听
WKIM.getInstance().msgManager.addOnRefreshMsgListener("") { wkMsg, isEnd ->
// wkMsg刷新的消息对象
// isEnd为了避免频繁刷新UI导致卡顿当isEnd为true时在刷新UI
}
// 退出页面时移除刷新监听
WKIM.getInstance().msgManager.removeRefreshMsgListener("key")
```

View File

@ -5,7 +5,7 @@
`java`
```java
// 获取指定会话的提醒项
List<WKReminder> allReminder = WKIM.getInstance().getReminderManager().getReminders(channelId, channelType);
WKIM.getInstance().getReminderManager().getReminders(channelId, channelType);
// 获取指定类型的提醒项
WKIM.getInstance().getReminderManager().getRemindersWithType(String channelID, byte channelType, int type);
@ -13,7 +13,7 @@ WKIM.getInstance().getReminderManager().getRemindersWithType(String channelID, b
`kotlin`
```kotlin
// 获取指定会话的提醒项
val allReminder = WKIM.getInstance().reminderManager.s(channelId, channelType)
WKIM.getInstance().reminderManager.s(channelId, channelType)
// 获取指定类型的提醒项
WKIM.getInstance().reminderManager.getRemindersWithType( channelID, channelType, type);

View File

@ -24,6 +24,33 @@ class GifContent extends WKMessageContent{
```
#### 第二步 编码解码
```dart
@override
WKMessageContent decodeJson(Map<String, dynamic> json) {
url = readString(json, 'url');
width = readInt(json, 'width');
height = readInt(json, 'height');
return this;
}
@override
Map<String, dynamic> encodeJson() {
return {'url': url, 'width': width, 'height': height};
}
```
- <font color='#999' size=2>解码和编码消息时无需将 `type` 字段考虑其中sdk 内部会自动处理</font>
#### 第三步 注册消息
```dart
WKIM.shared.messageManager.registerMsgContent(WkMessageContentType.gif,
(dynamic data) {
return GifContent('').decodeJson(data);
});
```
对此通过这三步自定义普通消息就已完成。在收到消息时`WKMsg`中的type为3就表示该消息是名片消息其中`messageContent`则为自定义的`GifContent`,这时可将`messageContent`强转为`GifContent`并渲染到UI上
完整代码如下:
```dart
class GifContent extends WKMessageContent{
int c=0; // 宽度
int height=0; // 高度
@ -53,21 +80,9 @@ class GifContent extends WKMessageContent{
}
}
```
- <font color='#999' size=2>解码和编码消息时无需将 `type` 字段考虑其中sdk 内部会自动处理</font>
#### 第三步 注册消息
```dart
WKIM.shared.messageManager.registerMsgContent(WkMessageContentType.gif,
(dynamic data) {
return GifContent('').decodeJson(data);
});
```
对此通过这三步自定义普通消息就已完成。在收到消息时`WKMsg`中的type为3就表示该消息是名片消息其中`messageContent`则为自定义的`GifContent`,这时可将`messageContent`强转为`GifContent`并渲染到UI上
### 自定义附件消息
我们在发送消息的时候有时需发送带附件的消息。WuKongIM 也提供自定义附件消息,自定义附件消息和普通消息区别不大。下面我们图片消息举例
我们在发送消息的时候有时需发送带附件的消息。WuKongIM 也提供自定义附件消息,自定义附件消息和普通消息区别不大。下面我们位置消息举例
#### 第一步 定义消息
@ -76,47 +91,39 @@ WKIM.shared.messageManager.registerMsgContent(WkMessageContentType.gif,
```dart
class WKImageContent extends WKMediaMessageContent {
int width; // 图片宽度
int height; // 图片高度
WKImageContent(this.width, this.height) {
contentType = WkMessageContentType.image;
class WKLocationContent extends WKMediaMessageContent {
var longitude = 0.0;
var latitude = 0.0;
var address = "";
WKLocationContent() {
contentType = 10;
}
}
```
#### 第二步 编码解码
```dart
class WKImageContent extends WKMediaMessageContent {
int width; // 图片宽度
int height; // 图片高度
WKImageContent(this.width, this.height) {
contentType = WkMessageContentType.image;
}
@override
Map<String, dynamic> encodeJson() {
return {'width': width, 'height': height, 'url': url};
return {'longitude': longitude, 'latitude': latitude, 'url': url,'address':address, 'localPath': localPath};
}
@override
WKMessageContent decodeJson(Map<String, dynamic> json) {
width = readInt(json, 'width');
height = readInt(json, 'height');
address = readString(json, 'address');
longitude = readDouble(json, 'longitude');
url = readString(json, 'url');
latitude = readDouble(json, 'latitude');
localPath = readString(json, 'localPath');
return this;
}
}
```
#### 第三步 注册消息
```dart
WKIM.shared.messageManager.registerMsgContent(WkMessageContentType.image,
WKIM.shared.messageManager.registerMsgContent(10,
(dynamic data) {
return WKImageContent(
0,
0,
return WKLocationContent(
).decodeJson(data);
});
```
@ -186,7 +193,7 @@ WKIM.shared.messageManager.sendMessage( text, WKChannel(channelID, channelType))
WKIM.shared.messageManager.saveMessageReactions(List<WKSyncMsgReaction> list);
```
- <font color='#999' size=2>同一个用户对同一条消息只能做出一条回应。重复进行消息不同 emoji 的回应会做为修改回应,重复进行相同 emoji 的回应则做为删除回应</font> sdk 更新消息回应后会触发消息刷新的事件。app 需监听事件并对 UI 进行刷新
- <font color='#999' size=2>同一个用户对同一条消息只能做出一条回应。重复进行消息不同 emoji 的回应会做为修改回应,重复进行相同 emoji 的回应则做为删除回应</font> sdk 更新消息回应后会触发消息刷新的事件。app 需监听消息刷新事件并对 UI 进行刷新
### 消息编辑

View File

@ -12,6 +12,7 @@ WKIM.shared.conversationManager.getAll();
只有第一次打开应用时,需要同步最近会话列表, 后续最近会话列表的变化,通过监听来获取
```dart
// 监听刷新消息
WKIM.getInstance().getConversationManager().addOnRefreshMsgListener("key", new IRefreshConversationMsg() {
@Override
public void onRefreshConversationMsg(WKUIConversationMsg wkUIConversationMsg, boolean isEnd) {
@ -19,6 +20,8 @@ WKIM.shared.conversationManager.getAll();
// isEnd 为了防止频繁刷新UI当isEnd为true可刷新UI
}
});
// 移除监听
WKIM.getInstance().getConversationManager().removeOnRefreshMsg("key");
```
### 删除最近会话

View File

@ -7,49 +7,28 @@
WKIM.shared.messageManager.sendMessage(WKTextContent('我是文本消息'), WKChannel('uid_1', WKChannelType.personal));
```
如给用户`A`发送一条文本消息。构建文本消息正文
```dart
WKTextContent textContent = new WKTextContent("你好,悟空");
```
将消息发送给用户`A`
```dart
WKIM.shared.messageManager.sendMessage(textContent,WKChannel('A', WKChannelType.personal));
```
#### 文本消息
```dart
class WKTextContent extends WKMessageContent {
WKTextContent(content) {
contentType = WkMessageContentType.text;
this.content = content;
}
}
// 定义文本消息
WKTextContent text = WKTextContent("你好,悟空");
// 发送文本消息
WKIM.shared.messageManager.sendMessage(text,channel);
```
#### 图片消息
```dart
class WKImageContent extends WKMediaMessageContent {
int width;
int height;
WKImageContent(this.width, this.height) {
contentType = WkMessageContentType.image;
}
}
// 定义图片消息
WKImageContent image = WKImageContent(100, 100);
image.localPath = "xxx"; // 图片本地路径
image.url = "http://xxx.com/xxx.jpg"
// 发送图片消息
WKIM.shared.messageManager.sendMessage(image,channel);
```
#### 语音消息
```dart
class WKVoiceContent extends WKMediaMessageContent {
int timeTrad; // 语音秒长
String? waveform; // 语音波纹 base64编码
WKVoiceContent(this.timeTrad) {
contentType = WkMessageContentType.voice;
}
}
```
#### 自定义消息
参考自定义消息: [自定义消息](/sdk/flutter/advance.html#自定义消息)
### 消息入库返回(并不是消息发送状态)
在发送消息时sdk 将消息保存在本地数据库后就会触发入库回调。此时消息并未进行发送,可在此监听中将消息展示在 UI 上
@ -65,9 +44,13 @@ WKIM.shared.messageManager.addOnMsgInsertedListener((wkMsg) {
监听新消息事件
```dart
// 监听新消息事件
WKIM.shared.messageManager.addOnNewMsgListener('chat', (msgs) {
// 展示在UI上
});
// 移除新消息监听
WKIM.shared.messageManager.removeNewMsgListener('chat');
```
- <font color='#999' size=2>如果在聊天页面内收到新消息时需判断该消息是否属于当前会话,可通过消息对象`WKMsg``channelID``channelType`判断</font>
@ -78,9 +61,13 @@ WKIM.shared.messageManager.addOnNewMsgListener('chat', (msgs) {
监听刷新消息事件
```dart
// 监听刷新消息事件
WKIM.shared.messageManager.addOnRefreshMsgListener('chat', (wkMsg) {
// todo 刷新消息
});
// 移除刷新消息监听
WKIM.shared.messageManager.removeOnRefreshMsgListener('chat');
```
### 查看某个频道的聊天信息

View File

@ -32,7 +32,7 @@ export class CardMessageContent extends WKMessageContent {
"avatar": "xxx"
}
```
重写`WKMessageContent``encodeJson`方法开始编码
重写`WKMessageContent``encodeJson`,`decodeJson`方法开始编码解码
```typescripts
@ -45,9 +45,6 @@ export class CardMessageContent extends WKMessageContent {
return json
}
```
重写`WKMessageContent``decodeJson`方法开始解码
```typescripts
// 解码内容
decodeJson(jsonStr: string): WKMessageContent {
@ -59,7 +56,9 @@ export class CardMessageContent extends WKMessageContent {
}
return this
}
```
- <font color='#999' size=2>解码和编码消息时无需将 `type` 字段考虑其中sdk 内部会自动处理</font>
##### 第三步 注册消息
```typescripts
@ -139,7 +138,7 @@ export class LocationMessageContent extends WKMediaMessageContent {
"address": "xxx"
}
```
重写`WKMessageContent`的encodeJson方法开始编码
重写`WKMessageContent``encodeJson`,`decodeJson`方法开始编码解码
```typescripts
// 编码
encodeJson(): Record<string, Object> {
@ -149,9 +148,8 @@ json['longitude'] = this.longitude
json['latitude'] = this.latitude
return json
}
```
重写`WKMessageContent``decodeJson`方法开始解码
```typescripts
// 解码
decodeJson(jsonStr: string): WKMessageContent {
let json = CommonUtil.jsonToRecord(jsonStr)
@ -164,6 +162,7 @@ if (json !== undefined) {
return this
}
```
##### 第三步 注册消息
```typescripts
// 注册自定义消息
@ -174,7 +173,7 @@ WKIM.shared.messageManager().registerMsgContent(17, (jsonStr: string) => {
### 消息扩展
随着业务的发展应用在聊天中的功能也日益增多,为了满足绝大部分的需求 WuKongIM 中增加了消息扩展功能。消息扩展分`本地扩展``远程扩展`,本地扩展只针对 app 本地使用卸载 app 后将丢失,远程扩展是服务器保存卸载重装后数据将恢复
#### 本地扩展
本地扩展就是消息对象`WKMsg`中的l`localExtraMap`字段
本地扩展就是消息对象`WKMsg`中的`localExtraMap`字段
```typescripts
/**
* 修改消息本地扩展

View File

@ -12,9 +12,16 @@ let msgs = WKIM.shared.conversationManager().all()
只有第一次打开应用时,需要同步最近会话列表, 后续最近会话列表的变化,通过监听来获取
```typescript
WKIM.shared.conversationManager().addRefreshListener((list:WKConversation[]) => {
// 定义监听器
let listener =(list:WKConversation[]) => {
// 当UI列表没有list中的数据时需执行添加操作
})
}
// 监听新消息
WKIM.shared.conversationManager().addRefreshListener(listener)
// 移出监听
WKIM.shared.conversationManager().removeRefreshListener(listener)
```
### 删除最近会话
@ -24,9 +31,16 @@ WKIM.shared.conversationManager().delete(channelId, channelType)
```
调用删除最近会话后会触发删除最近会话事件UI可以监听删除最近会话事件并将UI上的会话进行删除
```typescript
WKIM.shared.conversationManager().addDeletedListener((channelId: string, channelType: number) => {
// 定义监听器
let listener = (channelId: string, channelType: number) => {
// 删除UI上的会话
})
}
// 设置监听
WKIM.shared.conversationManager().addDeletedListener(listener)
// 移出监听
WKIM.shared.conversationManager().removeDeletedListener(listener)
```
### 数据结构说明

View File

@ -34,13 +34,9 @@ WKIM.shared.messageManager().send(imageModel, new WKChannel('A', WKChannelType.p
```
#### 自定义消息
```typescript
// 自定义消息
let model: xxx = new xxx()
// 发送给群组g_100
WKIM.shared.messageManager().send(model, new WKChannel('g_100', WKChannelType.group));
```
参考自定义消息: [自定义消息](/sdk/harmonyos/advance.html#自定义消息)
### 消息入库返回(并不是消息发送状态)
在发送消息时sdk 将消息保存在本地数据库后就会触发入库回调。此时消息并未进行发送,可在此监听中将消息展示在 UI 上

View File

@ -229,13 +229,13 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
@return 正文类型
*/
(NSInteger) contentType;
- (NSNumber*) contentType;
// 上层无需实现encode 实现此方法即可
(NSDictionary*) encodeWithJSON;
- (NSDictionary*) encodeWithJSON;
// 上层无序实现decode 实现此方法即可
(void) decodeWithJSON:(NSDictionary*)contentDic;
- (void) decodeWithJSON:(NSDictionary*)contentDic;
// 消息中的@提醒信息
@property (nonatomic, strong) WKMentionedInfo *mentionedInfo;
@ -880,12 +880,12 @@ cmd 消息由服务端下发客户端解析。
@implementation WKGIFContent
// 定义消息正文类型
(NSInteger) contentType {
return 3;
- (NSNumber*) contentType {
return @(3);
}
// 发送消息时对消息内容编码
(NSDictionary *)encodeWithJSON {
- (NSDictionary *)encodeWithJSON {
NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
[dataDict setObject:self.url?:@"" forKey:@"url"];
[dataDict setObject:@(self.width) forKey:@"width"];
@ -894,14 +894,14 @@ cmd 消息由服务端下发客户端解析。
}
// 收到消息时对消息内容解码
(void)decodeWithJSON:(NSDictionary *)contentDic {
- (void)decodeWithJSON:(NSDictionary *)contentDic {
self.url = contentDic[@"url"];
self.width = contentDic[@"width"]?[contentDic[@"width"] integerValue]:100;
self.height = contentDic[@"height"]?[contentDic[@"height"] integerValue]:100;
}
// 最近会话显示的内容
(NSString *)conversationDigest {
- (NSString *)conversationDigest {
return @"[gif表情]"
}
@ -945,18 +945,18 @@ cmd 消息由服务端下发客户端解析。
@implementation WKImageContent
// 定义消息正文类型
(NSInteger) contentType {
return 4;
- (NSNumber*) contentType {
return @(4);
}
// 将图片数据写入到本地路径,这样后面的上传任务会将此路径的附件上传到服务器
(void) writeDataToLocalPath {
- (void) writeDataToLocalPath {
[super writeDataToLocalPath];
[self.imageData writeToFile:self.localPath atomically:YES];
}
// 附件消息当附件上传成功后 会获取到上传后的self.remoteUrl下载地址我们只需要将此下载地址编码到json里附件的上传任务进度管理请查看 [WKSDK shared].mediaManager
(NSDictionary *)encodeWithJSON {
- (NSDictionary *)encodeWithJSON {
NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
[dataDict setObject:self.remoteUrl?:@"" forKey:@"url"];
[dataDict setObject:@(self.width) forKey:@"width"];
@ -964,7 +964,7 @@ cmd 消息由服务端下发客户端解析。
return dataDict;
}
// 当收到消息需要解码这时候我们只需要将下载地址url 赋值给self.remoteUrl后 下载任务会通过self.remoteUrl的下载地址进行下载附件 附件的下载任务进度管理请查看 [WKSDK shared].mediaManager
(void)decodeWithJSON:(NSDictionary *)contentDic {
- (void)decodeWithJSON:(NSDictionary *)contentDic {
self.remoteUrl = contentDic[@"url"];
self.width = contentDic[@"width"]?[contentDic[@"width"] floatValue]:0;
self.height = contentDic[@"height"]?[contentDic[@"height"] floatValue]:0;

View File

@ -0,0 +1,134 @@
# 自定义消息
### 自定义普通消息
我们以自定义一个 gif 消息为例。
#### 第一步 继承WKMessageContent 和定义 gif 消息的正文结构
```objc
@interface WKGIFContent : WKMessageContent
//GIF的地址
@property(nonatomic,copy) NSString *url;
// 宽度
@property(nonatomic,assign) NSInteger width;
// 高度
@property(nonatomic,assign) NSInteger height;
@end
```
#### 第二步 编码解码
```objc
// 最终传递的消息内容为 {"type":3,"url":"xxxx","width":xxx,"height":xxx}
@implementation WKGIFContent
// 定义消息正文类型
- (NSNumber*) contentType {
return @(3);
}
// 发送消息时对消息内容编码
- (NSDictionary *)encodeWithJSON {
NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
[dataDict setObject:self.url?:@"" forKey:@"url"];
[dataDict setObject:@(self.width) forKey:@"width"];
[dataDict setObject:@(self.height) forKey:@"height"];
return dataDict;
}
// 收到消息时对消息内容解码
- (void)decodeWithJSON:(NSDictionary *)contentDic {
self.url = contentDic[@"url"];
self.width = contentDic[@"width"]?[contentDic[@"width"] integerValue]:100;
self.height = contentDic[@"height"]?[contentDic[@"height"] integerValue]:100;
}
// 最近会话显示的内容
- (NSString *)conversationDigest {
return @"[gif表情]"
}
@end
```
#### 第三步 注册
```objc
[[WKSDK shared] registerMessageContent:WKGIFContent.class];
```
### 自定义附件消息
自定义附件消息的流程与普通消息差异不大,我们以图片消息为例
#### 第一步 继承WKMediaMessageContent
注意这里时继承 WKMediaMessageContent 不是 WKMessageContent
最终传递的消息内容为 ```{"type":4,"url":"xxxx","width":xxx,"height":xxx}```
```objc
@interface WKImageContent : WKMediaMessageContent
@property(nonatomic,assign) CGFloat width; // 图片宽度
@property(nonatomic,assign) CGFloat height; // 图片高度
@property(nonatomic,strong) NSData imageData; // 图片数据
@end
```
#### 第二步 编码解码和将需要上传的数据写入本地路径
```objc
@implementation WKImageContent
// 定义消息正文类型
- (NSNumber*) contentType {
return @(4);
}
// 将图片数据写入到本地路径,这样后面的上传任务会将此路径的附件上传到服务器
- (void) writeDataToLocalPath {
[super writeDataToLocalPath];
[self.imageData writeToFile:self.localPath atomically:YES];
}
// 附件消息当附件上传成功后 会获取到上传后的self.remoteUrl下载地址我们只需要将此下载地址编码到json里附件的上传任务进度管理请查看 [WKSDK shared].mediaManager
- (NSDictionary *)encodeWithJSON {
NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
[dataDict setObject:self.remoteUrl?:@"" forKey:@"url"];
[dataDict setObject:@(self.width) forKey:@"width"];
[dataDict setObject:@(self.height) forKey:@"height"];
return dataDict;
}
// 当收到消息需要解码这时候我们只需要将下载地址url 赋值给self.remoteUrl后 下载任务会通过self.remoteUrl的下载地址进行下载附件 附件的下载任务进度管理请查看 [WKSDK shared].mediaManager
- (void)decodeWithJSON:(NSDictionary *)contentDic {
self.remoteUrl = contentDic[@"url"];
self.width = contentDic[@"width"]?[contentDic[@"width"] floatValue]:0;
self.height = contentDic[@"height"]?[contentDic[@"height"] floatValue]:0;
}
@end
```
#### 第三步 注册
```objc
[[WKSDK shared] registerMessageContent:WKImageContent.class];
```

View File

@ -0,0 +1,46 @@
# 消息编辑
当我们发现发送的消息内容有误后,我们无需撤回后再编辑再发送,**WuKongIM**提供直接在发出去的消息上进行编辑的功能
<!-- <img src="./edit_before.png" width="250px">&nbsp;&nbsp; -->
<!-- <img src="./edit_after.png" width="250px"> -->
## 数据操作
```objc
// message 未原始消息对象
// newContent 为修改后的正文
// 返回编辑后的消息对象
WKMessage *messageEditAfter = [[WKSDK shared].chatManager editMessage:(WKMessage*)message newContent:(WKMessageContent*)newContent];
```
## 数据监听
如果别人编辑了消息或自己编辑了消息都会触发 WKChatManagerDelegate 的消息更新事件, 在此事件里我们通过 `message.remoteExtra.contentEdit` 对象可以获取到编辑后的正文
```objc
// ---------- WKChatManagerDelegate ----------
- (void) onMessageUpdate:(WKMessage*) message left:(NSInteger)left {
WKMessageContent *orgContent = message.content; // 原始正文
WKMessageContent *editContent = message.remoteExtra.contentEdit; // 编辑后的正文
}
```
## 数据源
```objc
// 提交编辑内容。
[[[WKSDK shared] chatManager] setMessageEditProvider:^(WKMessageExtra * _Nonnull extra, WKMessageEditCallback _Nonnull callback) {
NSData *editContentData = extra.contentEditData; // 编辑后的正文数据
// 请求自己的app服务端修改消息
....
// 修改结果回调
callback(result);
}];
```

View File

@ -0,0 +1,51 @@
# 消息点赞
## 数据操作
```objc
/**
添加或取消回应,如果同一个用户存在reactionName的回应则取消回应
@param reactionName 回应的名称一般是emoji或本地emoji图片的名称
@param messageID 回应消息的ID
@param complete 结果回调
*/
[[WKSDK shared].reactionManager addOrCancelReaction:(NSString*)reactionName messageID:(uint64_t)messageID complete:(void(^_Nullable)(NSError * _Nullable error))complete];
```
当点击某个会话的时候需要增量同步一下当前会话的回应
```objc
[[WKSDK shared].reactionManager sync:channel];
```
## 数据监听
如果有别人回应(点赞),我们可以通过 WKReactionManagerDelegate 监听到
```objc
// ---------- WKReactionManagerDelegate ----------
(void) reactionManagerChange:(WKReactionManager*)reactionManager reactions:(NSArray<WKReaction*>*)reactions channel:(WKChannel*)channel {
}
```
## 数据源
```objc
// channel 频道
// messageID 点赞的消息对应的消息id
// reactionName 点赞的符号名称
// callback 请求服务器后将结果回调给sdk
[[WKSDK shared].reactionManager setAddOrCancelReactionProvider:^(WKChannel * _Nonnull channel, uint64_t messageID, NSString *reactionName,WKAddOrCancelReactionsCallback _Nonnull callback) {
}];
```

View File

@ -0,0 +1,57 @@
# 消息已读
已读未读又称为回执,由`[WKSDK shared].receiptManager` 回执管理者管理
## 数据操作
发送消息的时候,在设置里开启消息回执`setting.receiptEnabled = true`
```objc
WKSetting *setting = [WKSetting new];
setting.receiptEnabled = true // 开启端消息回执
[[WKSDK shared].chatManager sendMessage:(WKMessageContent*)content channel:(WKChannel*)channel setting:setting]
```
当消息接受方UI展示消息的时候执行以下代码将消息标记为已读
```objc
[[WKSDK shared].receiptManager addReceiptMessages:(WKChannel*)channel messages:(NSArray<WKMessage*>*)messages];
```
## 数据监听
当消息已读的时候,会触发消息更新的方法
```objc
// ---------- WKChatManagerDelegate ----------
/**
消息更新
@param message <#message description#>
@param left 消息剩余数量 可当left为0时再刷新UI
*/
(void) onMessageUpdate:(WKMessage*) message left:(NSInteger)left {
if(message.remoteExtra.readed) {
NSLog(@"消息已读");
}
}
```
## 数据源
```objc
// 设置上传消息已读数据源。
[[[WKSDK shared] receiptManager] setMessageReadedProvider:^(WKChannel *channel,NSArray<WKMessage *> * _Nonnull messages, WKMessageReadedCallback _Nonnull callback) {
// 请求自己的app服务端
....
// 结果回调
callback(result);
}];
```

View File

@ -0,0 +1,54 @@
# 会话提醒管理
会话提醒目前只支持服务端下发指令,客户端同步提醒然后显示提醒,会话提醒由 `[WKSDK shared].reminderManager` 管理
可以实现类似 @我,入群申请等等会话提醒
## 数据操作
```objc
// 同步提醒,离线后上线首次调用,或服务器主动下发指令去同步
[[WKSDK shared].reminderManager sync];
// 提醒项已处理完成ids为提醒项的唯一ID集合
[[WKSDK shared].reminderManager done:(NSArray<NSNumber*>*)ids];
```
## 数据监听
```objc
// ---------- WKReminderManagerDelegate ----------
// 某个频道的reminders发生变化
(void) reminderManager:(WKReminderManager*)manager didChange:(WKChannel*)channel reminders:(NSArray<WKReminder*>*) reminders {
}
```
## 数据源
同步提醒数据源,需要实现请求服务器获取提醒的逻辑
`触发时机:调用[[WKSDK shared].reminderManager sync]时`
```objc
[[WKSDK shared].reminderManager setReminderProvider:^(WKReminderCallback _Nonnull callback) {
}];
```
完成提醒数据源,需要实现请求服务器完成提醒的逻辑
`触发时机:调用[[WKSDK shared].reminderManager done:(NSArray<NSNumber*>*)ids]时`
```objc
[[WKSDK shared].reminderManager setReminderDoneProvider:^(NSArray<NSNumber *> * _Nonnull ids, WKReminderDoneCallback _Nonnull callback) {
}];
```

119
src/sdk/iossdk/channel.md Normal file
View File

@ -0,0 +1,119 @@
# 频道管理
`个人频道,群组频道统称为频道,个人信息,群组信息统称为频道信息`
负责频道信息数据的增删改查,通过频道管理可以实现用户/群昵称,用户/群头像,用户/群置顶,用户/群免打扰等功能
文档只介绍核心方法,更多内容查看代码的`[WKSDK shared].channelManager`接口
## 获取频道
### 数据操作
获取客户端本地的频道信息,如果本地没有则调用`fetchChannelInfo`去触发数据源去服务器请求。
当调用`fetchChannelInfo`获取到频道信息数据后会触发数据监听在监听里再重新刷新ui这时`[[WKSDK shared].channelManager getChannelInfo:channel]`就能获取频道信息数据了
```objc
WKChannelInfo *channelInfo = [[WKSDK shared].channelManager getChannelInfo:channel];
if(!channelInfo) {
[[WKSDK shared].channelManager fetchChannelInfo:channel];
}
```
### 数据监听
`触发时机channelInfo数据发生变化时`
添加`WKChannelManagerDelegate `委托
```objc
[[WKSDK shared].channelManager addDelegate:self]
```
`WKChannelManagerDelegate` 说明
```objc
// 频道更新
// @param channelInfo 新频道信息
// @param oldChannelInfo 旧频道信息
-(void) channelInfoUpdate:(WKChannelInfo*)channelInfo oldChannelInfo:(WKChannelInfo* __nullable)oldChannelInfo {
}
```
### 数据源
`触发时机:调用[[WKSDK shared].channelManager fetchChannelInfo]时触发`
频道信息数据源,需要实现请求服务器获取频道信息的逻辑
```objc
// channel 频道
// callback 当请求服务器获取到数据后,应调用此回调 (注意: 不管请求失败与否都需要调用callback
[[WKSDK shared] setChannelInfoUpdate:^WKTaskOperator * (WKChannel * _Nonnull channel, WKChannelInfoCallback _Nonnull callback) {
}];
```
示例:
![频道数据源示例](./channelInfoDataSource.png)
## 修改频道
### 数据操作
修改频道资料(同时触发数据监听)
```objc
// 更新频道信息
[[WKSDK shared].channelManager updateChannelInfo:(WKChannelInfo*) channelInfo]
// 添加或更新频道信息
[[WKSDK shared].channelManager addOrUpdateChannelInfo:(WKChannelInfo*) channelInfo]
```
## 类核心属性
```objc
@interface WKChannelInfo : NSObject<NSCopying>
// 频道
@property(nonatomic,strong) WKChannel *channel;
/**
频道名字
*/
@property(nonatomic,copy) NSString *name;
/**
频道logo
*/
@property(nonatomic,copy) NSString *logo;
/**
是否置顶
*/
@property(nonatomic,assign) BOOL stick;
/**
是否免打扰
*/
@property(nonatomic,assign) BOOL mute;
/// 是否全员禁言
@property(nonatomic,assign) BOOL forbidden;
/**
是否已关注 0.未关注(陌生人) 1.已关注(好友)
*/
@property(nonatomic,assign) WKChannelInfoFollow follow;
/**
扩展字段,自定义频道业务属性可以添加到扩展字端内
*/
@property(nonatomic,strong) NSMutableDictionary<WKChannelExtraKey,id> *extra;
...
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 KiB

356
src/sdk/iossdk/chat.md Normal file
View File

@ -0,0 +1,356 @@
# 聊天管理
负责消息数据的管理,比如:消息发送,消息接受,消息更新等等
文档只介绍核心方法,更多内容查看代码的`[WKSDK shared].chatManager`接口
## 在线消息收发
### 数据操作
发送消息
```objc
/**
发送消息 (发送并保存消息)
@param content 消息正文
@param channel 投递的频道(个人频道,群频道,客服频道等等)
*/
[[WKSDK shared].chatManager sendMessage:(WKMessageContent*)content channel:(WKChannel*)channel];
```
举例说明
```objc
// 给用户A发送消息hello
WKChannel *channel = [[WKChannel alloc] initWith:@"A" channelType:WK_PERSON];
// 发送给群组 g1
// WKChannel *channel = [[WKChannel alloc] initWith:@"g1" channelType:WK_GROUP];
// 构建一个文本消息对象
WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
// 发送此文本消息给指定频道
[[WKSDK shared].chatManager sendMessage:content channel:channel];
```
### 数据监听
WKChatManagerDelegate委托
```objc
[WKSDK.shared.chatManager addDelegate:self]; // WKChatManagerDelegate
```
WKChatManagerDelegate 说明
```objc
// ------ WKChatManagerDelegate ------
/**
收到消息通知
@param message 收到的消息
@param left 消息剩余数量 可当left为0时再刷新UI,避免频繁刷新UI导致卡顿
*/
- (void)onRecvMessages:(WKMessage*)message left:(NSInteger)left;
/**
消息更新通知
@param message 变化的消息
*/
-(void) onMessageUpdate:(WKMessage*) message;
...
```
## 常用消息
SDK内置了一些常用的消息类型比如文本消息图片消息语音消息
### 文本消息
```objc
@interface WKTextContent : WKMessageContent
- (instancetype)initWithContent:(NSString*)content;
@property(nonatomic,copy) NSString *content; // 消息内容
@property(nonatomic,copy,nullable) NSString *format; // 内容格式 默认为普通文本 html,markdown
@end
```
### 图片消息
```objc
@interface WKImageContent : WKMediaMessageContent
@property(nonatomic,assign) CGFloat width; // 图片宽度
@property(nonatomic,assign) CGFloat height; // 图片高度
/*!
初始化图片消息
@param image 原始图片
@return 图片消息对象
*/
- (instancetype)initWithImage:(UIImage *)image;
/// 通过data初始化
/// @param data 图片数据
/// @param width 图片宽度
/// @param height 图片高度
- (instancetype)initWithData:(NSData *)data width:(CGFloat)width height:(CGFloat)height;
/// 初始化
/// @param data 原图data
/// @param width 原图宽度
/// @param height 原图高度
/// @param thumbData 缩略图data 如果传了缩略图的data数据sdk将不再生成缩略图数据
- (instancetype)initWithData:(NSData *)data width:(CGFloat)width height:(CGFloat)height thumbData:( nullable NSData*)thumbData;
/*!
是否发送原图
@discussion 在发送图片的时候是否发送原图默认值为NO。
*/
@property (nonatomic, getter=isFull) BOOL full;
@end
```
### 语音消息
```objc
@interface WKVoiceContent : WKMediaMessageContent
/**
初始化
@param voiceData 音频数据
@param second 音频秒长
@param waveform 音频波浪数据 (可选参数)
@return <#return value description#>
*/
(instancetype)initWithData:(NSData *)voiceData second:(int)second waveform:(NSData*)waveform;
// 音频数据
@property(nonatomic,strong) NSData *voiceData;
// 音频长度(单位秒)
@property(nonatomic,assign) NSInteger second;
// 音频波浪数据 (可选参数)
@property(nonatomic,strong) NSData *waveform;
@end
```
### 自定义消息
查看[自定义消息](./advance/custommessage.md)
## 消息扩展
一些消息可能需要携带一些额外的信息,比如消息已读状态,消息是否被编辑过等等,这些信息可以通过消息的扩展属性来实现
### 数据操作
#### 更新扩展
WKMessage类里有个 `remoteExtra` 属性,当修改这个属性后,需要调用此方法来更新远程扩展
```objc
[[WKSDK shared].chatManager updateMessageRemoteExtra:(WKMessage*)message]
```
#### 同步扩展
增量同步指定频道的所有消息扩展数据 (此方法一般点开聊天页面的时候调用一次)
```objc
// channel 需要同步的频道
[[WKSDK shared].chatManager syncMessageExtra:(WKChannel*)channel complete:(void(^_Nullable)(NSError * _Nullable error))complete]
```
### 数据监听
当前消息扩展数据变化时,会触发`WKChatManagerDelegate`委托
### 数据源
#### 更新扩展
`触发时机:调用[[WKSDK shared].chatManager updateMessageRemoteExtra]的时候触发`
```objc
// newExtra 新的扩展数据
// oldExtra 旧的扩展数据
[[[WKSDK shared] chatManager] setUpdateMessageExtraProvider:^(WKMessageExtra *newExtra,WKMessageExtra *oldExtra,WKUpdateMessageExtraCallback callback) {
}];
```
#### 同步扩展
`触发时机:调用[[WKSDK shared].chatManager syncMessageExtra]的时候触发`
增量同步频道的扩展数据
```objc
// channel 同步扩展消息的频道
// extraVersion 当前客户端存在的数据版本
// limit 每次同步数据量
// callback 当请求服务器获取到消息后,应调用此回调 (注意: 不管请求失败与否都需要调用callback
[[[WKSDK shared] chatManager] setSyncMessageExtraProvider:^(WKChannel * _Nonnull channel, long long extraVersion,NSInteger limit, WKSyncMessageExtraCallback _Nonnull callback) {
}];
```
## 历史消息
### 数据操作
```objc
/**
查询某个频道最新的消息 (一般是第一次进入会话页面查询首屏消息时调用此方法)
@param channel 频道
@param WKit 消息数量限制
@param complete 查询回调
*/
[[WKSDK shared].chatManager pullLastMessages:(WKChannel*)channel limit:(int)limit complete:(void(^)(NSArray<WKMessage*> *messages,NSError *error))complete];
/**
下拉加载消息
@param channel 频道
@param startOrderSeq 起始的orderSeq 比如需要查询 100以上的10条消息 那么startOrderSeq就是100 查询出来的数据为 90 91 92 93 94 95 96 97 98 99
@param WKit 消息数量限制
@param complete 查询回调
*/
[[WKSDK shared].chatManager pullDown:(WKChannel*)channel startOrderSeq:(uint32_t)startOrderSeq limit:(int)limit complete:(void(^)(NSArray<WKMessage*> *messages,NSError *error))complete];
/**
上拉加载消息
@param startOrderSeq 起始的orderSeq 比如需要查询 100以下的10条消息 那么startOrderSeq就是100 查询出来的数据为 101 102 103 104 105 106 107 108 109 110
@param WKit 消息数量限制
@param complete 查询回调
*/
[[WKSDK shared].chatManager pullUp:(WKChannel*)channel startOrderSeq:(uint32_t)startOrderSeq limit:(int)limit complete:(void(^)(NSArray<WKMessage*> *messages,NSError *error))complete];
/**
查询指定orderSeq周围的消息 上5条下5条 ,比如 orderSeq 为 20 则查询 16 17 18 19 20 21 22 23 24 25 主要使用在定位消息
@param channel 频道
@param orderSeq 以此OrderSeq查询周围的消息
*/
[[WKSDK shared].chatManager pullAround:(WKChannel*)channel orderSeq:(uint32_t)orderSeq limit:(int)limit complete:(void(^)(NSArray<WKMessage*> *messages,NSError *error))complete];
```
### 数据源
`触发时机获取历史消息并且本地没有此消息时SDK会调用此方法来补全本地消息`
同步频道消息当操作请求历史消息的时候SDK会判断本地是否有消息如果没有或者缺失SDK会调用此方法来请求服务器的消息
```objc
// channel 同步消息的频道
// startMessageSeq 开始消息序号
// endMessageSeq 结束消息序号
// limit 消息每次同步数量
// pullMode 拉取消息模式 0:向下拉取 1:向上拉取
// callback 当请求服务器获取到消息后,应调用此回调 (注意: 不管请求失败与否都需要调用callback
[WKSDK.shared.chatManager setSyncChannelMessageProvider:^(WKChannel * _Nonnull channel, uint32_t startMessageSeq, uint32_t endMessageSeq, NSInteger limit, WKPullMode pullMode, WKSyncChannelMessageCallback _Nonnull callback) {
}]
```
例子:
![同步消息数据源设置例子](./channelMsgSync.png)
## 类属性说明
消息类核心属性
```objc
@interface WKMessage : NSObject
@property(nonatomic,strong) WKMessageHeader *header; // 消息头
@property(nonatomic,strong) WKSetting *setting; // 消息设置
@property(nonatomic,strong) WKChannel *channel; // 聊天频道
@property(nonatomic,copy) NSString *fromUid; // 发送者uid
@property(nonatomic,strong) WKMessageContent *content; // 消息正文
@property(nonatomic,assign) NSInteger timestamp; // 消息时间(服务器时间,单位秒)
@property(nonatomic,strong) NSMutableDictionary *extra; // 消息本地扩展数据
@property(nonatomic,strong) WKMessageExtra *remoteExtra; // 消息远程扩展
...
```
消息正文核心属性
```objc
@interface WKMessageContent : NSObject<NSCopying>
/**
你自定义的消息类型,在各个平台上需要保持一致
@return 正文类型
*/
- (NSNumber*) contentType;
// 上层无需实现encode 实现此方法即可
- (NSDictionary*) encodeWithJSON;
// 上层无序实现decode 实现此方法即可
- (void) decodeWithJSON:(NSDictionary*)contentDic;
// 消息中的@提醒信息
@property (nonatomic, strong) WKMentionedInfo *mentionedInfo;
/// 回复内容
@property(nonatomic,strong) WKReply *reply;
...
```

View File

@ -0,0 +1,63 @@
# 连接管理
负责IM连接的建立维护断开等等
文档只介绍核心方法,更多内容查看代码的`[WKSDK shared].connectionManager`接口
## 配置
```objc
[WKSDK shared].options.host = @"xxx.xxx.xxx.xxx"; // IM通信端的IP
[WKSDK shared].options.port = 5100; // IM通信端的TCP端口
// 设置IM连接认证信息
[WKSDK shared].options.connectInfoCallback = ^WKConnectInfo * _Nonnull{
WKConnectInfo *connectInfo = [WKConnectInfo new];
connectInfo.uid = "xxxx"; // 用户uid 业务服务端在IM通讯端登记了的uid
connectInfo.token = "xxxx"; // 用户的token 业务服务端在IM通讯端登记了的token
return connectInfo;
};
```
更多配置请查看 `[WKSDK shared].options`
## 连接
``` objc
// 连接
[[WKSDK shared].connectionManager connect];
```
## 断开
``` objc
// 断开连接 NO: SDK保持重连机制 YES: SDK将不再进行重连
[[WKSDK shared].connectionManager disconnect:NO];
```
## 监听连接状态
```objc
[WKSDK.shared.connectManager addDelegate:self]; // WKConnectionManagerDelegate
```
```objc
// ---------- WKConnectionManagerDelegate ----------
/**
连接状态监听
*/
-(void) onConnectStatus:(WKConnectStatus)status reasonCode:(WKReason)reasonCode {
if(status == WKConnetced) {
NSLog(@"连接成功!");
}
}
```

View File

@ -0,0 +1,129 @@
# 最近会话管理
负责最近会话数据的管理,比如:新增最近会话,删除最近会话,未读消息数量等等
文档只介绍核心方法,更多内容查看代码的`[WKSDK shared].conversationManager`接口
## 最近会话列表
### 数据操作
获取本地最近会话列表
```objc
NSArray<WKConversation*> *conversations = [[WKSDK shared].conversationManager getConversationList];
```
### 数据监听
添加`WKConversationManagerDelegate`
```objc
[[WKSDK shared].conversationManager addDelegate:self];
```
WKConversationManagerDelegate说明
```objc
/**
当最近会话被新增的时候会调用此方法
@param conversation 最近会话对象
@param left 会话剩余数量 UI层可以判断left == 0 的时候才刷新 避免频繁刷新UI导致卡顿
*/
- (void)onConversationAdd:(WKConversation*)conversation left:(NSInteger)left;
/**
当最近会话对象更新的时候会调用此方法
@param conversation 最近会话对象
@param left 会话剩余数量 UI层可以判断left == 0 的时候才刷新 避免频繁刷新UI导致卡顿
*/
- (void)onConversationUpdate:(WKConversation*)conversation left:(NSInteger)left;
/**
最近会话未读数发送改变
@param channel 频道
@param unreadCount 未读数量
*/
- (void)onConversationUnreadCountUpdate:(WKChannel*)channel unreadCount:(NSInteger)unreadCount;
```
### 数据源
`触发时机当建立连接后由SDK主动触发拉取离线后的最近会话`
增量同步离线后的最近会话数据
```objc
// version 数据版本号
// lastMsgSeqs 拼接好的最近会话seq关系数据
// callback 当请求服务器获取到消息后SDK应调用此回调 (注意: 不管请求失败与否都需要调用callback
[[WKSDK shared].conversationManager setSyncConversationProviderAndAck:^(long long version, NSString * _Nonnull lastMsgSeqs, WKSyncConversationCallback _Nonnull callback) {
} ack:^(uint64_t cmdVersion, void (^ _Nullable complete)(NSError * _Nullable)) {
// 如果不需要ack回执直接调用complete(nil);
complete(nil);
}];
```
示例:
![示例](./conversationProvider.png)
## 最近会话扩展
通过最近会话扩展属性,可以自定义自己独特的业务属性,比如实现类似微信的草稿功能,并且草稿数据多端同步
### 数据操作
#### 更新扩展
```objc
[[WKSDK shared].conversationManager updateOrAddExtra:(WKConversationExtra*)extra]
```
#### 同步扩展
```objc
[[WKSDK shared].conversationManager syncExtra]
```
### 数据监听
如何最近会话对象的数据变化都会触发`WKConversationManagerDelegate`委托,同理 调用`updateOrAddExtra`也会触发此委托
### 数据源
#### 更新扩展
`触发时机:调用[[WKSDK shared].conversationManager updateOrAddExtra]时触发`
```objc
// extra 更新的扩展数据
// callback 更新完毕后回调给sdk
[[WKSDK shared].conversationManager setUpdateConversationExtraProvider:^(WKConversationExtra * _Nonnull extra, WKUpdateConversationExtraCallback _Nonnull callback) {
}];
```
#### 同步扩展
`触发时机:调用[[WKSDK shared].conversationManager syncExtra]时触发`
```objc
// version 客户端本地存在的最新扩展数据版本
// callback 同步扩展后将数据回调给sdk
[[WKSDK shared].conversationManager setSyncConversationExtraProvider:^(long long version, WKSyncConversationExtraCallback _Nonnull callback) {
}];
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 KiB

View File

@ -0,0 +1,16 @@
# 集成
## 通过 CocoaPods 集成
```objc
pod 'WuKongIMSDK'
```
## 通过源码集成
```objc
pod 'WuKongIMSDK', :git => 'https://github.com/WuKongIM/WuKongIMiOSSDK.git'
```

74
src/sdk/iossdk/intro.md Normal file
View File

@ -0,0 +1,74 @@
# 说明
## 设计理念
像设计书的目录一样设计 api, 通过 WKSDK.shared.xxxManager 我们可以访问到所有需要的功能,例如发送消息 `[WKSDK.shared.chatManager sendMessage:xxx]`
## 结构说明
![sdk结构图](./wksdk.png)
```objc
// 聊天管理者
// 负责消息相关的增删改查操作 比如发送消息,删除消息,撤回消息,聊天消息的监听等等
WKSDK.shared.chatManager
// 连接管理者
// 负责与IM建立连接或断开连接 监听IM连接状态等等
WKSDK.shared.connectionManager
// 频道管理者
// 负责频道数据的获取和缓存和一些频道的设置,比如置顶,免打扰,禁言等等
WKSDK.shared.channelManager
// 最近会话管理者
// 负责维护最近会话的相关数据,比如未读数量,草稿,@我,最后一条消息等等
WKSDK.shared.conversationManager
// 回应管理者
// 负责点赞数据的维护
WKSDK.shared.reactionManager
// cmd管理者
// 负责监听服务端下发的命令类的消息
WKSDK.shared.cmdManager
// 消息回执管理者
// 负责维护消息的已读未读状态
WKSDK.shared.receiptManager
// 提醒管理者
// 负责最近会话的提醒项,比如 有人@我,入群申请等等 还可以自定义一些提醒,比如类似微信的 [红包] [转账] 列表都会有提醒
WKSDK.shared.reminderManager
// 多媒体管理者
// 负责消息的多媒体文件的上传下载,比如图片消息,视频消息等等带附件的消息
WKSDK.shared.mediaManager
```
### SDK 与已有 APP 交互原则
![SDK与已有APP交互原则](./sdktoapp.png)
sdk 与已有 APP 交互的整体流程就是 已有 APP 调用 SDK 对应的方法->产生数据变化->通过 delegate 回调给已有 APP
比如常用的发送消息->消息状态变化->通知已有 APP 更新 UI 上的发送状态标记
```objc
// 通过操作chatMananger发送消息
[WKSDK.shared.chatManager sendMessage:xxx]
// chatManagerDelegate 通过chatManager的chatManagerDelegate监听消息的状态变化
-(void) onMessageUpdate:(WKMessage*) message {
if(message.status == SUCCESS) {
[self updateItemUIWithSuccess:message];
}else {
[self updateItemUIWithFail:message];
}
}
```

224
src/sdk/iossdk/media.md Normal file
View File

@ -0,0 +1,224 @@
# 多媒体管理
`消息里的文件,图片,视频,语音等多媒体资源都是通过多媒体管理器来管理的。`
负责消息的多媒体资源的管理,包括上传,下载等操作。
文档只介绍核心方法,更多内容查看代码的`[WKSDK shared].mediaManager`接口
## 自定义上传
### 创建任务
伪代码如下:
```objc
// 继承WKMessageFileDownloadTask
@interface WKFileUploadTask : WKMessageFileUploadTask
@end
```
```objc
// 实现四个方法 initWithMessage resume cancel suspend
@implementation WKFileUploadTask
(instancetype)initWithMessage:(WKMessage *)message {
self = [super initWithMessage:message];
if(self) {
[self initTask];
}
return self;
}
(void) initTask {
WKMediaContent *mediaContent = (WKMediaContent*)self.message.content;
NSString *fileLocalPath = mediaContent.localPath; // 附件本地路径
// 以下为上传伪代码
NSURLSessionDataTask *task = [serverAPI upload:fileLocalPath].progress(^(progress){
self.progress = progress; // 内部方法 更新任务进度
self.status = WKTaskStatusProgressing; // 内部方法 更新任务状态
[self update]; // 内部方法 通知更新
}).success(^{
self.status = WKTaskStatusSuccess; // 内部方法 更新任务状态
[self update]; // 内部方法 通知更新
}).catch(^(NSError *error){
self.status = WKTaskStatusError; // 内部方法 更新任务状态
self.error = error; // 内部方法 更新错误信息
[self update]; // 内部方法 通知更新
});
self.task = task;
}
// 任务恢复
(void) resume {
[self.task resume];
}
// 任务取消
(void) cancel {
[self.task cancel];
}
// 任务挂起
(void)suspend {
[self.task suspend];
}
@end
```
### 注册任务
注册上传任务
```objc
[[WKSDK shared].mediaManager setUploadTaskProvider:^id<WKTaskProto> _Nonnull(WKMessage * _Nonnull message) {
return [[WKFileUploadTask alloc] initWithMessage:message];
}];
```
## 自定义下载
所有带附件消息的下载都会通过此下载任务进行下载
### 创建任务
伪代码如下:
```objc
// 继承WKMessageFileDownloadTask
@interface WKFileDownloadTask : WKMessageFileDownloadTask
@end
```
```objc
// 实现四个方法 initWithMessage resume cancel suspend
@implementation WKFileDownloadTask
(instancetype)initWithMessage:(WKMessage *)message {
self = [super initWithMessage:message];
if(self) {
[self initTask];
}
return self;
}
(void) initTask {
WKMediaContent *mediaContent = (WKMediaContent*)self.message.content;
NSString *downloadURL = mediaContent.remoteUrl; // 附件下载地址
// 以下为下载伪代码
NSURLSessionDownloadTask *task = [serverAPI download:downloadURL].progress(^(progress){
self.progress = progress; // 内部方法 更新任务进度
self.status = WKTaskStatusProgressing; // 内部方法 更新任务状态
[self update]; // 内部方法 通知更新
}).success(^{
self.status = WKTaskStatusSuccess; // 内部方法 更新任务状态
[self update]; // 内部方法 通知更新
}).catch(^(NSError *error){
self.status = WKTaskStatusError; // 内部方法 更新任务状态
self.error = error; // 内部方法 更新错误信息
[self update]; // 内部方法 通知更新
});
self.task = task;
}
// 任务恢复
(void) resume {
[self.task resume];
}
// 任务取消
(void) cancel {
[self.task cancel];
}
// 任务挂起
(void)suspend {
[self.task suspend];
}
@end
```
### 注册任务
注册下载任务
```objc
[[WKSDK shared].mediaManager setDownloadTaskProvider:^id<WKTaskProto> _Nonnull(WKMessage * _Nonnull message) {
return [[WKFileDownloadTask alloc] initWithMessage:message];
}];
```
## 进度管理
### 上传
获取指定消息的上传任务,然后获取进度
```objc
WKMessageFileUploadTask *uploadTask = [[WKSDK shared] getMessageFileUploadTask:message];
if(uploadTask) {
float progress = uploadTask.progress;
}
```
监听上传任务进度
```objc
WKMessageFileUploadTask *uploadTask = [[WKSDK shared] getMessageFileUploadTask:message];
if(uploadTask) {
[uploadTask addListener:^{
float progress = uploadTask.progress;
}];
}
```
### 下载
下载消息里的附件
```objc
WKMessageFileDownloadTask *downloadTask = [[WKSDK shared].mediaManager download:message];
```
获取指定消息的下载任务,然后获取进度
```objc
WKMessageFileDownloadTask *downloadTask = [[WKSDK shared] getMessageFileDownloadTask:message];
if(downloadTask) {
float progress = downloadTask.progress;
}
```
监听下载任务进度
```objc
WKMessageFileDownloadTask *downloadTask = [[WKSDK shared] getMessageFileDownloadTask:message];
if(downloadTask) {
[downloadTask addListener:^{
float progress = downloadTask.progress;
}];
}
```

View File

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Before

Width:  |  Height:  |  Size: 382 KiB

After

Width:  |  Height:  |  Size: 382 KiB

View File

@ -153,7 +153,7 @@ WKSDK.shared().chatManager.addMessageStatusListener((packet: SendackPacket) => {
WKSDK.shared().chatManager.addMessageListener((message: Message) => {});
```
## 离线消息接收
在悟空 **IM**中为了应付海量离线消息,采用了按需拉取的机制,比如 10 个会话一个会话 10 万条消息,**WuKongIM** 不会把这个 **1010** 万=100 万条消息都拉取到本地。 而是采用拉取这 10 个会话的信息和对应的最新 20 条消息,也就是实际只拉取了 200 条消息 相对 100 万条消息来说大大提高了离线拉取速度。用户点进对应的会话才会去按需拉取这个会话的消息。 这些机制 SDK 内部都已做好了封装,使用者其实不需要关心。使用者只需要关心最近会话的变化
在悟空 **IM**中为了应付海量离线消息,采用了按需拉取的机制,比如 10 个会话一个会话 10 万条消息,**WuKongIM** 不会把这个 10 \*10 万=100 万条消息都拉取到本地。 而是采用拉取这 10 个会话的信息和对应的最新 20 条消息,也就是实际只拉取了 200 条消息 相对 100 万条消息来说大大提高了离线拉取速度。用户点进对应的会话才会去按需拉取这个会话的消息。 这些机制 SDK 内部都已做好了封装,使用者其实不需要关心。使用者只需要关心最近会话的变化
### 数据源设置
``` js

View File

@ -1,6 +1,8 @@
# 基础
## 配置

View File

@ -19,9 +19,8 @@ order: 200
{
"channel_id": "xxxx", // 频道的唯一ID如果是群聊频道建议使用群聊ID
"channel_type": 2, // 频道的类型 1.个人频道 2.群聊频道(个人与个人聊天不需要创建频道,系统将自动创建)
"large": 0, // 是否是超大群0.否 1.是 一般建议500成员以上设置为超大群注意超大群不会维护最近会话数据。
"ban": 0, // 是否封禁此频道0.否 1.是 (被封后 任何人都不能发消息,包括创建者)
"subscribers": [uid1,uid2,...], // 订阅者集合
"subscribers": ["uid1","uid2",...], // 订阅者集合
}
```

View File

@ -63,7 +63,7 @@ order: 500
返回结果
```json
[uid1,uid2,...] // 黑单成员用户id集合
[uid1,uid2,...] // 黑单成员用户id集合
```
### 获取白名单

View File

@ -4,6 +4,10 @@
`配置采用yaml格式如果发现配置什么都不生效请检查缩进是否正确`
`所有的配置都可以转换成对应的环境变量配置在docker-compose.yaml的environment里`
转换过程参考文档 [环境变量](#环境变量)
```yaml
## 配置是yaml格式请严格注意缩进.
mode: "release" # 运行模式 模式 debug 测试 release 正式 bench 压力测试
@ -19,7 +23,7 @@ whitelistOffOfPerson: true # 是否关闭个人白名单 默认为true表示关
ginMode: "release" # gin框架的模式 debug 调试 release 正式 test 测试
external: # 公网配置
ip: "" # 节点外网IP客户端能够访问到的IP地址如果客户端是内网使用这里也可以填写内网IP
tcpAddr: "" # 默认自动获取, 节点的TCP地址 对外公开APP端长连接通讯 格式: ip:port (支持域名配置)
tcpAddr: "" # 默认自动获取, 节点的TCP地址 对外公开APP端长连接通讯 格式: ip:port
wsAddr: "" # 默认自动获取, 节点的wsAdd地址 对外公开 WEB端长连接通讯 格式: ws://ip:port (支持域名配置)
wssAddr: "" # 对外的wssAddr地址也就是客户端真正连接的地址 格式wss://ip:port (支持域名配置)
monitorAddr: "" # 默认自动获取, 节点的monitor地址 对外公开 监控服务 格式: ip:port