Compare commits

...

15 Commits

Author SHA1 Message Date
Gordon 958afd6115 fix: start don't kill old process (#892)
* fix: to start im or chat, ZooKeeper must be started first.

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: go mod update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: get all userID

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: msggateway add online status call

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* chore: network mode change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat: add api of get server time

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* feat: remove go work sum

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: pull message add isRead field

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: check msg-transfer script

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: start don't kill old process

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

---------

Signed-off-by: Gordon <1432970085@qq.com>
Signed-off-by: withchao <993506633@qq.com>
Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: Xinwei Xiong <3293172751NSS@gmail.com>
Co-authored-by: FGadvancer <FGadvancer@users.noreply.github.com>
2023-08-17 21:22:27 +08:00
EthanForAi 4f1dacabfa Feat/686: add release process (#891)
* feat: add pre-release process

* docs: add release process

---------

Co-authored-by: skiffer-git <44203734@qq.com>
2023-08-17 20:43:58 +08:00
Gordon 0c11880326 fix: script update (#889)
* fix: to start im or chat, ZooKeeper must be started first.

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: go mod update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: get all userID

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: msggateway add online status call

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* chore: network mode change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat: add api of get server time

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* feat: remove go work sum

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: pull message add isRead field

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: check msg-transfer script

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

---------

Signed-off-by: Gordon <1432970085@qq.com>
Signed-off-by: withchao <993506633@qq.com>
Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: Xinwei Xiong <3293172751NSS@gmail.com>
Co-authored-by: FGadvancer <FGadvancer@users.noreply.github.com>
2023-08-17 19:30:43 +08:00
Gordon b0d940945f fix: script update (#888)
* fix: to start im or chat, ZooKeeper must be started first.

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: go mod update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: get all userID

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: msggateway add online status call

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* chore: network mode change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat: add api of get server time

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* feat: remove go work sum

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: pull message add isRead field

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: check msg-transfer script

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

---------

Signed-off-by: Gordon <1432970085@qq.com>
Signed-off-by: withchao <993506633@qq.com>
Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: Xinwei Xiong <3293172751NSS@gmail.com>
Co-authored-by: FGadvancer <FGadvancer@users.noreply.github.com>
2023-08-17 19:21:12 +08:00
Gordon 6f9f7c767c fix: scripts of start and check update (#887)
* fix: to start im or chat, ZooKeeper must be started first.

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: go mod update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: get all userID

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: msggateway add online status call

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* chore: network mode change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat: add api of get server time

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* feat: remove go work sum

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: pull message add isRead field

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: check msg-transfer script

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix:  script update

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

---------

Signed-off-by: Gordon <1432970085@qq.com>
Signed-off-by: withchao <993506633@qq.com>
Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: Xinwei Xiong <3293172751NSS@gmail.com>
Co-authored-by: FGadvancer <FGadvancer@users.noreply.github.com>
2023-08-17 18:41:32 +08:00
Gordon dd5f2d0476 fix: check msg-transfer script (#886)
* fix: to start im or chat, ZooKeeper must be started first.

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: go mod update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: get all userID

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: msggateway add online status call

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* chore: network mode change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat: add api of get server time

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* feat: remove go work sum

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: pull message add isRead field

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: check msg-transfer script

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

---------

Signed-off-by: Gordon <1432970085@qq.com>
Signed-off-by: withchao <993506633@qq.com>
Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: Xinwei Xiong <3293172751NSS@gmail.com>
Co-authored-by: FGadvancer <FGadvancer@users.noreply.github.com>
2023-08-17 16:59:06 +08:00
Gordon 84c60cd6b6 Feature: add api of get server time and the message's read status is incorrect when app reinstalling. (#884)
* fix: to start im or chat, ZooKeeper must be started first.

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* fix: msg gateway start output err info

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: go mod update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* chore: package path changes

Signed-off-by: withchao <993506633@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: token update

Signed-off-by: Gordon <1432970085@qq.com>

* fix: get all userID

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* fix: msggateway add online status call

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* refactor: log change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* chore: network mode change

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat: add api of get server time

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* feat: remove go work sum

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: pull message add isRead field

Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>

---------

Signed-off-by: Gordon <1432970085@qq.com>
Signed-off-by: withchao <993506633@qq.com>
Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: Xinwei Xiong <3293172751NSS@gmail.com>
Co-authored-by: FGadvancer <FGadvancer@users.noreply.github.com>
2023-08-17 15:57:59 +08:00
pluto 7000755e15 Fix bug #862 (#879)
* test

* Solve the problem that the storage of multiple terminals in the online state is overwritten

* go.sum

* debug

* debug

* Judging whether to be kicked out

* Judging whether to be kicked out

* Finish debug
2023-08-17 14:20:46 +08:00
withchao b3899f559c fix: minio sign cndpoint crash caused by unconfigured (#881)
* fix: create group type limit

* fix: group notification

* fix: group notification

* fix: group notification

* chore: group member hash

* chore: group member hash

* chore: group member hash

* chore: group member hash

* test: log

* test: log

* test: log

* test: log

* test: log

* sync: hash code

* sync: hash code

* sync: hash code

* test: log

* test: log

* test: log

* test: log

* test: log

* fix: time stamp

* fix: minio sign endpoint opts
2023-08-16 18:43:10 +08:00
WangchuXiao 03906a89cd sync designation conversation unreadcount (#874)
* cicd: robot automated Change

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* new feat: get single con unread

* new feat: get single con unread

---------

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: wangchuxiao-dev <wangchuxiao-dev@users.noreply.github.com>
2023-08-16 10:54:53 +08:00
Dian Qi 51e747119c fix: support multi-platform build script(#866) (#867)
Co-authored-by: Dian Qi <qidian.qd@alibaba-inc.com>
2023-08-15 20:24:02 +08:00
pluto 5353e5fa66 Add feature 829 (#853)
* add user notification

* add user notification

* add UserStatusChangeNotification constant

* add get_subscribe_users_status interface

* update note

* log debug

* log debug

* add SingleChatType

* add SingleChatType and ContentTypeConf

* delete debug

* auto go.work.sum
2023-08-15 19:56:41 +08:00
withchao 57ce0bd29d group member sync use hash (#857)
* fix: create group type limit

* fix: group notification

* fix: group notification

* fix: group notification

* chore: group member hash

* chore: group member hash

* chore: group member hash

* chore: group member hash

* test: log

* test: log

* test: log

* test: log

* test: log

* sync: hash code

* sync: hash code

* sync: hash code

* test: log

* test: log

* test: log

* test: log

* test: log

* fix: time stamp
2023-08-14 17:55:36 +08:00
Ikko Eltociear Ashimine c5d66914fa fix: typo in golang.mk (#855)
Formating -> Formatting
2023-08-12 03:47:57 +00:00
Alan 50a63adf5e 815 (#849)
Signed-off-by: hanzhixiao <709674996@qq.com>
2023-08-11 06:41:40 +00:00
44 changed files with 1205 additions and 141 deletions
+4 -3
View File
@@ -1,5 +1,5 @@
# Build Stage # Build Stage
FROM golang:1.21 AS builder FROM golang:1.20 AS builder
# Set go mod installation source and proxy # Set go mod installation source and proxy
ARG GO111MODULE=on ARG GO111MODULE=on
@@ -10,8 +10,8 @@ ENV GOPROXY=$GOPROXY
# Set up the working directory # Set up the working directory
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
COPY go.mod go.sum ./ COPY go.mod go.sum go.work go.work.sum ./
RUN go mod download #RUN go mod download
# Copy all files to the container # Copy all files to the container
ADD . . ADD . .
@@ -27,5 +27,6 @@ WORKDIR ${SERVER_WORKDIR}
COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
COPY --from=builder ${SERVER_WORKDIR}/_output/bin/platforms /openim/openim-server/_output/bin/platforms COPY --from=builder ${SERVER_WORKDIR}/_output/bin/platforms /openim/openim-server/_output/bin/platforms
COPY --from=builder ${SERVER_WORKDIR}/_output/bin-tools/platforms /openim/openim-server/_output/bin-tools/platforms
CMD ["bash","-c","${OPENIM_SERVER_CMDDIR}/docker_start_all.sh"] CMD ["bash","-c","${OPENIM_SERVER_CMDDIR}/docker_start_all.sh"]
+10
View File
@@ -304,6 +304,16 @@ userInfoUpdated:
desc: "Remove a blocked user" desc: "Remove a blocked user"
ext: "Remove a blocked user" ext: "Remove a blocked user"
userStatusChanged:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "user status changed"
desc: "user status changed"
ext: "user status changed"
#####################conversation######################### #####################conversation#########################
conversationChanged: conversationChanged:
isSendMsg: false isSendMsg: false
+3 -2
View File
@@ -100,6 +100,7 @@ services:
openim-server: openim-server:
image: ghcr.io/openimsdk/openim-server:latest image: ghcr.io/openimsdk/openim-server:latest
# build: .
container_name: openim-server container_name: openim-server
volumes: volumes:
- ./logs:/openim/openim-server/logs - ./logs:/openim/openim-server/logs
@@ -149,7 +150,7 @@ services:
# ports: # ports:
# - 9091:9091 # - 9091:9091
depends_on: depends_on:
- openim-server - openim-server
command: --web.listen-address=:9091 --config.file="/etc/prometheus/prometheus.yml" command: --web.listen-address=:9091 --config.file="/etc/prometheus/prometheus.yml"
network_mode: "host" network_mode: "host"
@@ -169,4 +170,4 @@ services:
# container_name: node-exporter # container_name: node-exporter
# restart: always # restart: always
# ports: # ports:
# - "9100:9100" # - "9100:9100"
+12
View File
@@ -104,9 +104,21 @@ git merge release-v3.1
# Push the updates to the main branch # Push the updates to the main branch
git push origin main git push origin main
``` ```
## Release Process
```
Publishing v3.2.0: A Step-by-Step Guide
(1) Create the tag v3.2.0-alpha.0 from the main branch.
(2) Bugs are fixed on the main branch. Once the bugs are resolved, tag the main branch as v3.2.0-rc.0.
(3) After further testing, if v3.2.0-rc.0 is deemed stable, create a branch named release-v3.2 from the tag v3.2.0-rc.0.
(4) From the release-v3.2 branch, create the tag v3.2.0. At this point, the official release of v3.2.0 is complete.
After the release of v3.2.0, if urgent bugs are discovered, fix them on the release-v3.2 branch. Then, submit two pull requests (PRs) to both the main and release-v3.2 branches. Tag the release-v3.2 branch as v3.2.1.
```
Throughout this process, active communication within the team is pivotal to maintaining transparency and consensus on changes. Throughout this process, active communication within the team is pivotal to maintaining transparency and consensus on changes.
## Docker Images Version Management ## Docker Images Version Management
For more details on managing Docker image versions, visit [OpenIM Docker Images Administration](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md). For more details on managing Docker image versions, visit [OpenIM Docker Images Administration](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md).
+1 -1
View File
@@ -37,7 +37,7 @@ require (
require github.com/google/uuid v1.3.0 require github.com/google/uuid v1.3.0
require ( require (
github.com/OpenIMSDK/protocol v0.0.6 github.com/OpenIMSDK/protocol v0.0.12
github.com/OpenIMSDK/tools v0.0.13 github.com/OpenIMSDK/tools v0.0.13
github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible
github.com/go-redis/redis v6.15.9+incompatible github.com/go-redis/redis v6.15.9+incompatible
+2 -2
View File
@@ -17,8 +17,8 @@ cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7Biccwk
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4= firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs= firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OpenIMSDK/protocol v0.0.6 h1:KjaItOEww7vjrhwyxHnVzhw80pnjcNukpskadqW6gnA= github.com/OpenIMSDK/protocol v0.0.12 h1:79rBgpKBF4TMy5tkLH3DQNiZFVmxKMP7VyX+kmJh4d8=
github.com/OpenIMSDK/protocol v0.0.6/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= github.com/OpenIMSDK/protocol v0.0.12/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
github.com/OpenIMSDK/tools v0.0.13 h1:rcw4HS8S2DPZR9UOBxD8/ol9UBMzXBypzOVEytDRIMo= github.com/OpenIMSDK/tools v0.0.13 h1:rcw4HS8S2DPZR9UOBxD8/ol9UBMzXBypzOVEytDRIMo=
github.com/OpenIMSDK/tools v0.0.13/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/OpenIMSDK/tools v0.0.13/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
+2 -1
View File
@@ -1,7 +1,8 @@
go 1.20 go 1.20
use ( use (
. .
./tools/component
./tools/infra ./tools/infra
./tools/ncpu ./tools/ncpu
) )
+305 -1
View File
@@ -1,6 +1,310 @@
cloud.google.com/go/accessapproval v1.7.1 h1:/5YjNhR6lzCvmJZAnByYkfEgWjfAKwYP6nkuTk6nKFE=
cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68=
cloud.google.com/go/accesscontextmanager v1.8.1 h1:WIAt9lW9AXtqw/bnvrEUaE8VG/7bAAeMzRCBGMkc4+w=
cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo=
cloud.google.com/go/aiplatform v1.48.0 h1:M5davZWCTzE043rJCn+ZLW6hSxfG1KAx4vJTtas2/ec=
cloud.google.com/go/aiplatform v1.48.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA=
cloud.google.com/go/analytics v0.21.3 h1:TFBC1ZAqX9/jL56GEXdLrVe5vT3I22bDVWyDwZX4IEg=
cloud.google.com/go/analytics v0.21.3/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo=
cloud.google.com/go/apigateway v1.6.1 h1:aBSwCQPcp9rZ0zVEUeJbR623palnqtvxJlUyvzsKGQc=
cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA=
cloud.google.com/go/apigeeconnect v1.6.1 h1:6u/jj0P2c3Mcm+H9qLsXI7gYcTiG9ueyQL3n6vCmFJM=
cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs=
cloud.google.com/go/apigeeregistry v0.7.1 h1:hgq0ANLDx7t2FDZDJQrCMtCtddR/pjCqVuvQWGrQbXw=
cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw=
cloud.google.com/go/appengine v1.8.1 h1:J+aaUZ6IbTpBegXbmEsh8qZZy864ZVnOoWyfa1XSNbI=
cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY=
cloud.google.com/go/area120 v0.8.1 h1:wiOq3KDpdqXmaHzvZwKdpoM+3lDcqsI2Lwhyac7stss=
cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg=
cloud.google.com/go/artifactregistry v1.14.1 h1:k6hNqab2CubhWlGcSzunJ7kfxC7UzpAfQ1UPb9PDCKI=
cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E=
cloud.google.com/go/asset v1.14.1 h1:vlHdznX70eYW4V1y1PxocvF6tEwxJTTarwIGwOhFF3U=
cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ=
cloud.google.com/go/assuredworkloads v1.11.1 h1:yaO0kwS+SnhVSTF7BqTyVGt3DTocI6Jqo+S3hHmCwNk=
cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0=
cloud.google.com/go/automl v1.13.1 h1:iP9iQurb0qbz+YOOMfKSEjhONA/WcoOIjt6/m+6pIgo=
cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE=
cloud.google.com/go/baremetalsolution v1.1.1 h1:0Ge9PQAy6cZ1tRrkc44UVgYV15nw2TVnzJzYsMHXF+E=
cloud.google.com/go/baremetalsolution v1.1.1/go.mod h1:D1AV6xwOksJMV4OSlWHtWuFNZZYujJknMAP4Qa27QIA=
cloud.google.com/go/batch v1.3.1 h1:uE0Q//W7FOGPjf7nuPiP0zoE8wOT3ngoIO2HIet0ilY=
cloud.google.com/go/batch v1.3.1/go.mod h1:VguXeQKXIYaeeIYbuozUmBR13AfL4SJP7IltNPS+A4A=
cloud.google.com/go/beyondcorp v1.0.0 h1:VPg+fZXULQjs8LiMeWdLaB5oe8G9sEoZ0I0j6IMiG1Q=
cloud.google.com/go/beyondcorp v1.0.0/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4=
cloud.google.com/go/bigquery v1.53.0 h1:K3wLbjbnSlxhuG5q4pntHv5AEbQM1QqHKGYgwFIqOTg=
cloud.google.com/go/bigquery v1.53.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4=
cloud.google.com/go/billing v1.16.0 h1:1iktEAIZ2uA6KpebC235zi/rCXDdDYQ0bTXTNetSL80=
cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA=
cloud.google.com/go/binaryauthorization v1.6.1 h1:cAkOhf1ic92zEN4U1zRoSupTmwmxHfklcp1X7CCBKvE=
cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U=
cloud.google.com/go/certificatemanager v1.7.1 h1:uKsohpE0hiobx1Eak9jNcPCznwfB6gvyQCcS28Ah9E8=
cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI=
cloud.google.com/go/channel v1.16.0 h1:dqRkK2k7Ll/HHeYGxv18RrfhozNxuTJRkspW0iaFZoY=
cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc=
cloud.google.com/go/cloudbuild v1.13.0 h1:YBbAWcvE4x6xPWTyS+OU4eiUpz5rCS3VCM/aqmfddPA=
cloud.google.com/go/cloudbuild v1.13.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU=
cloud.google.com/go/clouddms v1.6.1 h1:rjR1nV6oVf2aNNB7B5uz1PDIlBjlOiBgR+q5n7bbB7M=
cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI=
cloud.google.com/go/cloudtasks v1.12.1 h1:cMh9Q6dkvh+Ry5LAPbD/U2aw6KAqdiU6FttwhbTo69w=
cloud.google.com/go/cloudtasks v1.12.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM=
cloud.google.com/go/contactcenterinsights v1.10.0 h1:YR2aPedGVQPpFBZXJnPkqRj8M//8veIZZH5ZvICoXnI=
cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM=
cloud.google.com/go/container v1.24.0 h1:N51t/cgQJFqDD/W7Mb+IvmAPHrf8AbPx7Bb7aF4lROE=
cloud.google.com/go/container v1.24.0/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4=
cloud.google.com/go/containeranalysis v0.10.1 h1:SM/ibWHWp4TYyJMwrILtcBtYKObyupwOVeceI9pNblw=
cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0=
cloud.google.com/go/datacatalog v1.16.0 h1:qVeQcw1Cz93/cGu2E7TYUPh8Lz5dn5Ws2siIuQ17Vng=
cloud.google.com/go/datacatalog v1.16.0/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4=
cloud.google.com/go/dataflow v0.9.1 h1:VzG2tqsk/HbmOtq/XSfdF4cBvUWRK+S+oL9k4eWkENQ=
cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw=
cloud.google.com/go/dataform v0.8.1 h1:xcWso0hKOoxeW72AjBSIp/UfkvpqHNzzS0/oygHlcqY=
cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M=
cloud.google.com/go/datafusion v1.7.1 h1:eX9CZoyhKQW6g1Xj7+RONeDj1mV8KQDKEB9KLELX9/8=
cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI=
cloud.google.com/go/datalabeling v0.8.1 h1:zxsCD/BLKXhNuRssen8lVXChUj8VxF3ofN06JfdWOXw=
cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY=
cloud.google.com/go/dataplex v1.9.0 h1:yoBWuuUZklYp7nx26evIhzq8+i/nvKYuZr1jka9EqLs=
cloud.google.com/go/dataplex v1.9.0/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE=
cloud.google.com/go/dataproc/v2 v2.0.1 h1:4OpSiPMMGV3XmtPqskBU/RwYpj3yMFjtMLj/exi425Q=
cloud.google.com/go/dataproc/v2 v2.0.1/go.mod h1:7Ez3KRHdFGcfY7GcevBbvozX+zyWGcwLJvvAMwCaoZ4=
cloud.google.com/go/dataqna v0.8.1 h1:ITpUJep04hC9V7C+gcK390HO++xesQFSUJ7S4nSnF3U=
cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8=
cloud.google.com/go/datastore v1.13.0 h1:ktbC66bOQB3HJPQe8qNI1/aiQ77PMu7hD4mzE6uxe3w=
cloud.google.com/go/datastore v1.13.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70=
cloud.google.com/go/datastream v1.10.0 h1:ra/+jMv36zTAGPfi8TRne1hXme+UsKtdcK4j6bnqQiw=
cloud.google.com/go/datastream v1.10.0/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q=
cloud.google.com/go/deploy v1.13.0 h1:A+w/xpWgz99EYzB6e31gMGAI/P5jTZ2UO7veQK5jQ8o=
cloud.google.com/go/deploy v1.13.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g=
cloud.google.com/go/dialogflow v1.40.0 h1:sCJbaXt6ogSbxWQnERKAzos57f02PP6WkGbOZvXUdwc=
cloud.google.com/go/dialogflow v1.40.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4=
cloud.google.com/go/dlp v1.10.1 h1:tF3wsJ2QulRhRLWPzWVkeDz3FkOGVoMl6cmDUHtfYxw=
cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI=
cloud.google.com/go/documentai v1.22.0 h1:dW8ex9yb3oT9s1yD2+yLcU8Zq15AquRZ+wd0U+TkxFw=
cloud.google.com/go/documentai v1.22.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E=
cloud.google.com/go/domains v0.9.1 h1:rqz6KY7mEg7Zs/69U6m6LMbB7PxFDWmT3QWNXIqhHm0=
cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE=
cloud.google.com/go/edgecontainer v1.1.1 h1:zhHWnLzg6AqzE+I3gzJqiIwHfjEBhWctNQEzqb+FaRo=
cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk=
cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0=
cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU=
cloud.google.com/go/essentialcontacts v1.6.2 h1:OEJ0MLXXCW/tX1fkxzEZOsv/wRfyFsvDVNaHWBAvoV0=
cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4=
cloud.google.com/go/eventarc v1.13.0 h1:xIP3XZi0Xawx8DEfh++mE2lrIi5kQmCr/KcWhJ1q0J4=
cloud.google.com/go/eventarc v1.13.0/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI=
cloud.google.com/go/filestore v1.7.1 h1:Eiz8xZzMJc5ppBWkuaod/PUdUZGCFR8ku0uS+Ah2fRw=
cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4=
cloud.google.com/go/functions v1.15.1 h1:LtAyqvO1TFmNLcROzHZhV0agEJfBi+zfMZsF4RT/a7U=
cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE=
cloud.google.com/go/gkebackup v1.3.0 h1:lgyrpdhtJKV7l1GM15YFt+OCyHMxsQZuSydyNmS0Pxo=
cloud.google.com/go/gkebackup v1.3.0/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU=
cloud.google.com/go/gkeconnect v0.8.1 h1:a1ckRvVznnuvDWESM2zZDzSVFvggeBaVY5+BVB8tbT0=
cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw=
cloud.google.com/go/gkehub v0.14.1 h1:2BLSb8i+Co1P05IYCKATXy5yaaIw/ZqGvVSBTLdzCQo=
cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY=
cloud.google.com/go/gkemulticloud v1.0.0 h1:MluqhtPVZReoriP5+adGIw+ij/RIeRik8KApCW2WMTw=
cloud.google.com/go/gkemulticloud v1.0.0/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw=
cloud.google.com/go/gsuiteaddons v1.6.1 h1:mi9jxZpzVjLQibTS/XfPZvl+Jr6D5Bs8pGqUjllRb00=
cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY=
cloud.google.com/go/iap v1.8.1 h1:X1tcp+EoJ/LGX6cUPt3W2D4H2Kbqq0pLAsldnsCjLlE=
cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ=
cloud.google.com/go/ids v1.4.1 h1:khXYmSoDDhWGEVxHl4c4IgbwSRR+qE/L4hzP3vaU9Hc=
cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw=
cloud.google.com/go/iot v1.7.1 h1:yrH0OSmicD5bqGBoMlWG8UltzdLkYzNUwNVUVz7OT54=
cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk=
cloud.google.com/go/kms v1.15.0 h1:xYl5WEaSekKYN5gGRyhjvZKM22GVBBCzegGNVPy+aIs=
cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM=
cloud.google.com/go/language v1.10.1 h1:3MXeGEv8AlX+O2LyV4pO4NGpodanc26AmXwOuipEym0=
cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0=
cloud.google.com/go/lifesciences v0.9.1 h1:axkANGx1wiBXHiPcJZAE+TDjjYoJRIDzbHC/WYllCBU=
cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc=
cloud.google.com/go/logging v1.7.0 h1:CJYxlNNNNAMkHp9em/YEXcfJg+rPDg7YfwoRpMU+t5I=
cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M=
cloud.google.com/go/managedidentities v1.6.1 h1:2/qZuOeLgUHorSdxSQGtnOu9xQkBn37+j+oZQv/KHJY=
cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak=
cloud.google.com/go/maps v1.4.0 h1:PdfgpBLhAoSzZrQXP+/zBc78fIPLZSJp5y8+qSMn2UU=
cloud.google.com/go/maps v1.4.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s=
cloud.google.com/go/mediatranslation v0.8.1 h1:50cF7c1l3BanfKrpnTCaTvhf+Fo6kdF21DG0byG7gYU=
cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig=
cloud.google.com/go/memcache v1.10.1 h1:7lkLsF0QF+Mre0O/NvkD9Q5utUNwtzvIYjrOLOs0HO0=
cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA=
cloud.google.com/go/metastore v1.12.0 h1:+9DsxUOHvsqvC0ylrRc/JwzbXJaaBpfIK3tX0Lx8Tcc=
cloud.google.com/go/metastore v1.12.0/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA=
cloud.google.com/go/monitoring v1.15.1 h1:65JhLMd+JiYnXr6j5Z63dUYCuOg770p8a/VC+gil/58=
cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM=
cloud.google.com/go/networkconnectivity v1.12.1 h1:LnrYM6lBEeTq+9f2lR4DjBhv31EROSAQi/P5W4Q0AEc=
cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E=
cloud.google.com/go/networkmanagement v1.8.0 h1:/3xP37eMxnyvkfLrsm1nv1b2FbMMSAEAOlECTvoeCq4=
cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0=
cloud.google.com/go/networksecurity v0.9.1 h1:TBLEkMp3AE+6IV/wbIGRNTxnqLXHCTEQWoxRVC18TzY=
cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ=
cloud.google.com/go/notebooks v1.9.1 h1:CUqMNEtv4EHFnbogV+yGHQH5iAQLmijOx191innpOcs=
cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8=
cloud.google.com/go/optimization v1.4.1 h1:pEwOAmO00mxdbesCRSsfj8Sd4rKY9kBrYW7Vd3Pq7cA=
cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk=
cloud.google.com/go/orchestration v1.8.1 h1:KmN18kE/xa1n91cM5jhCh7s1/UfIguSCisw7nTMUzgE=
cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8=
cloud.google.com/go/orgpolicy v1.11.1 h1:I/7dHICQkNwym9erHqmlb50LRU588NPCvkfIY0Bx9jI=
cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE=
cloud.google.com/go/osconfig v1.12.1 h1:dgyEHdfqML6cUW6/MkihNdTVc0INQst0qSE8Ou1ub9c=
cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE=
cloud.google.com/go/oslogin v1.10.1 h1:LdSuG3xBYu2Sgr3jTUULL1XCl5QBx6xwzGqzoDUw1j0=
cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs=
cloud.google.com/go/phishingprotection v0.8.1 h1:aK/lNmSd1vtbft/vLe2g7edXK72sIQbqr2QyrZN/iME=
cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I=
cloud.google.com/go/policytroubleshooter v1.8.0 h1:XTMHy31yFmXgQg57CB3w9YQX8US7irxDX0Fl0VwlZyY=
cloud.google.com/go/policytroubleshooter v1.8.0/go.mod h1:tmn5Ir5EToWe384EuboTcVQT7nTag2+DuH3uHmKd1HU=
cloud.google.com/go/privatecatalog v0.9.1 h1:B/18xGo+E0EMS9LOEQ0zXz7F2asMgmVgTYGSI89MHOA=
cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA=
cloud.google.com/go/pubsub v1.33.0 h1:6SPCPvWav64tj0sVX/+npCBKhUi/UjJehy9op/V3p2g=
cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc=
cloud.google.com/go/pubsublite v1.8.1 h1:pX+idpWMIH30/K7c0epN6V703xpIcMXWRjKJsz0tYGY=
cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0=
cloud.google.com/go/recaptchaenterprise/v2 v2.7.2 h1:IGkbudobsTXAwmkEYOzPCQPApUCsN4Gbq3ndGVhHQpI=
cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU=
cloud.google.com/go/recommendationengine v0.8.1 h1:nMr1OEVHuDambRn+/y4RmNAmnR/pXCuHtH0Y4tCgGRQ=
cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE=
cloud.google.com/go/recommender v1.10.1 h1:UKp94UH5/Lv2WXSQe9+FttqV07x/2p1hFTMMYVFtilg=
cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA=
cloud.google.com/go/redis v1.13.1 h1:YrjQnCC7ydk+k30op7DSjSHw1yAYhqYXFcOq1bSXRYA=
cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg=
cloud.google.com/go/resourcemanager v1.9.1 h1:QIAMfndPOHR6yTmMUB0ZN+HSeRmPjR/21Smq5/xwghI=
cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8=
cloud.google.com/go/resourcesettings v1.6.1 h1:Fdyq418U69LhvNPFdlEO29w+DRRjwDA4/pFamm4ksAg=
cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw=
cloud.google.com/go/retail v1.14.1 h1:gYBrb9u/Hc5s5lUTFXX1Vsbc/9BEvgtioY6ZKaK0DK8=
cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE=
cloud.google.com/go/run v1.2.0 h1:kHeIG8q+N6Zv0nDkBjSOYfK2eWqa5FnaiDPH/7/HirE=
cloud.google.com/go/run v1.2.0/go.mod h1:36V1IlDzQ0XxbQjUx6IYbw8H3TJnWvhii963WW3B/bo=
cloud.google.com/go/scheduler v1.10.1 h1:yoZbZR8880KgPGLmACOMCiY2tPk+iX4V/dkxqTirlz8=
cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo=
cloud.google.com/go/secretmanager v1.11.1 h1:cLTCwAjFh9fKvU6F13Y4L9vPcx9yiWPyWXE4+zkuEQs=
cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw=
cloud.google.com/go/security v1.15.1 h1:jR3itwycg/TgGA0uIgTItcVhA55hKWiNJxaNNpQJaZE=
cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA=
cloud.google.com/go/securitycenter v1.23.0 h1:XOGJ9OpnDtqg8izd7gYk/XUhj8ytjIalyjjsR6oyG0M=
cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ=
cloud.google.com/go/servicedirectory v1.11.0 h1:pBWpjCFVGWkzVTkqN3TBBIqNSoSHY86/6RL0soSQ4z8=
cloud.google.com/go/servicedirectory v1.11.0/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ=
cloud.google.com/go/shell v1.7.1 h1:aHbwH9LSqs4r2rbay9f6fKEls61TAjT63jSyglsw7sI=
cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g=
cloud.google.com/go/spanner v1.47.0 h1:aqiMP8dhsEXgn9K5EZBWxPG7dxIiyM2VaikqeU4iteg=
cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI=
cloud.google.com/go/speech v1.19.0 h1:MCagaq8ObV2tr1kZJcJYgXYbIn8Ai5rp42tyGYw9rls=
cloud.google.com/go/speech v1.19.0/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo=
cloud.google.com/go/storagetransfer v1.10.0 h1:+ZLkeXx0K0Pk5XdDmG0MnUVqIR18lllsihU/yq39I8Q=
cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA=
cloud.google.com/go/talent v1.6.2 h1:j46ZgD6N2YdpFPux9mc7OAf4YK3tiBCsbLKc8rQx+bU=
cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24=
cloud.google.com/go/texttospeech v1.7.1 h1:S/pR/GZT9p15R7Y2dk2OXD/3AufTct/NSxT4a7nxByw=
cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk=
cloud.google.com/go/tpu v1.6.1 h1:kQf1jgPY04UJBYYjNUO+3GrZtIb57MfGAW2bwgLbR3A=
cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E=
cloud.google.com/go/trace v1.10.1 h1:EwGdOLCNfYOOPtgqo+D2sDLZmRCEO1AagRTJCU6ztdg=
cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk=
cloud.google.com/go/translate v1.8.2 h1:PQHamiOzlehqLBJMnM72lXk/OsMQewZB12BKJ8zXrU0=
cloud.google.com/go/translate v1.8.2/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs=
cloud.google.com/go/video v1.19.0 h1:BRyyS+wU+Do6VOXnb8WfPr42ZXti9hzmLKLUCkggeK4=
cloud.google.com/go/video v1.19.0/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU=
cloud.google.com/go/videointelligence v1.11.1 h1:MBMWnkQ78GQnRz5lfdTAbBq/8QMCF3wahgtHh3s/J+k=
cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo=
cloud.google.com/go/vision/v2 v2.7.2 h1:ccK6/YgPfGHR/CyESz1mvIbsht5Y2xRsWCPqmTNydEw=
cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU=
cloud.google.com/go/vmmigration v1.7.1 h1:gnjIclgqbEMc+cF5IJuPxp53wjBIlqZ8h9hE8Rkwp7A=
cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro=
cloud.google.com/go/vmwareengine v1.0.0 h1:qsJ0CPlOQu/3MFBGklu752v3AkD+Pdu091UmXJ+EjTA=
cloud.google.com/go/vmwareengine v1.0.0/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0=
cloud.google.com/go/vpcaccess v1.7.1 h1:ram0GzjNWElmbxXMIzeOZUkQ9J8ZAahD6V8ilPGqX0Y=
cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs=
cloud.google.com/go/webrisk v1.9.1 h1:Ssy3MkOMOnyRV5H2bkMQ13Umv7CwB/kugo3qkAX83Fk=
cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc=
cloud.google.com/go/websecurityscanner v1.6.1 h1:CfEF/vZ+xXyAR3zC9iaC/QRdf1MEgS20r5UR17Q4gOg=
cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg=
cloud.google.com/go/workflows v1.11.1 h1:2akeQ/PgtRhrNuD/n1WvJd5zb7YyuDZrlOanBj2ihPg=
cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/OpenIMSDK/protocol v0.0.12/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409 h1:DTQ/38ao/CfXsrK0cSAL+h4R/u0VVvfWLZEOlLwEROI=
github.com/alecthomas/kingpin/v2 v2.3.1 h1:ANLJcKmQm4nIaog7xdr/id6FM6zm5hHnfZrvtKPxqGg=
github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk=
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q=
github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8=
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
github.com/google/go-pkcs11 v0.2.0 h1:5meDPB26aJ98f+K9G21f0AqZwo/S5BJMJh8nuhMbdsI=
github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563 h1:2VDxTtn9dAqI2DnnvB9fXpPE4DblOmquyzmN2zxTD8A=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563 h1:FoX+MK4vHThvPO6FbP5q98zD8S3n+d5+DbtK7skl++c=
github.com/xdg/scram v1.0.3 h1:nTadYh2Fs4BK2xdldEa2g5bbaZp0/+1nJMMPtPxS/to=
github.com/xdg/stringprep v1.0.3 h1:cmL5Enob4W83ti/ZHuZLuKD/xqJfus4fVPwE+/BDm+4=
github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc=
github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577 h1:ZX0eQu2J+jOO87sq8fQG8J/Nfp7D7BhHpixIE5EYK/k=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=
rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
+3
View File
@@ -363,3 +363,6 @@ func (m *MessageApi) GetActiveGroup(c *gin.Context) {
func (m *MessageApi) SearchMsg(c *gin.Context) { func (m *MessageApi) SearchMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.SearchMessage, m.Client, c) a2r.Call(msg.MsgClient.SearchMessage, m.Client, c)
} }
func (m *MessageApi) GetServerTime(c *gin.Context) {
a2r.Call(msg.MsgClient.GetServerTime, m.Client, c)
}
+3 -1
View File
@@ -82,9 +82,10 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
userRouterGroup.POST("/get_users", ParseToken, u.GetUsers) userRouterGroup.POST("/get_users", ParseToken, u.GetUsers)
userRouterGroup.POST("/get_users_online_status", ParseToken, u.GetUsersOnlineStatus) userRouterGroup.POST("/get_users_online_status", ParseToken, u.GetUsersOnlineStatus)
userRouterGroup.POST("/get_users_online_token_detail", ParseToken, u.GetUsersOnlineTokenDetail) userRouterGroup.POST("/get_users_online_token_detail", ParseToken, u.GetUsersOnlineTokenDetail)
userRouterGroup.POST("/subscribe_users_status", ParseToken, u.UnSubscriberStatus) userRouterGroup.POST("/subscribe_users_status", ParseToken, u.SubscriberStatus)
userRouterGroup.POST("/unsubscribe_users_status", ParseToken, u.UnSubscriberStatus) userRouterGroup.POST("/unsubscribe_users_status", ParseToken, u.UnSubscriberStatus)
userRouterGroup.POST("/get_users_status", ParseToken, u.GetUserStatus) userRouterGroup.POST("/get_users_status", ParseToken, u.GetUserStatus)
userRouterGroup.POST("/get_subscribe_users_status", ParseToken, u.GetSubscribeUsersStatus)
} }
// friend routing group // friend routing group
friendRouterGroup := r.Group("/friend", ParseToken) friendRouterGroup := r.Group("/friend", ParseToken)
@@ -186,6 +187,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
msgGroup.POST("/batch_send_msg", m.BatchSendMsg) msgGroup.POST("/batch_send_msg", m.BatchSendMsg)
msgGroup.POST("/check_msg_is_send_success", m.CheckMsgIsSendSuccess) msgGroup.POST("/check_msg_is_send_success", m.CheckMsgIsSendSuccess)
msgGroup.POST("/get_server_time", m.GetServerTime)
} }
// Conversation // Conversation
conversationGroup := r.Group("/conversation", ParseToken) conversationGroup := r.Group("/conversation", ParseToken)
+6
View File
@@ -196,6 +196,12 @@ func (u *UserApi) UnSubscriberStatus(c *gin.Context) {
a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c) a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c)
} }
// GetUserStatus Get the online status of the user.
func (u *UserApi) GetUserStatus(c *gin.Context) { func (u *UserApi) GetUserStatus(c *gin.Context) {
a2r.Call(user.UserClient.GetUserStatus, u.Client, c) a2r.Call(user.UserClient.GetUserStatus, u.Client, c)
} }
// GetSubscribeUsersStatus Get the online status of subscribers.
func (u *UserApi) GetSubscribeUsersStatus(c *gin.Context) {
a2r.Call(user.UserClient.GetSubscribeUsersStatus, u.Client, c)
}
+63 -13
View File
@@ -16,6 +16,9 @@ package group
import ( import (
"context" "context"
"crypto/md5"
"encoding/binary"
"encoding/json"
"fmt" "fmt"
"math/big" "math/big"
"math/rand" "math/rand"
@@ -73,20 +76,33 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
userRpcClient := rpcclient.NewUserRpcClient(client) userRpcClient := rpcclient.NewUserRpcClient(client)
msgRpcClient := rpcclient.NewMessageRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client)
conversationRpcClient := rpcclient.NewConversationRpcClient(client) conversationRpcClient := rpcclient.NewConversationRpcClient(client)
database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase()) var gs groupServer
pbGroup.RegisterGroupServer(server, &groupServer{ database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), gs.groupMemberHashCode)
GroupDatabase: database, gs.GroupDatabase = database
User: userRpcClient, gs.User = userRpcClient
Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) { gs.Notification = notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
users, err := userRpcClient.GetUsersInfo(ctx, userIDs) users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
}),
conversationRpcClient: conversationRpcClient,
msgRpcClient: msgRpcClient,
}) })
gs.conversationRpcClient = conversationRpcClient
gs.msgRpcClient = msgRpcClient
pbGroup.RegisterGroupServer(server, &gs)
//pbGroup.RegisterGroupServer(server, &groupServer{
// GroupDatabase: database,
// User: userRpcClient,
// Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
// users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
// if err != nil {
// return nil, err
// }
// return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
// }),
// conversationRpcClient: conversationRpcClient,
// msgRpcClient: msgRpcClient,
//})
return nil return nil
} }
@@ -1491,3 +1507,37 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req *
resp.Total = total resp.Total = total
return resp, nil return resp, nil
} }
func (s *groupServer) groupMemberHashCode(ctx context.Context, groupID string) (uint64, error) {
userIDs, err := s.GroupDatabase.FindGroupMemberUserID(ctx, groupID)
if err != nil {
return 0, err
}
var members []*sdkws.GroupMemberFullInfo
if len(userIDs) > 0 {
resp, err := s.GetGroupMembersInfo(ctx, &pbGroup.GetGroupMembersInfoReq{GroupID: groupID, UserIDs: userIDs})
if err != nil {
return 0, err
}
members = resp.Members
utils.Sort(userIDs, true)
}
memberMap := utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string {
return e.UserID
})
res := make([]*sdkws.GroupMemberFullInfo, 0, len(members))
for _, userID := range userIDs {
member, ok := memberMap[userID]
if !ok {
continue
}
member.AppMangerLevel = 0
res = append(res, member)
}
data, err := json.Marshal(res)
if err != nil {
return 0, err
}
sum := md5.Sum(data)
return binary.BigEndian.Uint64(sum[:]), nil
}
+10 -5
View File
@@ -26,10 +26,15 @@ import (
"github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/tools/log"
) )
func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (*msg.GetConversationsHasReadAndMaxSeqResp, error) { func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (resp *msg.GetConversationsHasReadAndMaxSeqResp, err error) {
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID) var conversationIDs []string
if err != nil { if len(req.ConversationIDs) == 0 {
return nil, err conversationIDs, err = m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
if err != nil {
return nil, err
}
} else {
conversationIDs = req.ConversationIDs
} }
hasReadSeqs, err := m.MsgDatabase.GetHasReadSeqs(ctx, req.UserID, conversationIDs) hasReadSeqs, err := m.MsgDatabase.GetHasReadSeqs(ctx, req.UserID, conversationIDs)
if err != nil { if err != nil {
@@ -49,7 +54,7 @@ func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *m
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp := &msg.GetConversationsHasReadAndMaxSeqResp{Seqs: make(map[string]*msg.Seqs)} resp = &msg.GetConversationsHasReadAndMaxSeqResp{Seqs: make(map[string]*msg.Seqs)}
for conversarionID, maxSeq := range maxSeqs { for conversarionID, maxSeq := range maxSeqs {
resp.Seqs[conversarionID] = &msg.Seqs{ resp.Seqs[conversarionID] = &msg.Seqs{
HasReadSeq: hasReadSeqs[conversarionID], HasReadSeq: hasReadSeqs[conversarionID],
+3
View File
@@ -188,3 +188,6 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq
resp.ChatLogsNum = total resp.ChatLogsNum = total
return resp, nil return resp, nil
} }
func (m *msgServer) GetServerTime(ctx context.Context, _ *msg.GetServerTimeReq) (*msg.GetServerTimeResp, error) {
return &msg.GetServerTimeResp{ServerTime: utils.GetCurrentTimestampByMill()}, nil
}
+1 -1
View File
@@ -113,7 +113,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
if groupMemberInfo.RoleLevel == constant.GroupOwner { if groupMemberInfo.RoleLevel == constant.GroupOwner {
return nil return nil
} else { } else {
if groupMemberInfo.MuteEndTime >= time.Now().Unix() { if groupMemberInfo.MuteEndTime >= time.Now().UnixMilli() {
return errs.ErrMutedInGroup.Wrap() return errs.ErrMutedInGroup.Wrap()
} }
if groupInfo.Status == constant.GroupStatusMuted && groupMemberInfo.RoleLevel != constant.GroupAdmin { if groupInfo.Status == constant.GroupStatusMuted && groupMemberInfo.RoleLevel != constant.GroupAdmin {
+42 -10
View File
@@ -47,9 +47,10 @@ import (
type userServer struct { type userServer struct {
controller.UserDatabase controller.UserDatabase
notificationSender *notification.FriendNotificationSender friendNotificationSender *notification.FriendNotificationSender
friendRpcClient *rpcclient.FriendRpcClient userNotificationSender *notification.UserNotificationSender
RegisterCenter registry.SvcDiscoveryRegistry friendRpcClient *rpcclient.FriendRpcClient
RegisterCenter registry.SvcDiscoveryRegistry
} }
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
@@ -82,10 +83,11 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
friendRpcClient := rpcclient.NewFriendRpcClient(client) friendRpcClient := rpcclient.NewFriendRpcClient(client)
msgRpcClient := rpcclient.NewMessageRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client)
u := &userServer{ u := &userServer{
UserDatabase: database, UserDatabase: database,
RegisterCenter: client, RegisterCenter: client,
friendRpcClient: &friendRpcClient, friendRpcClient: &friendRpcClient,
notificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)), friendNotificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)),
userNotificationSender: notification.NewUserNotificationSender(&msgRpcClient, notification.WithUserFunc(database.FindWithError)),
} }
pbuser.RegisterUserServer(server, u) pbuser.RegisterUserServer(server, u)
return u.UserDatabase.InitOnce(context.Background(), users) return u.UserDatabase.InitOnce(context.Background(), users)
@@ -118,13 +120,13 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
if err != nil { if err != nil {
return nil, err return nil, err
} }
_ = s.notificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID) _ = s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID)
friends, err := s.friendRpcClient.GetFriendIDs(ctx, req.UserInfo.UserID) friends, err := s.friendRpcClient.GetFriendIDs(ctx, req.UserInfo.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, friendID := range friends { for _, friendID := range friends {
s.notificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID) s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
} }
return resp, nil return resp, nil
} }
@@ -139,7 +141,7 @@ func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Se
if err := s.UpdateByMap(ctx, req.UserID, m); err != nil { if err := s.UpdateByMap(ctx, req.UserID, m); err != nil {
return nil, err return nil, err
} }
s.notificationSender.UserInfoUpdatedNotification(ctx, req.UserID) s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserID)
return resp, nil return resp, nil
} }
@@ -272,6 +274,7 @@ func (s *userServer) SubscribeOrCancelUsersStatus(ctx context.Context, req *pbus
return &pbuser.SubscribeOrCancelUsersStatusResp{}, nil return &pbuser.SubscribeOrCancelUsersStatusResp{}, nil
} }
// GetUserStatus Get the online status of the user.
func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatusReq) (resp *pbuser.GetUserStatusResp, err error) { func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatusReq) (resp *pbuser.GetUserStatusResp, err error) {
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, req.UserIDs) onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, req.UserIDs)
if err != nil { if err != nil {
@@ -280,10 +283,39 @@ func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatu
return &pbuser.GetUserStatusResp{StatusList: onlineStatusList}, nil return &pbuser.GetUserStatusResp{StatusList: onlineStatusList}, nil
} }
// SetUserStatus Synchronize user's online status.
func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatusReq) (resp *pbuser.SetUserStatusResp, err error) { func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatusReq) (resp *pbuser.SetUserStatusResp, err error) {
err = s.UserDatabase.SetUserStatus(ctx, req.StatusList) err = s.UserDatabase.SetUserStatus(ctx, req.StatusList)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, value := range req.StatusList {
list, err := s.UserDatabase.GetSubscribedList(ctx, value.UserID)
if err != nil {
return nil, err
}
for _, userID := range list {
tips := &sdkws.UserStatusChangeTips{
FromUserID: value.UserID,
ToUserID: userID,
Status: value.Status,
PlatformID: value.PlatformIDs[0],
}
s.userNotificationSender.UserStatusChangeNotification(ctx, tips)
}
}
return &pbuser.SetUserStatusResp{}, nil return &pbuser.SetUserStatusResp{}, nil
} }
// GetSubscribeUsersStatus Get the online status of subscribers.
func (s *userServer) GetSubscribeUsersStatus(ctx context.Context, req *pbuser.GetSubscribeUsersStatusReq) (*pbuser.GetSubscribeUsersStatusResp, error) {
userList, err := s.UserDatabase.GetAllSubscribeList(ctx, req.UserID)
if err != nil {
return nil, err
}
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, userList)
if err != nil {
return nil, err
}
return &pbuser.GetSubscribeUsersStatusResp{StatusList: onlineStatusList}, nil
}
+1 -1
View File
@@ -90,7 +90,7 @@ func InitMsgTool() (*MsgTool, error) {
tx.NewGorm(db), tx.NewGorm(db),
userMongoDB, userMongoDB,
) )
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase()) groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), nil)
conversationDatabase := controller.NewConversationDatabase( conversationDatabase := controller.NewConversationDatabase(
relation.NewConversationGorm(db), relation.NewConversationGorm(db),
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)), cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)),
+2 -1
View File
@@ -284,7 +284,8 @@ type notification struct {
GroupInfoSetAnnouncement NotificationConf `yaml:"groupInfoSetAnnouncement"` GroupInfoSetAnnouncement NotificationConf `yaml:"groupInfoSetAnnouncement"`
GroupInfoSetName NotificationConf `yaml:"groupInfoSetName"` GroupInfoSetName NotificationConf `yaml:"groupInfoSetName"`
////////////////////////user/////////////////////// ////////////////////////user///////////////////////
UserInfoUpdated NotificationConf `yaml:"userInfoUpdated"` UserInfoUpdated NotificationConf `yaml:"userInfoUpdated"`
UserStatusChanged NotificationConf `yaml:"userStatusChanged"`
//////////////////////friend/////////////////////// //////////////////////friend///////////////////////
FriendApplicationAdded NotificationConf `yaml:"friendApplicationAdded"` FriendApplicationAdded NotificationConf `yaml:"friendApplicationAdded"`
FriendApplicationApproved NotificationConf `yaml:"friendApplicationApproved"` FriendApplicationApproved NotificationConf `yaml:"friendApplicationApproved"`
+1
View File
@@ -78,6 +78,7 @@ func MsgDB2Pb(msgModel *unrelation.MsgDataModel) *sdkws.MsgData {
msg.SendTime = msgModel.SendTime msg.SendTime = msgModel.SendTime
msg.CreateTime = msgModel.CreateTime msg.CreateTime = msgModel.CreateTime
msg.Status = msgModel.Status msg.Status = msgModel.Status
msg.IsRead = msgModel.IsRead
msg.Options = msgModel.Options msg.Options = msgModel.Options
if msgModel.OfflinePush != nil { if msgModel.OfflinePush != nil {
msg.OfflinePushInfo = &sdkws.OfflinePushInfo{ msg.OfflinePushInfo = &sdkws.OfflinePushInfo{
+64 -20
View File
@@ -16,10 +16,10 @@ package cache
import ( import (
"context" "context"
"math/big"
"strings"
"time" "time"
"github.com/OpenIMSDK/tools/log"
"github.com/dtm-labs/rockscache" "github.com/dtm-labs/rockscache"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
@@ -33,7 +33,7 @@ const (
groupExpireTime = time.Second * 60 * 60 * 12 groupExpireTime = time.Second * 60 * 60 * 12
groupInfoKey = "GROUP_INFO:" groupInfoKey = "GROUP_INFO:"
groupMemberIDsKey = "GROUP_MEMBER_IDS:" groupMemberIDsKey = "GROUP_MEMBER_IDS:"
groupMembersHashKey = "GROUP_MEMBERS_HASH:" groupMembersHashKey = "GROUP_MEMBERS_HASH2:"
groupMemberInfoKey = "GROUP_MEMBER_INFO:" groupMemberInfoKey = "GROUP_MEMBER_INFO:"
joinedSuperGroupsKey = "JOIN_SUPER_GROUPS:" joinedSuperGroupsKey = "JOIN_SUPER_GROUPS:"
SuperGroupMemberIDsKey = "SUPER_GROUP_MEMBER_IDS:" SuperGroupMemberIDsKey = "SUPER_GROUP_MEMBER_IDS:"
@@ -96,6 +96,7 @@ type GroupCacheRedis struct {
mongoDB unrelationTb.SuperGroupModelInterface mongoDB unrelationTb.SuperGroupModelInterface
expireTime time.Duration expireTime time.Duration
rcClient *rockscache.Client rcClient *rockscache.Client
hashCode func(ctx context.Context, groupID string) (uint64, error)
} }
func NewGroupCacheRedis( func NewGroupCacheRedis(
@@ -104,13 +105,16 @@ func NewGroupCacheRedis(
groupMemberDB relationTb.GroupMemberModelInterface, groupMemberDB relationTb.GroupMemberModelInterface,
groupRequestDB relationTb.GroupRequestModelInterface, groupRequestDB relationTb.GroupRequestModelInterface,
mongoClient unrelationTb.SuperGroupModelInterface, mongoClient unrelationTb.SuperGroupModelInterface,
hashCode func(ctx context.Context, groupID string) (uint64, error),
opts rockscache.Options, opts rockscache.Options,
) GroupCache { ) GroupCache {
rcClient := rockscache.NewClient(rdb, opts) rcClient := rockscache.NewClient(rdb, opts)
return &GroupCacheRedis{ return &GroupCacheRedis{
rcClient: rcClient, expireTime: groupExpireTime, rcClient: rcClient, expireTime: groupExpireTime,
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB, groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
mongoDB: mongoClient, metaCache: NewMetaCacheRedis(rcClient), mongoDB: mongoClient,
hashCode: hashCode,
metaCache: NewMetaCacheRedis(rcClient),
} }
} }
@@ -290,22 +294,61 @@ func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache
// groupMembersHash. // groupMembersHash.
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) { func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
return getCache( return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) {
ctx, return g.hashCode(ctx, groupID)
g.rcClient, })
g.getGroupMembersHashKey(groupID),
g.expireTime, //return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime,
func(ctx context.Context) (uint64, error) { // func(ctx context.Context) (uint64, error) {
userIDs, err := g.GetGroupMemberIDs(ctx, groupID) // userIDs, err := g.GetGroupMemberIDs(ctx, groupID)
if err != nil { // if err != nil {
return 0, err // return 0, err
} // }
utils.Sort(userIDs, true) // log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "userIDs", userIDs)
bi := big.NewInt(0) // var members []*relationTb.GroupMemberModel
bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16) // if len(userIDs) > 0 {
return bi.Uint64(), nil // members, err = g.GetGroupMembersInfo(ctx, groupID, userIDs)
}, // if err != nil {
) // return 0, err
// }
// utils.Sort(userIDs, true)
// }
// memberMap := make(map[string]*relationTb.GroupMemberModel)
// for i, member := range members {
// memberMap[member.UserID] = members[i]
// }
// data := make([]string, 0, len(members)*11)
// for _, userID := range userIDs {
// member, ok := memberMap[userID]
// if !ok {
// continue
// }
// data = append(data,
// member.GroupID,
// member.UserID,
// member.Nickname,
// member.FaceURL,
// strconv.Itoa(int(member.RoleLevel)),
// strconv.FormatInt(member.JoinTime.UnixMilli(), 10),
// strconv.Itoa(int(member.JoinSource)),
// member.InviterUserID,
// member.OperatorUserID,
// strconv.FormatInt(member.MuteEndTime.UnixMilli(), 10),
// member.Ex,
// )
// }
// log.ZInfo(ctx, "hash data info", "userIDs.len", len(userIDs), "hash.data.len", len(data))
// log.ZInfo(ctx, "json hash data", "groupID", groupID, "data", data)
// val, err := json.Marshal(data)
// if err != nil {
// return 0, err
// }
// sum := md5.Sum(val)
// code := binary.BigEndian.Uint64(sum[:])
// log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "hashCode", code, "num", len(members))
// return code, nil
// },
//)
} }
func (g *GroupCacheRedis) GetGroupMemberHashMap( func (g *GroupCacheRedis) GetGroupMemberHashMap(
@@ -318,6 +361,7 @@ func (g *GroupCacheRedis) GetGroupMemberHashMap(
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.ZInfo(ctx, "GetGroupMemberHashMap", "groupID", groupID, "hash", hash)
num, err := g.GetGroupMemberNum(ctx, groupID) num, err := g.GetGroupMemberNum(ctx, groupID)
if err != nil { if err != nil {
return nil, err return nil, err
+77 -8
View File
@@ -21,6 +21,8 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/OpenIMSDK/protocol/constant"
"github.com/OpenIMSDK/protocol/user" "github.com/OpenIMSDK/protocol/user"
"github.com/OpenIMSDK/tools/errs" "github.com/OpenIMSDK/tools/errs"
@@ -37,6 +39,7 @@ const (
olineStatusKey = "ONLINE_STATUS:" olineStatusKey = "ONLINE_STATUS:"
userOlineStatusExpireTime = time.Second * 60 * 60 * 24 userOlineStatusExpireTime = time.Second * 60 * 60 * 24
statusMod = 501 statusMod = 501
platformID = "_PlatformIDSuffix"
) )
type UserCache interface { type UserCache interface {
@@ -92,6 +95,10 @@ func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string {
return userGlobalRecvMsgOptKey + userID return userGlobalRecvMsgOptKey + userID
} }
func (u *UserCacheRedis) getUserStatusHashKey(userID string, Id int32) string {
return userID + "_" + string(Id) + platformID
}
func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationTb.UserModel, err error) { func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationTb.UserModel, err error) {
return getCache( return getCache(
ctx, ctx,
@@ -177,9 +184,9 @@ func (u *UserCacheRedis) GetUserStatus(ctx context.Context, userIDs []string) ([
if err == redis.Nil { if err == redis.Nil {
// key or field does not exist // key or field does not exist
res = append(res, &user.OnlineStatus{ res = append(res, &user.OnlineStatus{
UserID: userID, UserID: userID,
Status: 0, Status: constant.Offline,
PlatformID: -1, PlatformIDs: nil,
}) })
continue continue
} else { } else {
@@ -211,12 +218,74 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, list []*user.OnlineS
if err != nil { if err != nil {
return errs.Wrap(err) return errs.Wrap(err)
} }
_, err = u.rdb.HSet(ctx, key, status.UserID, string(jsonData)).Result() if isNewKey == 0 {
if err != nil { _, err = u.rdb.HSet(ctx, key, status.UserID, string(jsonData)).Result()
return errs.Wrap(err) if err != nil {
} return errs.Wrap(err)
if isNewKey > 0 { }
u.rdb.Expire(ctx, key, userOlineStatusExpireTime) u.rdb.Expire(ctx, key, userOlineStatusExpireTime)
} else {
result, err := u.rdb.HGet(ctx, key, status.UserID).Result()
if err != nil {
return errs.Wrap(err)
}
var onlineStatus user.OnlineStatus
err = json.Unmarshal([]byte(result), &onlineStatus)
if err != nil {
return errs.Wrap(err)
}
onlineStatus.UserID = status.UserID
if status.Status == constant.Offline {
var newPlatformIDs []int32
for _, val := range onlineStatus.PlatformIDs {
if val != status.PlatformIDs[0] {
newPlatformIDs = append(newPlatformIDs, val)
}
}
if newPlatformIDs == nil {
onlineStatus.Status = constant.Offline
onlineStatus.PlatformIDs = nil
newjsonData, err := json.Marshal(&onlineStatus)
if err != nil {
return errs.Wrap(err)
}
_, err = u.rdb.HSet(ctx, key, status.UserID, string(newjsonData)).Result()
if err != nil {
return errs.Wrap(err)
}
} else {
onlineStatus.PlatformIDs = newPlatformIDs
newjsonData, err := json.Marshal(&onlineStatus)
if err != nil {
return errs.Wrap(err)
}
_, err = u.rdb.HSet(ctx, key, status.UserID, string(newjsonData)).Result()
if err != nil {
return errs.Wrap(err)
}
}
} else {
onlineStatus.Status = constant.Online
// Judging whether to be kicked out.
flag := false
for _, val := range onlineStatus.PlatformIDs {
if val == status.PlatformIDs[0] {
flag = true
break
}
}
if !flag {
onlineStatus.PlatformIDs = append(onlineStatus.PlatformIDs, status.PlatformIDs[0])
}
newjsonData, err := json.Marshal(&onlineStatus)
if err != nil {
return errs.Wrap(err)
}
_, err = u.rdb.HSet(ctx, key, status.UserID, string(newjsonData)).Result()
if err != nil {
return errs.Wrap(err)
}
}
} }
} }
return nil return nil
+3 -2
View File
@@ -153,7 +153,7 @@ func NewGroupDatabase(
return database return database
} }
func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database) GroupDatabase { func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database, hashCode func(ctx context.Context, groupID string) (uint64, error)) GroupDatabase {
rcOptions := rockscache.NewDefaultOptions() rcOptions := rockscache.NewDefaultOptions()
rcOptions.StrongConsistency = true rcOptions.StrongConsistency = true
rcOptions.RandomExpireAdjustment = 0.2 rcOptions.RandomExpireAdjustment = 0.2
@@ -170,6 +170,7 @@ func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.D
relation.NewGroupMemberDB(db), relation.NewGroupMemberDB(db),
relation.NewGroupRequest(db), relation.NewGroupRequest(db),
unrelation.NewSuperGroupMongoDriver(database), unrelation.NewSuperGroupMongoDriver(database),
hashCode,
rcOptions, rcOptions,
), ),
) )
@@ -315,7 +316,7 @@ func (g *groupDatabase) FindGroupMember(
userIDs []string, userIDs []string,
roleLevels []int32, roleLevels []int32,
) (totalGroupMembers []*relationTb.GroupMemberModel, err error) { ) (totalGroupMembers []*relationTb.GroupMemberModel, err error) {
if roleLevels == nil { if len(roleLevels) == 0 {
for _, groupID := range groupIDs { for _, groupID := range groupIDs {
groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs) groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
if err != nil { if err != nil {
+1 -1
View File
@@ -53,7 +53,7 @@ type UserDatabase interface {
CountTotal(ctx context.Context, before *time.Time) (int64, error) CountTotal(ctx context.Context, before *time.Time) (int64, error)
// CountRangeEverydayTotal Get the user increment in the range // CountRangeEverydayTotal Get the user increment in the range
CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error)
//SubscribeUsersStatus Subscribe a user's presence status // SubscribeUsersStatus Subscribe a user's presence status
SubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error SubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error
// UnsubscribeUsersStatus unsubscribe a user's presence status // UnsubscribeUsersStatus unsubscribe a user's presence status
UnsubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error UnsubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error
+1
View File
@@ -84,6 +84,7 @@ func NewMinio() (s3.Interface, error) {
init: false, init: false,
} }
if conf.SignEndpoint == "" || conf.SignEndpoint == conf.Endpoint { if conf.SignEndpoint == "" || conf.SignEndpoint == conf.Endpoint {
m.opts = opts
m.sign = m.core.Client m.sign = m.core.Client
} else { } else {
su, err := url.Parse(conf.SignEndpoint) su, err := url.Parse(conf.SignEndpoint)
+2 -2
View File
@@ -155,7 +155,7 @@ func (u *UserMongoDriver) RemoveSubscribedListFromUser(ctx context.Context, user
return errs.Wrap(err) return errs.Wrap(err)
} }
// GetAllSubscribeList Get all users subscribed by this user // GetAllSubscribeList Get all users subscribed by this user.
func (u *UserMongoDriver) GetAllSubscribeList(ctx context.Context, userID string) (userIDList []string, err error) { func (u *UserMongoDriver) GetAllSubscribeList(ctx context.Context, userID string) (userIDList []string, err error) {
var user unrelation.UserModel var user unrelation.UserModel
cursor := u.userCollection.FindOne( cursor := u.userCollection.FindOne(
@@ -168,7 +168,7 @@ func (u *UserMongoDriver) GetAllSubscribeList(ctx context.Context, userID string
return user.UserIDList, nil return user.UserIDList, nil
} }
// GetSubscribedList Get the user subscribed by those users // GetSubscribedList Get the user subscribed by those users.
func (u *UserMongoDriver) GetSubscribedList(ctx context.Context, userID string) (userIDList []string, err error) { func (u *UserMongoDriver) GetSubscribedList(ctx context.Context, userID string) (userIDList []string, err error) {
var user unrelation.UserModel var user unrelation.UserModel
cursor := u.userCollection.FindOne( cursor := u.userCollection.FindOne(
+4 -2
View File
@@ -56,7 +56,8 @@ func newContentTypeConf() map[int32]config.NotificationConf {
constant.GroupInfoSetAnnouncementNotification: config.Config.Notification.GroupInfoSetAnnouncement, constant.GroupInfoSetAnnouncementNotification: config.Config.Notification.GroupInfoSetAnnouncement,
constant.GroupInfoSetNameNotification: config.Config.Notification.GroupInfoSetName, constant.GroupInfoSetNameNotification: config.Config.Notification.GroupInfoSetName,
// user // user
constant.UserInfoUpdatedNotification: config.Config.Notification.UserInfoUpdated, constant.UserInfoUpdatedNotification: config.Config.Notification.UserInfoUpdated,
constant.UserStatusChangeNotification: config.Config.Notification.UserStatusChanged,
// friend // friend
constant.FriendApplicationNotification: config.Config.Notification.FriendApplicationAdded, constant.FriendApplicationNotification: config.Config.Notification.FriendApplicationAdded,
constant.FriendApplicationApprovedNotification: config.Config.Notification.FriendApplicationApproved, constant.FriendApplicationApprovedNotification: config.Config.Notification.FriendApplicationApproved,
@@ -102,7 +103,8 @@ func newSessionTypeConf() map[int32]int32 {
constant.GroupInfoSetAnnouncementNotification: constant.SuperGroupChatType, constant.GroupInfoSetAnnouncementNotification: constant.SuperGroupChatType,
constant.GroupInfoSetNameNotification: constant.SuperGroupChatType, constant.GroupInfoSetNameNotification: constant.SuperGroupChatType,
// user // user
constant.UserInfoUpdatedNotification: constant.SingleChatType, constant.UserInfoUpdatedNotification: constant.SingleChatType,
constant.UserStatusChangeNotification: constant.SingleChatType,
// friend // friend
constant.FriendApplicationNotification: constant.SingleChatType, constant.FriendApplicationNotification: constant.SingleChatType,
constant.FriendApplicationApprovedNotification: constant.SingleChatType, constant.FriendApplicationApprovedNotification: constant.SingleChatType,
+19 -19
View File
@@ -136,7 +136,7 @@ func (f *FriendNotificationSender) FriendApplicationAddNotification(
return f.Notification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &tips) return f.Notification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &tips)
} }
func (c *FriendNotificationSender) FriendApplicationAgreedNotification( func (f *FriendNotificationSender) FriendApplicationAgreedNotification(
ctx context.Context, ctx context.Context,
req *pbFriend.RespondFriendApplyReq, req *pbFriend.RespondFriendApplyReq,
) error { ) error {
@@ -144,10 +144,10 @@ func (c *FriendNotificationSender) FriendApplicationAgreedNotification(
FromUserID: req.FromUserID, FromUserID: req.FromUserID,
ToUserID: req.ToUserID, ToUserID: req.ToUserID,
}, HandleMsg: req.HandleMsg} }, HandleMsg: req.HandleMsg}
return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &tips) return f.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &tips)
} }
func (c *FriendNotificationSender) FriendApplicationRefusedNotification( func (f *FriendNotificationSender) FriendApplicationRefusedNotification(
ctx context.Context, ctx context.Context,
req *pbFriend.RespondFriendApplyReq, req *pbFriend.RespondFriendApplyReq,
) error { ) error {
@@ -155,15 +155,15 @@ func (c *FriendNotificationSender) FriendApplicationRefusedNotification(
FromUserID: req.FromUserID, FromUserID: req.FromUserID,
ToUserID: req.ToUserID, ToUserID: req.ToUserID,
}, HandleMsg: req.HandleMsg} }, HandleMsg: req.HandleMsg}
return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &tips) return f.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &tips)
} }
func (c *FriendNotificationSender) FriendAddedNotification( func (f *FriendNotificationSender) FriendAddedNotification(
ctx context.Context, ctx context.Context,
operationID, opUserID, fromUserID, toUserID string, operationID, opUserID, fromUserID, toUserID string,
) error { ) error {
tips := sdkws.FriendAddedTips{Friend: &sdkws.FriendInfo{}, OpUser: &sdkws.PublicUserInfo{}} tips := sdkws.FriendAddedTips{Friend: &sdkws.FriendInfo{}, OpUser: &sdkws.PublicUserInfo{}}
user, err := c.getUsersInfo(ctx, []string{opUserID}) user, err := f.getUsersInfo(ctx, []string{opUserID})
if err != nil { if err != nil {
return err return err
} }
@@ -171,52 +171,52 @@ func (c *FriendNotificationSender) FriendAddedNotification(
tips.OpUser.Ex = user[0].GetEx() tips.OpUser.Ex = user[0].GetEx()
tips.OpUser.Nickname = user[0].GetNickname() tips.OpUser.Nickname = user[0].GetNickname()
tips.OpUser.FaceURL = user[0].GetFaceURL() tips.OpUser.FaceURL = user[0].GetFaceURL()
friends, err := c.db.FindFriendsWithError(ctx, fromUserID, []string{toUserID}) friends, err := f.db.FindFriendsWithError(ctx, fromUserID, []string{toUserID})
if err != nil { if err != nil {
return err return err
} }
tips.Friend, err = convert.FriendDB2Pb(ctx, friends[0], c.getUsersInfoMap) tips.Friend, err = convert.FriendDB2Pb(ctx, friends[0], f.getUsersInfoMap)
if err != nil { if err != nil {
return err return err
} }
return c.Notification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &tips) return f.Notification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &tips)
} }
func (c *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *pbFriend.DeleteFriendReq) error { func (f *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *pbFriend.DeleteFriendReq) error {
tips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{ tips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{
FromUserID: req.OwnerUserID, FromUserID: req.OwnerUserID,
ToUserID: req.FriendUserID, ToUserID: req.FriendUserID,
}} }}
return c.Notification(ctx, req.OwnerUserID, req.FriendUserID, constant.FriendDeletedNotification, &tips) return f.Notification(ctx, req.OwnerUserID, req.FriendUserID, constant.FriendDeletedNotification, &tips)
} }
func (c *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Context, fromUserID, toUserID string) error { func (f *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Context, fromUserID, toUserID string) error {
tips := sdkws.FriendInfoChangedTips{FromToUserID: &sdkws.FromToUserID{}} tips := sdkws.FriendInfoChangedTips{FromToUserID: &sdkws.FromToUserID{}}
tips.FromToUserID.FromUserID = fromUserID tips.FromToUserID.FromUserID = fromUserID
tips.FromToUserID.ToUserID = toUserID tips.FromToUserID.ToUserID = toUserID
return c.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips) return f.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips)
} }
func (c *FriendNotificationSender) BlackAddedNotification(ctx context.Context, req *pbFriend.AddBlackReq) error { func (f *FriendNotificationSender) BlackAddedNotification(ctx context.Context, req *pbFriend.AddBlackReq) error {
tips := sdkws.BlackAddedTips{FromToUserID: &sdkws.FromToUserID{}} tips := sdkws.BlackAddedTips{FromToUserID: &sdkws.FromToUserID{}}
tips.FromToUserID.FromUserID = req.OwnerUserID tips.FromToUserID.FromUserID = req.OwnerUserID
tips.FromToUserID.ToUserID = req.BlackUserID tips.FromToUserID.ToUserID = req.BlackUserID
return c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackAddedNotification, &tips) return f.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackAddedNotification, &tips)
} }
func (c *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, req *pbFriend.RemoveBlackReq) { func (f *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, req *pbFriend.RemoveBlackReq) {
blackDeletedTips := sdkws.BlackDeletedTips{FromToUserID: &sdkws.FromToUserID{ blackDeletedTips := sdkws.BlackDeletedTips{FromToUserID: &sdkws.FromToUserID{
FromUserID: req.OwnerUserID, FromUserID: req.OwnerUserID,
ToUserID: req.BlackUserID, ToUserID: req.BlackUserID,
}} }}
c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackDeletedNotification, &blackDeletedTips) f.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackDeletedNotification, &blackDeletedTips)
} }
func (c *FriendNotificationSender) FriendInfoUpdatedNotification( func (f *FriendNotificationSender) FriendInfoUpdatedNotification(
ctx context.Context, ctx context.Context,
changedUserID string, changedUserID string,
needNotifiedUserID string, needNotifiedUserID string,
) { ) {
tips := sdkws.UserInfoUpdatedTips{UserID: changedUserID} tips := sdkws.UserInfoUpdatedTips{UserID: changedUserID}
c.Notification(ctx, mcontext.GetOpUserID(ctx), needNotifiedUserID, constant.FriendInfoUpdatedNotification, &tips) f.Notification(ctx, mcontext.GetOpUserID(ctx), needNotifiedUserID, constant.FriendInfoUpdatedNotification, &tips)
} }
+105
View File
@@ -0,0 +1,105 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package notification
import (
"context"
"github.com/OpenIMSDK/protocol/constant"
"github.com/OpenIMSDK/protocol/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
relationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
)
type UserNotificationSender struct {
*rpcclient.NotificationSender
getUsersInfo func(ctx context.Context, userIDs []string) ([]CommonUser, error)
// db controller
db controller.UserDatabase
}
type userNotificationSenderOptions func(*UserNotificationSender)
func WithUserDB(db controller.UserDatabase) userNotificationSenderOptions {
return func(u *UserNotificationSender) {
u.db = db
}
}
func WithUserFunc(
fn func(ctx context.Context, userIDs []string) (users []*relationTb.UserModel, err error),
) userNotificationSenderOptions {
return func(u *UserNotificationSender) {
f := func(ctx context.Context, userIDs []string) (result []CommonUser, err error) {
users, err := fn(ctx, userIDs)
if err != nil {
return nil, err
}
for _, user := range users {
result = append(result, user)
}
return result, nil
}
u.getUsersInfo = f
}
}
func NewUserNotificationSender(
msgRpcClient *rpcclient.MessageRpcClient,
opts ...userNotificationSenderOptions,
) *UserNotificationSender {
f := &UserNotificationSender{
NotificationSender: rpcclient.NewNotificationSender(rpcclient.WithRpcClient(msgRpcClient)),
}
for _, opt := range opts {
opt(f)
}
return f
}
func (u *UserNotificationSender) getUsersInfoMap(
ctx context.Context,
userIDs []string,
) (map[string]*sdkws.UserInfo, error) {
users, err := u.getUsersInfo(ctx, userIDs)
if err != nil {
return nil, err
}
result := make(map[string]*sdkws.UserInfo)
for _, user := range users {
result[user.GetUserID()] = user.(*sdkws.UserInfo)
}
return result, nil
}
func (u *UserNotificationSender) getFromToUserNickname(
ctx context.Context,
fromUserID, toUserID string,
) (string, string, error) {
users, err := u.getUsersInfoMap(ctx, []string{fromUserID, toUserID})
if err != nil {
return "", "", nil
}
return users[fromUserID].Nickname, users[toUserID].Nickname, nil
}
func (u *UserNotificationSender) UserStatusChangeNotification(
ctx context.Context,
tips *sdkws.UserStatusChangeTips,
) error {
return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserStatusChangeNotification, tips)
}
+1 -1
View File
@@ -158,6 +158,6 @@ func (u *UserRpcClient) GetAllUserIDs(ctx context.Context, pageNumber, showNumbe
} }
func (u *UserRpcClient) SetUserStatus(ctx context.Context, userID string, status int32, platformID int) error { func (u *UserRpcClient) SetUserStatus(ctx context.Context, userID string, status int32, platformID int) error {
_, err := u.Client.SetUserStatus(ctx, &user.SetUserStatusReq{StatusList: []*user.OnlineStatus{{UserID: userID, Status: status, PlatformID: int32(platformID)}}}) _, err := u.Client.SetUserStatus(ctx, &user.SetUserStatusReq{StatusList: []*user.OnlineStatus{{UserID: userID, Status: status, PlatformIDs: []int32{int32(platformID)}}}})
return err return err
} }
+13 -1
View File
@@ -54,7 +54,19 @@ fi
cd $OPENIM_ROOT cd $OPENIM_ROOT
# CPU core number # CPU core number
cpu_count=$(lscpu | grep -e '^CPU(s):' | awk '{print $2}') # Check the system type
system_type=$(uname)
if [[ "$system_type" == "Darwin" ]]; then
# macOS (using sysctl)
cpu_count=$(sysctl -n hw.ncpu)
elif [[ "$system_type" == "Linux" ]]; then
# Linux (using lscpu)
cpu_count=$(lscpu --parse | grep -E '^([^#].*,){3}[^#]' | sort -u | wc -l)
else
echo "Unsupported operating system: $system_type"
exit 1
fi
echo -e "${GREEN_PREFIX}======> cpu_count=$cpu_count${COLOR_SUFFIX}" echo -e "${GREEN_PREFIX}======> cpu_count=$cpu_count${COLOR_SUFFIX}"
# Count the number of concurrent compilations (half the number of cpus) # Count the number of concurrent compilations (half the number of cpus)
+1 -1
View File
@@ -58,7 +58,7 @@ done
#Check launched service process #Check launched service process
check=$(ps aux | grep -w ./${openim_msgtransfer} | grep -v grep | wc -l) check=$(ps aux | grep -w ./${openim_msgtransfer} | grep -v grep | wc -l)
if [ $check -eq ${msg_transfer_service_num} ]; then if [ $check -ge ${msg_transfer_service_num} ]; then
echo -e ${GREEN_PREFIX}"none port has been listening,belongs service is openImMsgTransfer"${COLOR_SUFFIX} echo -e ${GREEN_PREFIX}"none port has been listening,belongs service is openImMsgTransfer"${COLOR_SUFFIX}
else else
echo $check ${msg_transfer_service_num} echo $check ${msg_transfer_service_num}
+9
View File
@@ -30,6 +30,15 @@ need_to_start_server_shell=(
${SCRIPTS_ROOT}/start_cron.sh ${SCRIPTS_ROOT}/start_cron.sh
) )
component_check=start_component_check.sh
chmod +x $SCRIPTS_ROOT/$component_check
$SCRIPTS_ROOT/$component_check
if [ $? -ne 0 ]; then
# Print error message and exit
echo "${BOLD_PREFIX}${RED_PREFIX}Error executing ${component_check}. Exiting...${COLOR_SUFFIX}"
exit -1
fi
#fixme The 10 second delay to start the project is for the docker-compose one-click to start openIM when the infrastructure dependencies are not started #fixme The 10 second delay to start the project is for the docker-compose one-click to start openIM when the infrastructure dependencies are not started
sleep 10 sleep 10
+1 -1
View File
@@ -183,7 +183,7 @@ go.test.cover: go.test.junit-report
## go.format: Run unit test and format codes ## go.format: Run unit test and format codes
.PHONY: go.format .PHONY: go.format
go.format: tools.verify.golines tools.verify.goimports go.format: tools.verify.golines tools.verify.goimports
@echo "===========> Formating codes" @echo "===========> Formatting codes"
@$(FIND) -type f -name '*.go' -not -name '*pb*' | $(XARGS) gofmt -s -w @$(FIND) -type f -name '*.go' -not -name '*pb*' | $(XARGS) gofmt -s -w
@$(FIND) -type f -name '*.go' -not -name '*pb*' | $(XARGS) $(TOOLS_DIR)/goimports -w -local $(ROOT_PACKAGE) @$(FIND) -type f -name '*.go' -not -name '*pb*' | $(XARGS) $(TOOLS_DIR)/goimports -w -local $(ROOT_PACKAGE)
@$(FIND) -type f -name '*.go' -not -name '*pb*' | $(XARGS) $(TOOLS_DIR)/golines -w --max-len=200 --reformat-tags --shorten-comments --ignore-generated . @$(FIND) -type f -name '*.go' -not -name '*pb*' | $(XARGS) $(TOOLS_DIR)/golines -w --max-len=200 --reformat-tags --shorten-comments --ignore-generated .
+6 -6
View File
@@ -50,11 +50,11 @@ if [ ${#rpc_ports[@]} -ne ${#ws_ports[@]} ]; then
fi fi
#Check if the service exists #Check if the service exists
#If it is exists,kill this process #If it is exists,kill this process
check=$(ps aux | grep -w ./${openim_msggateway} | grep -v grep | wc -l) #check=$(ps aux | grep -w ./${openim_msggateway} | grep -v grep | wc -l)
if [ $check -ge 1 ]; then #if [ $check -ge 1 ]; then
oldPid=$(ps aux | grep -w ./${openim_msggateway} | grep -v grep | awk '{print $2}') # oldPid=$(ps aux | grep -w ./${openim_msggateway} | grep -v grep | awk '{print $2}')
kill -9 ${oldPid} # kill -9 ${oldPid}
fi #fi
#Waiting port recycling #Waiting port recycling
sleep 1 sleep 1
cd ${msg_gateway_binary_root} cd ${msg_gateway_binary_root}
@@ -78,5 +78,5 @@ if [ $check -ge 1 ]; then
echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allNewPid}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allNewPid}${COLOR_SUFFIX}
echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX}
else else
echo -e ${BACKGROUND_GREEN}${openim_msggateway}${COLOR_SUFFIX}${RED_PREFIX}"\n SERVICE START ERROR, PLEASE CHECK openIM.log"${COLOR_SUFFIX} exit -1
fi fi
+9 -9
View File
@@ -37,12 +37,12 @@ prome_ports=($ports_array)
#Check if the service exists #Check if the service exists
#If it is exists,kill this process #If it is exists,kill this process
check=`ps | grep -w ./${openim_msgtransfer} | grep -v grep| wc -l` #check=`ps | grep -w ./${openim_msgtransfer} | grep -v grep| wc -l`
if [ $check -ge 1 ] #if [ $check -ge 1 ]
then #then
oldPid=`ps | grep -w ./${openim_msgtransfer} | grep -v grep|awk '{print $2}'` #oldPid=`ps | grep -w ./${openim_msgtransfer} | grep -v grep|awk '{print $2}'`
kill -9 $oldPid # kill -9 $oldPid
fi #fi
#Waiting port recycling #Waiting port recycling
sleep 1 sleep 1
@@ -58,15 +58,15 @@ for ((i = 0; i < ${msg_transfer_service_num}; i++)); do
done done
#Check launched service process #Check launched service process
check=`ps | grep -w ./${openim_msgtransfer} | grep -v grep| wc -l` check=`ps -axu| grep -w ./${openim_msgtransfer} | grep -v grep| wc -l`
if [ $check -ge 1 ] if [ $check -ge 1 ]
then then
newPid=`ps | grep -w ./${openim_msgtransfer} | grep -v grep|awk '{print $2}'` newPid=`ps -axu| grep -w ./${openim_msgtransfer} | grep -v grep|awk '{print $2}'`
allPorts="" allPorts=""
echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS "${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS "${COLOR_SUFFIX}
echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${openim_msgtransfer}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${openim_msgtransfer}${COLOR_SUFFIX}
echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX}
echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX}
else else
echo -e ${BACKGROUND_GREEN}${openim_msgtransfer}${COLOR_SUFFIX}${RED_PREFIX}"\n SERVICE START ERROR, PLEASE CHECK openIM.log"${COLOR_SUFFIX} exit -1
fi fi
+19 -1
View File
@@ -40,6 +40,19 @@ declare -A supported_architectures=(
["darwin-x86_64"]="_output/bin/platforms/darwin/amd64" # Alias for darwin-amd64 ["darwin-x86_64"]="_output/bin/platforms/darwin/amd64" # Alias for darwin-amd64
) )
declare -A supported_architectures_tools=(
["linux-amd64"]="_output/bin-tools/platforms/linux/amd64"
["linux-arm64"]="_output/bin-tools/platforms/linux/arm64"
["linux-mips64"]="_output/bin-tools/platforms/linux/mips64"
["linux-mips64le"]="_output/bin-tools/platforms/linux/mips64le"
["linux-ppc64le"]="_output/bin-tools/platforms/linux/ppc64le"
["linux-s390x"]="_output/bin-tools/platforms/linux/s390x"
["darwin-amd64"]="_output/bin-tools/platforms/darwin/amd64"
["windows-amd64"]="_output/bin-tools/platforms/windows/amd64"
["linux-x86_64"]="_output/bin-tools/platforms/linux/amd64" # Alias for linux-amd64
["darwin-x86_64"]="_output/bin-tools/platforms/darwin/amd64" # Alias for darwin-amd64
)
# Check if the architecture and version are supported # Check if the architecture and version are supported
if [[ -z ${supported_architectures["$version-$architecture"]} ]]; then if [[ -z ${supported_architectures["$version-$architecture"]} ]]; then
echo -e "${BLUE_PREFIX}================> Unsupported architecture: $architecture or version: $version${COLOR_SUFFIX}" echo -e "${BLUE_PREFIX}================> Unsupported architecture: $architecture or version: $version${COLOR_SUFFIX}"
@@ -50,6 +63,7 @@ echo -e "${BLUE_PREFIX}================> Architecture: $architecture${COLOR_SUFF
# Set the BIN_DIR based on the architecture and version # Set the BIN_DIR based on the architecture and version
BIN_DIR=${supported_architectures["$version-$architecture"]} BIN_DIR=${supported_architectures["$version-$architecture"]}
BIN_DIR_TOOLS=${supported_architectures_tools["$version-$architecture"]}
echo -e "${BLUE_PREFIX}================> BIN_DIR: $OPENIM_ROOT/$BIN_DIR${COLOR_SUFFIX}" echo -e "${BLUE_PREFIX}================> BIN_DIR: $OPENIM_ROOT/$BIN_DIR${COLOR_SUFFIX}"
@@ -84,6 +98,10 @@ config_path="$OPENIM_ROOT/config/config.yaml"
configfile_path="$OPENIM_ROOT/config" configfile_path="$OPENIM_ROOT/config"
log_path="$OPENIM_ROOT/log" log_path="$OPENIM_ROOT/log"
component_check="component"
component_check_binary_root="$OPENIM_ROOT/$BIN_DIR_TOOLS"
# servicefile dir path # servicefile dir path
service_source_root=( service_source_root=(
# api service file # api service file
@@ -120,4 +138,4 @@ service_names=(
"${msg_name}" "${msg_name}"
"${push_name}" "${push_name}"
# "${sdk_server_name}" # "${sdk_server_name}"
) )
+8 -8
View File
@@ -44,11 +44,11 @@ prome_ports=($ports_array)
#Check if the service exists #Check if the service exists
#If it is exists,kill this process #If it is exists,kill this process
check=$(ps | grep -w ./${push_name} | grep -v grep | wc -l) #check=$(ps | grep -w ./${push_name} | grep -v grep | wc -l)
if [ $check -ge 1 ]; then #if [ $check -ge 1 ]; then
oldPid=$(ps | grep -w ./${push_name} | grep -v grep | awk '{print $2}') # oldPid=$(ps | grep -w ./${push_name} | grep -v grep | awk '{print $2}')
kill -9 $oldPid # kill -9 $oldPid
fi #fi
#Waiting port recycling #Waiting port recycling
sleep 1 sleep 1
cd ${push_binary_root} cd ${push_binary_root}
@@ -60,9 +60,9 @@ done
sleep 3 sleep 3
#Check launched service process #Check launched service process
check=$(ps | grep -w ./${push_name} | grep -v grep | wc -l) check=$(ps -axu| grep -w ./${push_name} | grep -v grep | wc -l)
if [ $check -ge 1 ]; then if [ $check -ge 1 ]; then
newPid=$(ps | grep -w ./${push_name} | grep -v grep | awk '{print $2}') newPid=$(ps -axu| grep -w ./${push_name} | grep -v grep | awk '{print $2}')
ports=$(netstat -netulp | grep -w ${newPid} | awk '{print $4}' | awk -F '[:]' '{print $NF}') ports=$(netstat -netulp | grep -w ${newPid} | awk '{print $4}' | awk -F '[:]' '{print $NF}')
allPorts="" allPorts=""
@@ -74,5 +74,5 @@ if [ $check -ge 1 ]; then
echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX}
echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX}
else else
echo -e ${BACKGROUND_GREEN}${push_name}${COLOR_SUFFIX}${RED_PREFIX}"\n SERVICE START ERROR, PLEASE CHECK openIM.log"${COLOR_SUFFIX} exit -1
fi fi
+14 -1
View File
@@ -77,6 +77,19 @@ need_to_start_server_shell=(
start_cron.sh start_cron.sh
) )
component_check=start_component_check.sh
echo -e ""
chmod +x $component_check
echo -e "=========> ${BACKGROUND_GREEN}Executing ${component_check}...${COLOR_SUFFIX}"
echo -e ""
./$component_check
if [ $? -ne 0 ]; then
# Print error message and exit
echo -e "${RED_PREFIX}${BOLD_PREFIX}Error executing ${component_check}. Exiting...${COLOR_SUFFIX}"
exit -1
fi
# Loop through the script names and execute them # Loop through the script names and execute them
for i in ${need_to_start_server_shell[*]}; do for i in ${need_to_start_server_shell[*]}; do
chmod +x $i chmod +x $i
@@ -91,7 +104,7 @@ for i in ${need_to_start_server_shell[*]}; do
# Check if the script executed successfully # Check if the script executed successfully
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
# Print error message and exit # Print error message and exit
echo "${BOLD_PREFIX}${RED_PREFIX}Error executing ${i}. Exiting...${COLOR_SUFFIX}" echo -e "${RED_PREFIX}${BOLD_PREFIX}Error executing ${i}. Exiting(please check open-im-server/logs/openIM.log)... ${COLOR_SUFFIX}"
exit -1 exit -1
fi fi
done done
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Copyright © 2023 OpenIM. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#Include shell font styles and some basic information
SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
#Include shell font styles and some basic information
source $SCRIPTS_ROOT/style_info.sh
source $SCRIPTS_ROOT/path_info.sh
source $SCRIPTS_ROOT/function.sh
echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}"
echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}"
echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}"
bin_dir="$BIN_DIR"
logs_dir="$OPENIM_ROOT/logs"
cd ${component_check_binary_root}
echo -e "${YELLOW_PREFIX}=======>$PWD${COLOR_SUFFIX}"
cmd="./${component_check}"
echo "==========================start components checking===========================">>$OPENIM_ROOT/logs/openIM.log
$cmd
if [ $? -ne 0 ]; then
exit 1
fi
+8 -8
View File
@@ -35,11 +35,11 @@ logs_dir="$OPENIM_ROOT/logs"
#Check if the service exists #Check if the service exists
#If it is exists,kill this process #If it is exists,kill this process
check=`ps | grep -w ./${cron_task_name} | grep -v grep| wc -l` check=`ps | grep -w ./${cron_task_name} | grep -v grep| wc -l`
if [ $check -ge 1 ] #if [ $check -ge 1 ]
then #then
oldPid=`ps | grep -w ./${cron_task_name} | grep -v grep|awk '{print $2}'` #oldPid=`ps | grep -w ./${cron_task_name} | grep -v grep|awk '{print $2}'`
kill -9 $oldPid # kill -9 $oldPid
fi #fi
#Waiting port recycling #Waiting port recycling
sleep 1 sleep 1
@@ -50,15 +50,15 @@ nohup ./${cron_task_name} >>$OPENIM_ROOT/logs/openIM.log 2>&1 &
#done #done
#Check launched service process #Check launched service process
check=`ps | grep -w ./${cron_task_name} | grep -v grep| wc -l` check=`ps -axu| grep -w ./${cron_task_name} | grep -v grep| wc -l`
if [ $check -ge 1 ] if [ $check -ge 1 ]
then then
newPid=`ps | grep -w ./${cron_task_name} | grep -v grep|awk '{print $2}'` newPid=`ps -axu| grep -w ./${cron_task_name} | grep -v grep|awk '{print $2}'`
allPorts="" allPorts=""
echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS "${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS "${COLOR_SUFFIX}
echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${cron_task_name}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${cron_task_name}${COLOR_SUFFIX}
echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX}
echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX} echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX}
else else
echo -e ${BACKGROUND_GREEN}${cron_task_name}${COLOR_SUFFIX}${RED_PREFIX}"\n SERVICE START ERROR, PLEASE CHECK openIM.log"${COLOR_SUFFIX} exit -1
fi fi
+8 -8
View File
@@ -78,14 +78,14 @@ for ((i = 0; i < ${#service_filename[*]}; i++)); do
service_name="ps |grep -w ${service_filename[$i]} |grep -v grep" service_name="ps |grep -w ${service_filename[$i]} |grep -v grep"
count="${service_name}| wc -l" count="${service_name}| wc -l"
if [ $(eval ${count}) -gt 0 ]; then # if [ $(eval ${count}) -gt 0 ]; then
pid="${service_name}| awk '{print \$2}'" # pid="${service_name}| awk '{print \$2}'"
echo "${service_filename[$i]} service has been started,pid:$(eval $pid)" # echo "${service_filename[$i]} service has been started,pid:$(eval $pid)"
echo "killing the service ${service_filename[$i]} pid:$(eval $pid)" # echo "killing the service ${service_filename[$i]} pid:$(eval $pid)"
#kill the service that existed # #kill the service that existed
kill -9 $(eval $pid) # kill -9 $(eval $pid)
sleep 0.5 # sleep 0.5
fi # fi
cd $OPENIM_ROOT cd $OPENIM_ROOT
cd $BIN_DIR cd $BIN_DIR
# Get the rpc port in the configuration file # Get the rpc port in the configuration file
+1
View File
@@ -61,6 +61,7 @@ function style-info() {
BACKGROUND_LIGHT_PURPLE="\033[105m" # Light purple background BACKGROUND_LIGHT_PURPLE="\033[105m" # Light purple background
BACKGROUND_LIGHT_SKY_BLUE="\033[106m" # Light sky blue background BACKGROUND_LIGHT_SKY_BLUE="\033[106m" # Light sky blue background
BACKGROUND_LIGHT_WHITE="\033[107m" # Light white background BACKGROUND_LIGHT_WHITE="\033[107m" # Light white background
} }
style-info style-info
+3
View File
@@ -0,0 +1,3 @@
module github.com/OpenIMSDK/Open-IM-Server/tools/component
go 1.19
+312
View File
@@ -0,0 +1,312 @@
package main
import (
"context"
"database/sql"
"fmt"
"net"
"net/url"
"os"
"strings"
"time"
"github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/utils"
"github.com/Shopify/sarama"
"github.com/go-zookeeper/zk"
"github.com/minio/minio-go/v7"
"github.com/redis/go-redis/v9"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
"gopkg.in/yaml.v3"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/minio/minio-go/v7/pkg/credentials"
)
const (
cfgPath = "../../../../../config/config.yaml"
minioHealthCheckDuration = 1
maxRetry = 100
componentStartErrCode = 6000
configErrCode = 6001
)
var (
ErrComponentStart = errs.NewCodeError(componentStartErrCode, "ComponentStartErr")
ErrConfig = errs.NewCodeError(configErrCode, "Config file is incorrect")
)
func initCfg() error {
data, err := os.ReadFile(cfgPath)
if err != nil {
return err
}
if err = yaml.Unmarshal(data, &config.Config); err != nil {
return err
}
return nil
}
func main() {
err := initCfg()
if err != nil {
fmt.Printf("Read config failed: %v", err.Error())
}
for i := 0; i < maxRetry; i++ {
if i != 0 {
time.Sleep(3 * time.Second)
}
fmt.Printf("Checking components Round %v......\n", i+1)
// Check MySQL
if err := checkMysql(); err != nil {
errorPrint(fmt.Sprintf("Starting Mysql failed: %v. Please make sure your mysql service has started", err.Error()))
continue
} else {
successPrint(fmt.Sprint("Mysql starts successfully"))
}
// Check MongoDB
if err := checkMongo(); err != nil {
errorPrint(fmt.Sprintf("Starting Mongo failed: %v. Please make sure your monngo service has started", err.Error()))
continue
} else {
successPrint(fmt.Sprint("Mongo starts successfully"))
}
// Check Minio
if err := checkMinio(); err != nil {
if index := strings.Index(err.Error(), utils.IntToString(configErrCode)); index != -1 {
successPrint(fmt.Sprint("Minio starts successfully"))
warningPrint(fmt.Sprintf("%v. Please modify your config file", err.Error()))
} else {
errorPrint(fmt.Sprintf("Starting Minio failed: %v. Please make sure your Minio service has started", err.Error()))
continue
}
} else {
successPrint(fmt.Sprint("Minio starts successfully"))
}
// Check Redis
if err := checkRedis(); err != nil {
errorPrint(fmt.Sprintf("Starting Redis failed: %v.Please make sure your Redis service has started", err.Error()))
continue
} else {
successPrint(fmt.Sprint("Redis starts successfully"))
}
// Check Zookeeper
if err := checkZookeeper(); err != nil {
errorPrint(fmt.Sprintf("Starting Zookeeper failed: %v.Please make sure your Zookeeper service has started", err.Error()))
continue
} else {
successPrint(fmt.Sprint("Zookeeper starts successfully"))
}
// Check Kafka
if err := checkKafka(); err != nil {
errorPrint(fmt.Sprintf("Starting Kafka failed: %v.Please make sure your Kafka service has started", err.Error()))
continue
} else {
successPrint(fmt.Sprint("Kafka starts successfully"))
}
successPrint(fmt.Sprint("All components starts successfully"))
os.Exit(0)
}
os.Exit(1)
}
func exactIP(urll string) string {
u, _ := url.Parse(urll)
host, _, err := net.SplitHostPort(u.Host)
if err != nil {
host = u.Host
}
if strings.HasSuffix(host, ":") {
host = host[0 : len(host)-1]
}
return host
}
func checkMysql() error {
var sqlDB *sql.DB
defer func() {
if sqlDB != nil {
sqlDB.Close()
}
}()
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=true&loc=Local",
config.Config.Mysql.Username, config.Config.Mysql.Password, config.Config.Mysql.Address[0], "mysql")
db, err := gorm.Open(mysql.Open(dsn), nil)
if err != nil {
return err
} else {
sqlDB, err = db.DB()
err = sqlDB.Ping()
if err != nil {
return err
}
}
return nil
}
func checkMongo() error {
var client *mongo.Client
defer func() {
if client != nil {
client.Disconnect(context.TODO())
}
}()
mongodbHosts := ""
for i, v := range config.Config.Mongo.Address {
if i == len(config.Config.Mongo.Address)-1 {
mongodbHosts += v
} else {
mongodbHosts += v + ","
}
}
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(
fmt.Sprintf("mongodb://%v:%v@%v/?authSource=admin",
config.Config.Mongo.Username, config.Config.Mongo.Password, mongodbHosts)))
if err != nil {
return err
} else {
err = client.Ping(context.TODO(), &readpref.ReadPref{})
if err != nil {
return err
}
}
return nil
}
func checkMinio() error {
if config.Config.Object.Enable == "minio" {
conf := config.Config.Object.Minio
u, _ := url.Parse(conf.Endpoint)
minioClient, err := minio.New(u.Host, &minio.Options{
Creds: credentials.NewStaticV4(conf.AccessKeyID, conf.SecretAccessKey, ""),
Secure: u.Scheme == "https",
})
if err != nil {
return err
}
cancel, err := minioClient.HealthCheck(time.Duration(minioHealthCheckDuration) * time.Second)
defer func() {
if cancel != nil {
cancel()
}
}()
if err != nil {
return err
} else {
if minioClient.IsOffline() {
return ErrComponentStart.Wrap("Minio server is offline")
}
}
if exactIP(config.Config.Object.ApiURL) == "127.0.0.1" || exactIP(config.Config.Object.Minio.Endpoint) == "127.0.0.1" {
return ErrConfig.Wrap("apiURL or Minio endpoint contain 127.0.0.1.")
}
}
return nil
}
func checkRedis() error {
var redisClient redis.UniversalClient
defer func() {
if redisClient != nil {
redisClient.Close()
}
}()
if len(config.Config.Redis.Address) > 1 {
redisClient = redis.NewClusterClient(&redis.ClusterOptions{
Addrs: config.Config.Redis.Address,
Username: config.Config.Redis.Username,
Password: config.Config.Redis.Password,
})
} else {
redisClient = redis.NewClient(&redis.Options{
Addr: config.Config.Redis.Address[0],
Username: config.Config.Redis.Username,
Password: config.Config.Redis.Password,
})
}
_, err := redisClient.Ping(context.Background()).Result()
if err != nil {
return err
}
return nil
}
func checkZookeeper() error {
var c *zk.Conn
defer func() {
if c != nil {
c.Close()
}
}()
c, _, err := zk.Connect(config.Config.Zookeeper.ZkAddr, time.Second)
if err != nil {
return err
} else {
if config.Config.Zookeeper.Username != "" && config.Config.Zookeeper.Password != "" {
if err := c.AddAuth("digest", []byte(config.Config.Zookeeper.Username+":"+config.Config.Zookeeper.Password)); err != nil {
return err
}
}
_, _, err = c.Get("/")
if err != nil {
return err
}
}
return nil
}
func checkKafka() error {
var kafkaClient sarama.Client
defer func() {
if kafkaClient != nil {
kafkaClient.Close()
}
}()
cfg := sarama.NewConfig()
if config.Config.Kafka.Username != "" && config.Config.Kafka.Password != "" {
cfg.Net.SASL.Enable = true
cfg.Net.SASL.User = config.Config.Kafka.Username
cfg.Net.SASL.Password = config.Config.Kafka.Password
}
kafkaClient, err := sarama.NewClient(config.Config.Kafka.Addr, cfg)
if err != nil {
return err
} else {
topics, err := kafkaClient.Topics()
if err != nil {
return err
}
if !utils.IsContain(config.Config.Kafka.MsgToMongo.Topic, topics) {
return ErrComponentStart.Wrap(fmt.Sprintf("kafka doesn't contain topic:%v", config.Config.Kafka.MsgToMongo.Topic))
}
if !utils.IsContain(config.Config.Kafka.MsgToPush.Topic, topics) {
return ErrComponentStart.Wrap(fmt.Sprintf("kafka doesn't contain topic:%v", config.Config.Kafka.MsgToPush.Topic))
}
if !utils.IsContain(config.Config.Kafka.LatestMsgToRedis.Topic, topics) {
return ErrComponentStart.Wrap(fmt.Sprintf("kafka doesn't contain topic:%v", config.Config.Kafka.LatestMsgToRedis.Topic))
}
}
return nil
}
func errorPrint(s string) {
fmt.Printf("\x1b[%dm%v\x1b[0m\n", 31, s)
}
func successPrint(s string) {
fmt.Printf("\x1b[%dm%v\x1b[0m\n", 32, s)
}
func warningPrint(s string) {
fmt.Printf("\x1b[%dmWarning: But %v\x1b[0m\n", 33, s)
}