docs: update readme

This commit is contained in:
tangtaoit
2024-04-30 12:45:17 +08:00
parent f425e60926
commit 8e332758f8
17 changed files with 94 additions and 115 deletions

View File

@@ -2,8 +2,6 @@
9年积累沉淀出来的高性能通用通讯服务支持即时通讯站内/系统消息消息中台物联网通讯音视频信令直播弹幕客服系统AI通讯即时社区等场景。
注意此项目是一个通用的底层即时通讯服务上层需要对接自己的具体业务系统通过webhook和datasource机制非常轻松与自己业务系统对接此项目核心点主要维护大量客户端的长连接并根据第三方业务系统配置的投递消息规则进行消息投递。
`本项目需要在go1.20.0或以上环境编译`
#### 2.0.0-beta版本发布正式发布beta版本不建议上生产生产请使用1.2.x的版本
@@ -28,15 +26,22 @@
[![](https://img.shields.io/badge/go%20report-A+-brightgreen.svg?style=flat)](https://goreportcard.com/report/github.com/WuKongIM/WuKongIM)
<a href="https://join.slack.com/t/wukongim/shared_invite/zt-22o7we8on-2iKNUmgigB9ERdF9XUivmw"><img src="https://img.shields.io/badge/Slack-99%2B-blueviolet?logo=slack&amp;logoColor=white"></a>
架构图
--------
![架构图](./docs/architecture/cluster.png)
节点故障转移演示
--------
![节点故障转移演示](./docs/architecture/cluster-failover.webp)
演示
--------
**聊天Demo**
![image](./docs/demo.gif)
Demo源码 https://github.com/WuKongIM/WuKongIMJSSDK/tree/main/examples
web聊天场景演示 http://imdemo.githubim.com
后端监控演示: http://monitor.githubim.com/web
@@ -47,6 +52,7 @@ web聊天场景演示 http://imdemo.githubim.com
深知开发一个即时通讯系统的复杂性,我们希望通过开源的方式,让更多的开发者可以快速的搭建自己的即时通讯系统,让信息传递更简单。 -->
特点
--------
@@ -92,94 +98,47 @@ web聊天场景演示 http://imdemo.githubim.com
---------------
### Docker部署
### Docker部署(单机)
```shell
docker run -d -p 5001:5001 -p 5100:5100 -p 5172:5172 -p 5200:5200 -p 5210:5210 -p 5300:5300 --name wukongim -v ./wukongim:/root/wukongim wukongim/wukongim:v2.0.0-beta-20240428
docker run -d -p 15001:5001 -p 15100:5100 -p 15172:5172 -p 15200:5200 -p 15210:5210 -p 15300:5300 --name wukongim -v ./wukongim:/root/wukongim wukongim/wukongim:v2.0.0-beta-20240428
```
### 二进制部署
```shell
wget -O wukongim https://github.com/WuKongIM/WuKongIM/releases/download/v1.2.1/wukongim-linux-amd64 # 其他系统请查看 https://github.com/WuKongIM/WuKongIM/releases
```
```shell
chmod +x wukongim
```
启动
```shell
./wukongim --config config/wk.yaml
```
### 源码部署
```shell
### Docker部署分布式
```yaml
git clone https://github.com/WuKongIM/WuKongIM.git
cd WuKongIM
cd ./WuKongIM/docker/cluster
go run main.go --config config/wk.yaml
sudo docker compose up -d
```
### 访问
查询系统信息: http://127.0.0.1:5001/varz
查询系统信息: http://127.0.0.1:15001/varz
查看监控信息: http://127.0.0.1:5300/web
查看监控信息: http://127.0.0.1:15300/web
客户端演示地址http://127.0.0.1:5172/chatdemo
客户端演示地址http://127.0.0.1:15172/chatdemo (分布式地址为http://127.0.0.1:15172/login)
端口解释:
```
5001: api端口
5100: tcp长连接端口
5172: demo端口
5200: websocket长连接端口
5300: 监控系统端口
15001: api端口
15100: tcp长连接端口
15172: demo端口
15200: websocket长连接端口
15300: 监控系统端口
```
分布式部署
---------------
启动集群
```shell
./wukongim --node-id=1001 --listen-addr=192.168.1.11:10001 --init-nodes=1001@192.168.1.11:10001,1002@192.168.1.12:10001
./wukongim --node-id=1002 --listen-addr=192.168.1.12:10001 --init-nodes=1001@192.168.1.11:10001,1002@192.168.1.12:10001
```
加入集群
```shell
./wukongim --node-id=1003 --listen-addr=192.168.1.13:1001 --join=192.168.1.11:10001
```
`
--join: 指定现有集群中的任意节点,新节点会自动加入到集群中
`
配套SDK源码和Demo
---------------

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{d as m,m as g,r as d,b as f,c as b,j as e,t as x,u as k,W as I,w as u,v as _,A as p,G as w,H as y,_ as S}from"./index-a9e9fb27.js";const U="/chatdemo/logo.png",c=a=>(w("data-v-6e16c5bf"),a=a(),y(),a),V={class:"hello"},A=c(()=>e("div",null,[e("a",{href:"https://githubim.com",target:"_blank"},[e("img",{src:U,class:"logo",alt:"Vite logo"})])],-1)),P={class:"form"},D={class:"item"},L=c(()=>e("div",{class:"label"},[e("label",null,"API基地址")],-1)),B={class:"field"},C={class:"item"},K=c(()=>e("div",{class:"label"},[e("label",null,"登录账号")],-1)),R={class:"field"},W={class:"item"},E=c(()=>e("div",{class:"label"},[e("label",null,"登录密码")],-1)),M={class:"field"},$=m({__name:"Login",setup(a){const v=g();var s=(o=>{var t=new RegExp("(^|&)"+o+"=([^&]*)(&|$)"),l=window.location.search.substr(1).match(t);return l!=null?unescape(l[2]):null})("apiurl");!s||(s==null?void 0:s.trim())==""?s="http://127.0.0.1:5001":s&&s.endsWith("/")&&(s=s.substring(0,s.length-1)),console.log("apiurl--->",s),d(0);const r=d(s||""),n=d(""),i=d(""),h=()=>{p.shared.config.apiURL=r.value,p.shared.post("/user/token",{uid:n.value,token:i.value||"default111111",device_flag:1,device_level:0}).then(o=>{console.log(o),v.push({path:"/chat",query:{uid:n.value,token:i.value}})}).catch(o=>{alert(o.msg)})};return(o,t)=>(f(),b("div",V,[A,e("p",null," 悟空IM演示程序当前SDK版本[v"+x(k(I).shared().config.sdkVersion)+"] ",1),e("div",P,[e("div",D,[L,e("div",B,[u(e("input",{type:"text",placeholder:"请输入API基地址","onUpdate:modelValue":t[0]||(t[0]=l=>r.value=l)},null,512),[[_,r.value]])])]),e("div",C,[K,e("div",R,[u(e("input",{type:"text",placeholder:"演示下,随便输,唯一即可","onUpdate:modelValue":t[1]||(t[1]=l=>n.value=l)},null,512),[[_,n.value]])])]),e("div",W,[E,e("div",M,[u(e("input",{type:"text",placeholder:"演示下,随便输","onUpdate:modelValue":t[2]||(t[2]=l=>i.value=l)},null,512),[[_,i.value]])])]),e("button",{class:"submit",onClick:h},"登录")])]))}});const G=S($,[["__scopeId","data-v-6e16c5bf"]]);export{G as default};
import{d as m,m as g,r as d,b as f,c as b,j as e,t as x,u as k,W as I,w as u,v as _,A as p,G as w,H as y,_ as S}from"./index-27af4409.js";const U="/chatdemo/logo.png",c=a=>(w("data-v-6e16c5bf"),a=a(),y(),a),V={class:"hello"},A=c(()=>e("div",null,[e("a",{href:"https://githubim.com",target:"_blank"},[e("img",{src:U,class:"logo",alt:"Vite logo"})])],-1)),P={class:"form"},D={class:"item"},L=c(()=>e("div",{class:"label"},[e("label",null,"API基地址")],-1)),B={class:"field"},C={class:"item"},K=c(()=>e("div",{class:"label"},[e("label",null,"登录账号")],-1)),R={class:"field"},W={class:"item"},E=c(()=>e("div",{class:"label"},[e("label",null,"登录密码")],-1)),M={class:"field"},$=m({__name:"Login",setup(a){const v=g();var s=(o=>{var t=new RegExp("(^|&)"+o+"=([^&]*)(&|$)"),l=window.location.search.substr(1).match(t);return l!=null?unescape(l[2]):null})("apiurl");!s||(s==null?void 0:s.trim())==""?s="http://127.0.0.1:5001":s&&s.endsWith("/")&&(s=s.substring(0,s.length-1)),console.log("apiurl--->",s),d(0);const r=d(s||""),n=d(""),i=d(""),h=()=>{p.shared.config.apiURL=r.value,p.shared.post("/user/token",{uid:n.value,token:i.value||"default111111",device_flag:1,device_level:0}).then(o=>{console.log(o),v.push({path:"/chat",query:{uid:n.value,token:i.value}})}).catch(o=>{alert(o.msg)})};return(o,t)=>(f(),b("div",V,[A,e("p",null," 悟空IM演示程序当前SDK版本[v"+x(k(I).shared().config.sdkVersion)+"] ",1),e("div",P,[e("div",D,[L,e("div",B,[u(e("input",{type:"text",placeholder:"请输入API基地址","onUpdate:modelValue":t[0]||(t[0]=l=>r.value=l)},null,512),[[_,r.value]])])]),e("div",C,[K,e("div",R,[u(e("input",{type:"text",placeholder:"演示下,随便输,唯一即可","onUpdate:modelValue":t[1]||(t[1]=l=>n.value=l)},null,512),[[_,n.value]])])]),e("div",W,[E,e("div",M,[u(e("input",{type:"text",placeholder:"演示下,随便输","onUpdate:modelValue":t[2]||(t[2]=l=>i.value=l)},null,512),[[_,i.value]])])]),e("button",{class:"submit",onClick:h},"登录")])]))}});const G=S($,[["__scopeId","data-v-6e16c5bf"]]);export{G as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -8,7 +8,7 @@
<title>悟空IM演示程序</title>
<script type="module" crossorigin src="/chatdemo/assets/index-a9e9fb27.js"></script>
<script type="module" crossorigin src="/chatdemo/assets/index-27af4409.js"></script>
<link rel="stylesheet" href="/chatdemo/assets/index-4eaedd69.css">
</head>

View File

@@ -14,7 +14,7 @@
"process": "^0.11.10",
"vue": "^3.2.45",
"vue-router": "^4.0.13",
"wukongimjssdk": "^1.2.4"
"wukongimjssdk": "^1.2.10"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.0.0",

View File

@@ -3,7 +3,7 @@
import { nextTick, onMounted, onUnmounted, ref, toRaw, toRefs, unref } from 'vue';
import APIClient from '../services/APIClient'
import { useRouter } from "vue-router";
import { WKSDK, Message, StreamItem, MessageText, Channel, ChannelTypePerson, ChannelTypeGroup, MessageStatus, SyncOptions, PullMode, MessageContent, MessageContentType } from "wukongimjssdk";
import { WKSDK, Message, StreamItem, MessageText, Channel, ChannelTypePerson, ChannelTypeGroup, MessageStatus, SyncOptions, PullMode, MessageContent, MessageContentType, ConnectionInfo } from "wukongimjssdk";
import { ConnectStatus, ConnectStatusListener } from 'wukongimjssdk';
import { SendackPacket, Setting } from 'wukongimjssdk';
import { Buffer } from 'buffer';
@@ -75,9 +75,14 @@ const connectIM = (addr: string) => {
// 监听连接状态
connectStatusListener = (status) => {
connectStatusListener = (status:ConnectStatus,reasonCode?:number,connectionInfo?:ConnectionInfo) => {
if (status == ConnectStatus.Connected) {
title.value = `${uid || ""}(连接成功)`
if(connectionInfo) {
title.value = `${uid || ""}(连接成功-节点:${connectionInfo.nodeId})`
}else{
title.value = `${uid || ""}(连接成功)`
}
} else {
title.value = `${uid || ""}(断开)`
}

View File

@@ -558,10 +558,10 @@ vue@^3.2.45:
"@vue/server-renderer" "3.3.4"
"@vue/shared" "3.3.4"
wukongimjssdk@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/wukongimjssdk/-/wukongimjssdk-1.2.4.tgz#1b716c02f12f9cdab755d26f9aea2b36f184bf31"
integrity sha512-HdiEvRxWVNniC0inSj/AzoSRXP1TF8u4WKsayyW+JA65eum8Q5xw2Si7KuCWs/6lqp0t5rNO0qj7Jzsh5WnLCg==
wukongimjssdk@^1.2.10:
version "1.2.10"
resolved "https://registry.yarnpkg.com/wukongimjssdk/-/wukongimjssdk-1.2.10.tgz#2aad714d9b04ca4ceae11bb527328bbeb715cb64"
integrity sha512-MX4NJoXGV+KnxZ6kK8UwsjLWEewGQudmCGV2d4/vrtI99Z78EkfWARPyVGX3jkqX0vwDzxid2JrcQewuo3vXGA==
dependencies:
"@types/bignumber.js" "^5.0.0"
"@types/crypto-js" "^4.0.2"

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

BIN
docs/screen6.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 MiB

2
go.mod
View File

@@ -4,7 +4,7 @@ go 1.22.1
require (
github.com/RussellLuo/timingwheel v0.0.0-20220218152713-54845bda3108
github.com/WuKongIM/WuKongIMGoProto v1.0.2
github.com/WuKongIM/WuKongIMGoProto v1.0.3
github.com/WuKongIM/crypto v0.0.0-20240416072338-b872b70b395f
github.com/bwmarrin/snowflake v0.3.0
github.com/cockroachdb/pebble v1.0.0

4
go.sum
View File

@@ -51,8 +51,8 @@ github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4K
github.com/RussellLuo/timingwheel v0.0.0-20220218152713-54845bda3108 h1:iPugyBI7oFtbDZXC4dnY093M1kZx6k/95sen92gafbY=
github.com/RussellLuo/timingwheel v0.0.0-20220218152713-54845bda3108/go.mod h1:WAMLHwunr1hi3u7OjGV6/VWG9QbdMhGpEKjROiSFd10=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
github.com/WuKongIM/WuKongIMGoProto v1.0.2 h1:IL48ILX0ghFvOOjmdyglYgf8CC0los84+ZUEDppydeU=
github.com/WuKongIM/WuKongIMGoProto v1.0.2/go.mod h1:EMPYhZR5K4cFvMCGhWzKlgfVieec1pnioUFgP0ga+ag=
github.com/WuKongIM/WuKongIMGoProto v1.0.3 h1:7nrITC19Si9cic4Ex4BE788GyjYtl88ZYDdsyBi8c6s=
github.com/WuKongIM/WuKongIMGoProto v1.0.3/go.mod h1:dUQCRuqwMoyYeLiHTsLBfbiWlVtB+8Gdsyq1M1oeEzg=
github.com/WuKongIM/crypto v0.0.0-20240416072338-b872b70b395f h1:erzPrCjuS7yvfpMyUxQjaMDHhBicUKt/qxwC/8s25VQ=
github.com/WuKongIM/crypto v0.0.0-20240416072338-b872b70b395f/go.mod h1:gS8ErzMrBY+zJfxwFFzUzR9S2jFo/FTyEVr4pedbfbA=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=

View File

@@ -250,6 +250,7 @@ func (p *Processor) processLocalAuth(conn wknet.Conn, connectPacket *wkproto.Con
ReasonCode: wkproto.ReasonSuccess,
TimeDiff: timeDiff,
ServerVersion: lastVersion,
NodeId: p.s.opts.Cluster.NodeId,
}
connack.HasServerVersion = hasServerVersion
p.response(conn, connack)
@@ -316,13 +317,27 @@ func (p *Processor) processRemoteAuth(conn wknet.Conn, connectPacket *wkproto.Co
// -------------------- response connack --------------------
lastVersion := connectPacket.Version
hasServerVersion := false
if connectPacket.Version > wkproto.LatestVersion {
lastVersion = wkproto.LatestVersion
}
if connectPacket.Version > 3 {
hasServerVersion = true
}
connack := &wkproto.ConnackPacket{
Salt: connResp.AesIV,
ServerKey: connResp.ServerPublicKey,
ReasonCode: wkproto.ReasonSuccess,
TimeDiff: timeDiff,
NodeId: p.s.opts.Cluster.NodeId,
ServerVersion: lastVersion,
}
connack.HasServerVersion = hasServerVersion
p.s.Debug("Auth Success", zap.Any("conn", conn))
p.response(conn, &wkproto.ConnackPacket{
Salt: connResp.AesIV,
ServerKey: connResp.ServerPublicKey,
ReasonCode: wkproto.ReasonSuccess,
TimeDiff: timeDiff,
})
p.response(conn, connack)
}