Compare commits

..

78 Commits

Author SHA1 Message Date
kubbot 0001573af7 release: v3.0 release
Signed-off-by: kubbot <3293172751ysy@gmail.com>
2023-07-14 21:14:22 +08:00
skiffer-git 4ca0a4b861 fix bug: DelConvsersations->DelConversations 2023-07-14 21:07:30 +08:00
BanTanger 9d6acf41f9 fix: implement of GetUsersOnlineStatus (#567) (#569) 2023-07-14 12:54:24 +00:00
WangchuXiao 2f59be98d1 fix bug: multiple gateway kick user (#568)
* new feature: add batch send msg

* new feature: add batch send msg

* new feature: add batch send msg

* new feature: add batch send msg

* new feature: add batch send msg

* new feature: add batch send msg

* fix bug: multiple gateway kick user

* fix bug: multiple gateway kick user

* fix bug: multiple gateway kick user

* fix bug: multiple gateway kick user

* fix bug: multiple gateway kick user
2023-07-14 12:46:25 +00:00
Alan 0c23b3a443 debug (#566)
* message for your changes

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>

* debug

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>

* Delete start.bat

* Delete build.cmd

---------

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
Co-authored-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-14 12:40:41 +00:00
Alan 16a851d951 message for your changes (#565)
Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
Co-authored-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-14 11:14:18 +00:00
pluto 887267e62d fix bug #545 (#555) 2023-07-14 10:59:28 +00:00
Xinwei Xiong e8229700e9 feat: Add light mode and dark mode.(#89) (#564)
Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
2023-07-14 10:56:54 +00:00
Alan 3aa8d2fa69 fix get groups bug (#562)
* fix get group bug

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>

* bug

* api

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>

* Delete start.bat

* Delete build.cmd

---------

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
Co-authored-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-14 10:54:56 +00:00
Xinwei Xiong b85c5ad84e feat: Add light mode and dark mode.(#89) (#558)
* feat: Add light mode and dark mode.(#89)

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* fix: make file code len

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* feat: fix scripts support win

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* fix: make build issue

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* fix: golint and format

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* feat: add scripts sudo limits of authority

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* fix: docker images fix

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* fix: docker images fix

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

---------

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
2023-07-14 08:17:59 +00:00
WangchuXiao 70d8ae4c19 new feature: add batch send msg (#560)
* new feature: add batch send msg

* new feature: add batch send msg

* new feature: add batch send msg

* new feature: add batch send msg

* new feature: add batch send msg

* new feature: add batch send msg
2023-07-14 06:49:28 +00:00
Xinwei Xiong 3b438d58a9 fix: scripts and release (#552)
* fix: scripts and release

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* fix: fix  bug

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* fix: docker compose  and release

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* fix: cicd bug

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* fix: cicd bug

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

---------

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
2023-07-14 03:32:14 +00:00
Xinwei Xiong 02cf07de3d Merge pull request #547 from wangchuxiao-dev/main
fix bug: log path and user rpc
2023-07-13 12:56:54 +00:00
wangchuxiao 084a374c62 fix bug: log not in correct position 2023-07-13 20:48:57 +08:00
wangchuxiao 642ae4d159 Merge branch 'main' of github.com:wangchuxiao-dev/Open-IM-Server 2023-07-13 20:05:46 +08:00
wangchuxiao 99de4f8a7e fix bug: init conn once 2023-07-13 20:05:39 +08:00
wangchuxiao e1b1fc705b Merge remote-tracking branch 'upstream/main' 2023-07-13 20:02:26 +08:00
wangchuxiao 38a191e5d1 fix bug: init conn once 2023-07-13 19:57:52 +08:00
wangchuxiao 7cf48c89f3 fix bug: init conn once 2023-07-13 19:57:40 +08:00
withchao 7624821f5f Merge pull request #546 from withchao/main
fix: rpc mw mismatch key
2023-07-13 11:53:19 +00:00
wangchuxiao dbe58fac04 Merge remote-tracking branch 'upstream/main' 2023-07-13 19:49:09 +08:00
withchao 3163f42597 fix: rpc mw mismatch key 2023-07-13 19:26:17 +08:00
Xinwei Xiong ab406bea3d Merge pull request #543 from hanzhixiao/fix/v3-error2
fix conflict
2023-07-13 10:39:35 +00:00
‘hanzhixiao’ 4bd97149c3 fix conflict
Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-13 18:37:59 +08:00
‘hanzhixiao’ fda6cd5354 fix conflict
Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-13 18:30:18 +08:00
Xinwei Xiong c6203c825f Merge pull request #542 from hanzhixiao/fix/v3-error
Fix/v3 error
2023-07-13 10:26:27 +00:00
‘hanzhixiao’ 90d226c290 fix conflict
Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-13 18:21:42 +08:00
‘hanzhixiao’ 25eabde3f6 fix conflict
Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-13 18:20:11 +08:00
‘hanzhixiao’ 02e6b7ec18 fix conflict
Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-13 18:20:03 +08:00
‘hanzhixiao’ be7d785f1d fix conflict
Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-13 18:17:27 +08:00
Xinwei Xiong ccf2cdaab2 Merge pull request #540 from cubxxw/fix/copy
feat: add test file
2023-07-13 10:09:16 +00:00
Xinwei Xiong(cubxxw-openim) 99dc701ff6 feat: script and make build
Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
2023-07-13 17:37:51 +08:00
Xinwei Xiong 8fbc7e8116 Merge pull request #539 from plutoyty/main
url to uri
2023-07-13 09:33:37 +00:00
pluto 4066726221 Merge branch 'OpenIMSDK:main' into main 2023-07-13 17:22:39 +08:00
withchao 53048951ec Merge pull request #538 from withchao/main
fix: minio auto make bucket
2023-07-13 09:19:30 +00:00
plutoyty 772cb859fa url to uri 2023-07-13 17:18:14 +08:00
withchao 81bcd86304 fix: minio auto make bucket 2023-07-13 17:10:48 +08:00
pluto b0b7d6fe7f Merge branch 'OpenIMSDK:main' into main 2023-07-13 17:08:00 +08:00
Xinwei Xiong(cubxxw-openim) 6ecf253ef6 feat: add copy
Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
2023-07-13 17:07:45 +08:00
Xinwei Xiong(cubxxw-openim) fd3c19d6a5 feat: add test file
Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
2023-07-13 17:07:45 +08:00
Gordon ce33b79915 fix: conflict resolve main (#537)
* statistics user register

* refactor: router change

* minio init

* UserRegisterCount

* push use local conn

* refactor: user pb update

* remove online push close grpc conn

* refactor: user pb update

* refactor:pb file

* msgs statistics

* msgs statistics

* revoke userID

* refactor: errcode update

* active user

* active user

* active user

* refactor: errcode update

* feat: conn update token

* active user

* active user

* feat: conn update token

* active user

* feat: conn update token

* feat: conn update token

* feat: conn update token

* add tx_oss cos

* active user

* active user

* group create

* group create

* feat: group notification show to conversation

* feat: group notification show to conversation

* group active

* user active

* sendNotificationWithName

* withname

* privateChat

* a2r call option

* grpc with detail return error

* change log error

* chain unary interceptor

* api nil slice map

* fix sync has read

* fix: text update

* fix: update add model

* set conversations update

* set privateChat

* fix: content update

* remove unuse rpc

* msgDestruct

* cron use rpc mw

* set IsMsgDestruct

* msg destruct

* msgDestruct

* s3 minio, cos, oss support

* feat: add implement of GetUsersOnlineStatus, #472 (#477)

* s3 minio, cos, oss support

* s3 route

* remove extendMsg code

* s3 route

* remove unuse code

* s3 pb

* s3 pb

* s3 pb

* s3 presigned put

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* Update .gitignore (#482)

* s3 debug log

* s3 debug log

* cron add log and fix cron

* add log

* cron

* s3 config

* fix kick user bug

* s3 cos

* add kick log

* s3 cos test

* s3 cos test

* s3 cos test

* kick user log

* kickuserlog

* s3 cos copy

* s3 cos copy

* s3 url

* s3 url

* s3 AccessURL

* log

* s3 InitiateMultipartUpload add ExpireTime

* feat: regenerate pb file

* feat: regenerate pb file

* Revert "feat: regenerate pb file"

This reverts commit 434f22564a.

* Delete .idea directory

* feat: regenerate pb file

* fix: remove import C

* fix: add msg transfer main file

* fix: get user online status fix

---------

Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: wangchuxiao <wangchuxiao97@outlook.com>
Co-authored-by: BanTanger <88583317+BanTanger@users.noreply.github.com>
Co-authored-by: withchao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Alan <68671759+hanzhixiao@users.noreply.github.com>
2023-07-13 16:51:52 +08:00
pluto 2388f93cfb Merge branch 'OpenIMSDK:main' into main 2023-07-13 15:46:37 +08:00
WangchuXiao 4cacc3f621 fix bug: friend, args error (#534)
* fix bug: args error

* fix bug: args error

* fix bug: add friend need update both request

* fix bug: add friend need update both request
2023-07-13 15:26:25 +08:00
wangchuxiao 2607862544 Merge remote-tracking branch 'upstream/main' 2023-07-13 15:22:59 +08:00
Gordon e5ab278be5 fix: get user online status #472 (#527)
* statistics user register

* refactor: router change

* minio init

* UserRegisterCount

* push use local conn

* refactor: user pb update

* remove online push close grpc conn

* refactor: user pb update

* refactor:pb file

* msgs statistics

* msgs statistics

* revoke userID

* refactor: errcode update

* active user

* active user

* active user

* refactor: errcode update

* feat: conn update token

* active user

* active user

* feat: conn update token

* active user

* feat: conn update token

* feat: conn update token

* feat: conn update token

* add tx_oss cos

* active user

* active user

* group create

* group create

* feat: group notification show to conversation

* feat: group notification show to conversation

* group active

* user active

* sendNotificationWithName

* withname

* privateChat

* a2r call option

* grpc with detail return error

* change log error

* chain unary interceptor

* api nil slice map

* fix sync has read

* fix: text update

* fix: update add model

* set conversations update

* set privateChat

* fix: content update

* remove unuse rpc

* msgDestruct

* cron use rpc mw

* set IsMsgDestruct

* msg destruct

* msgDestruct

* s3 minio, cos, oss support

* feat: add implement of GetUsersOnlineStatus, #472 (#477)

* s3 minio, cos, oss support

* s3 route

* remove extendMsg code

* s3 route

* remove unuse code

* s3 pb

* s3 pb

* s3 pb

* s3 presigned put

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* s3 presigned test

* Update .gitignore (#482)

* s3 debug log

* s3 debug log

* cron add log and fix cron

* add log

* cron

* s3 config

* fix kick user bug

* s3 cos

* add kick log

* s3 cos test

* s3 cos test

* s3 cos test

* kick user log

* kickuserlog

* s3 cos copy

* s3 cos copy

* s3 url

* s3 url

* s3 AccessURL

* log

* s3 InitiateMultipartUpload add ExpireTime

* feat: regenerate pb file

* feat: regenerate pb file

* Revert "feat: regenerate pb file"

This reverts commit 434f22564a.

* Delete .idea directory

* feat: regenerate pb file

* fix: remove import C

* fix: add msg transfer main file

* fix: get user online status fix

---------

Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: wangchuxiao <wangchuxiao97@outlook.com>
Co-authored-by: BanTanger <88583317+BanTanger@users.noreply.github.com>
Co-authored-by: withchao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Alan <68671759+hanzhixiao@users.noreply.github.com>
2023-07-13 15:17:05 +08:00
Alan 0b306d996d all back-office api (#533)
* fix conflict

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>

* all Back-office management api

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>

---------

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
Co-authored-by: ‘hanzhixiao’ <‘709674996@qq.com’>
2023-07-13 15:11:33 +08:00
wangchuxiao 643de8c7ec fix bug: add friend need update both request 2023-07-13 14:41:49 +08:00
wangchuxiao 4c365701d4 fix bug: add friend need update both request 2023-07-13 13:09:46 +08:00
pluto 5e92c76136 Merge branch 'OpenIMSDK:main' into main 2023-07-13 12:27:20 +08:00
pluto 058e2eee32 add MongoDB,Redis,Kafka retry mechanism (#518) 2023-07-13 12:26:09 +08:00
wangchuxiao 9d6f46b7f9 fix bug: args error 2023-07-13 11:49:51 +08:00
Xinwei Xiong 7bf8a898e2 feat: add scripts (#525) 2023-07-13 11:37:23 +08:00
wangchuxiao 549721ec8e Merge remote-tracking branch 'upstream/main' 2023-07-13 11:33:25 +08:00
wangchuxiao 4d89d7c618 fix bug: args error 2023-07-13 11:03:22 +08:00
pluto eb7953cacb cicd: update openim-ci.yml (#528) 2023-07-13 10:30:25 +08:00
pluto 59f948bde2 Merge branch 'OpenIMSDK:main' into main 2023-07-13 10:14:40 +08:00
skiffer-git b46f3410ad Add feature: Replace apiURL (in config.yaml) with an external IP address 2023-07-12 22:07:25 +08:00
skiffer-git 62cd1dace0 Merge remote-tracking branch 'origin/main' 2023-07-12 21:33:25 +08:00
skiffer-git 95ec99daf0 fix bug ContentType is wrong range for Check 2023-07-12 21:33:11 +08:00
pluto df38875d88 Merge branch 'OpenIMSDK:main' into main 2023-07-12 20:58:37 +08:00
Xinwei Xiong 135dc7b359 feat: add scripts (#515)
* feat: add scripts

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* build: Infrastructure, openimv3.0.0

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>

* feat: add code (#519)

---------

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
2023-07-12 20:46:34 +08:00
plutoyty d41f2a7aef Add retry mechanism to mongoDB, Redis, Kafka 2023-07-12 20:21:52 +08:00
plutoyty 40b26f9a2f Merge remote-tracking branch 'origin/main' into add-new-feature-#484 2023-07-12 19:29:12 +08:00
pluto 2cca8b8927 Merge branch 'OpenIMSDK:main' into main 2023-07-12 19:27:50 +08:00
Xinwei Xiong 1b5eb4a5c0 feat: add scripts (#514) 2023-07-12 19:21:55 +08:00
plutoyty 9ac47e3423 Merge remote-tracking branch 'origin/main' into add-new-feature-#484
# Conflicts:
#	pkg/common/db/unrelation/extend_msg.go
2023-07-12 19:16:48 +08:00
pluto 568e6a8e86 Merge branch 'OpenIMSDK:main' into main 2023-07-12 19:16:04 +08:00
plutoyty 35b1f75036 Add retry mechanism to mongoDB, Redis, Kafka 2023-07-12 19:15:39 +08:00
pluto 496d178313 Merge branch 'OpenIMSDK:main' into main 2023-07-12 15:34:47 +08:00
pluto 1fe6423593 Merge branch 'OpenIMSDK:main' into main 2023-07-12 15:28:38 +08:00
plutoyty a735a70a7b Remove .idea directory and add it to .gitignore 2023-07-12 12:05:32 +08:00
plutoyty 2f5bcf1cf7 For 'add database retry' add test
Signed-off-by: plutoyty <2631223275@qq.com>
2023-07-12 11:53:22 +08:00
plutoyty 6bc369ed00 For "add database retry" add test 2023-07-12 11:43:30 +08:00
plutoyty 66f6e3d604 Merge remote-tracking branch 'origin/main' into add-new-feature-#484 2023-07-12 11:39:28 +08:00
pluto 4d2bd1a1c5 Merge branch 'OpenIMSDK:main' into main 2023-07-12 11:37:54 +08:00
plutoyty 2693db218a For "add database retry" add test 2023-07-12 11:35:06 +08:00
pluto 51314729fc Merge branch 'OpenIMSDK:main' into main 2023-07-12 09:57:32 +08:00
杨腾宇 2b041d8f6a Add database retry 2023-07-11 17:34:39 +08:00
192 changed files with 4622 additions and 2892 deletions
+31
View File
@@ -0,0 +1,31 @@
# Ignore files and directories starting with a dot
# Ignore specific files
.dockerignore
# Ignore build artifacts
_output/
logs/
# Ignore non-essential documentation
README.md
README-zh_CN.md
CONTRIBUTING.md
CHANGELOG/
# LICENSE
# Ignore testing and linting configuration
.golangci.yml
# Ignore deployment-related files
docker-compose.yaml
deployments/
# Ignore assets
assets/
# Ignore components
components/
# Ignore tools and scripts
.github/
+1
View File
@@ -1,4 +1,5 @@
USER=root USER=root
PASSWORD=openIM123 PASSWORD=openIM123
MINIO_ENDPOINT=http://127.0.0.1:10005 MINIO_ENDPOINT=http://127.0.0.1:10005
API_URL=http://127.0.0.1:10002/object/
DATA_DIR=./ DATA_DIR=./
+36
View File
@@ -0,0 +1,36 @@
name: OpenIM Build Docker Images
on:
push:
tags:
- v*
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
bin:
- ssserver
- sslocal
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker metadata
id: metadata
uses: docker/metadata-action@v4
with:
images: ghcr.io/${{ github.repository_owner }}/openim-${{ matrix.bin }}
- name: Build and release Docker images
uses: docker/build-push-action@v3
with:
platforms: linux/386,linux/amd64,linux/arm64/v8
target: ${{ matrix.bin }}
tags: ${{ steps.metadata.outputs.tags }}
push: true
+1 -1
View File
@@ -45,7 +45,7 @@ jobs:
# args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0 # args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0
# Optional: show only new issues if it's a pull request. The default value is `false`. # Optional: show only new issues if it's a pull request. The default value is `false`.
only-new-issues: true # only-new-issues: true
# Optional:The mode to install golangci-lint. It can be 'binary' or 'goinstall'. # Optional:The mode to install golangci-lint. It can be 'binary' or 'goinstall'.
install-mode: "goinstall" install-mode: "goinstall"
+2 -20
View File
@@ -66,6 +66,7 @@ jobs:
run: | run: |
make format make format
echo "Run go format successfully" echo "Run go format successfully"
continue-on-error: true
# - name: Generate all necessary files, such as error code files # - name: Generate all necessary files, such as error code files
# run: | # run: |
@@ -82,7 +83,7 @@ jobs:
- name: Build source code for host platform - name: Build source code for host platform
run: | run: |
make multiarch make build
echo "Build source code for host platform successfully" echo "Build source code for host platform successfully"
# - name: Collect Test Coverage File # - name: Collect Test Coverage File
@@ -131,22 +132,3 @@ jobs:
# - name: Test docker image # - name: Test docker image
# run: | # run: |
# docker build -t openim:ci-build . # docker build -t openim:ci-build .
# goreleaser-test:
# runs-on: ubuntu-20.04
# steps:
# - name: Checkout
# uses: actions/checkout@v3
# with:
# fetch-depth: 0
# - name: Set up Go
# uses: actions/setup-go@v3
# with:
# go-version: ${{ env.GO_VERSION }}
# - name: Run GoReleaser
# uses: goreleaser/goreleaser-action@v4
# with:
# version: latest
# args: release --clean --skip-publish --snapshot
+37
View File
@@ -0,0 +1,37 @@
name: goreleaser
on:
push:
# run only against tags
tags:
- '*'
permissions:
contents: write
# packages: write
# issues: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v4
with:
go-version: stable
# More assembly might be required: Docker logins, GPG, etc. It all depends
# on your needs.
- uses: goreleaser/goreleaser-action@v4
with:
# either 'goreleaser' (default) or 'goreleaser-pro':
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
# distribution:
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
+21 -17
View File
@@ -28,42 +28,46 @@ jobs:
- name: Start Docker Compose - name: Start Docker Compose
run: | run: |
docker-compose stop sudo docker compose stop
docker-compose up -d sudo sleep 30
sleep 60 sudo docker compose up -d
sudo sleep 60
continue-on-error: true
- name: Stop all services - name: Stop all services
run: | run: |
chmod +x ./scripts/stop_all.sh sudo chmod +x ./scripts/stop_all.sh
./scripts/stop_all.sh sudo ./scripts/stop_all.sh
sudo cat logs/openIM.log 2>/dev/null
shell: bash shell: bash
continue-on-error: true
- name: Build all services - name: Build all services
run: | run: |
chmod +x ./scripts/build_all_service.sh sudo chmod +x ./scripts/build_all_service.sh
./scripts/build_all_service.sh sudo ./scripts/build_all_service.sh
cat logs/openIM.log sudo cat logs/openIM.log 2>/dev/null
shell: bash shell: bash
continue-on-error: true
- name: Start all services - name: Start all services
run: | run: |
chmod +x ./scripts/start_all.sh sudo chmod +x ./scripts/start_all.sh
./scripts/start_all.sh sudo ./scripts/start_all.sh
cat logs/openIM.log sudo cat logs/openIM.log 2>/dev/null
continue-on-error: true continue-on-error: true
shell: bash shell: bash
- name: Check all services - name: Check all services
run: | run: |
chmod +x ./scripts/check_all.sh sudo chmod +x ./scripts/check_all.sh
./scripts/check_all.sh sudo ./scripts/check_all.sh
cat logs/openIM.log sudo cat logs/openIM.log 2>/dev/null
shell: bash shell: bash
continue-on-error: true
- name: Print openIM.log - name: Print openIM.log
run: | run: |
cat logs/openIM.log sudo cat logs/* 2>/dev/null
cat logs/openIM.log >> "$GITHUB_OUTPUT" sudo cat logs/* 2>/dev/null >> "$GITHUB_OUTPUT"
shell: bash shell: bash
continue-on-error: true continue-on-error: true
+1 -2
View File
@@ -163,7 +163,6 @@ go.work
# User-specific stuff # User-specific stuff
.idea/ .idea/
.idea
.idea/**/workspace.xml .idea/**/workspace.xml
.idea/**/tasks.xml .idea/**/tasks.xml
.idea/**/usage.statistics.xml .idea/**/usage.statistics.xml
@@ -353,7 +352,6 @@ cscope.po.out
*testsdir *testsdir
*testsfile *testsfile
*testsfiles *testsfiles
*test
*testdir *testdir
*testfile *testfile
*testfiles *testfiles
@@ -391,3 +389,4 @@ Sessionx.vim
[._]*.un~ [._]*.un~
# End of https://www.toptal.com/developers/gitignore/api/go,git,vim,tags,test,emacs,backup,jetbrains # End of https://www.toptal.com/developers/gitignore/api/go,git,vim,tags,test,emacs,backup,jetbrains
.idea
+665 -57
View File
@@ -1,10 +1,27 @@
# Copyright © 2023 OpenIMSDK open source community. 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.
# This file contains all available configuration options
# with their default values.
# options for analysis running # options for analysis running
run: run:
# default concurrency is a available CPU number # default concurrency is a available CPU number
concurrency: 4 concurrency: 4
# timeout for analysis, e.g. 30s, 5m, default is 1m # timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 1m timeout: 5m
# exit code when at least one issue was found, default is 1 # exit code when at least one issue was found, default is 1
issues-exit-code: 1 issues-exit-code: 1
@@ -12,10 +29,36 @@ run:
# include test files or not, default is true # include test files or not, default is true
tests: true tests: true
# list of build tags, all linters use it. Default is empty list.
build-tags:
- mytag
# which dirs to skip: issues from them won't be reported;
# can use regexp here: generated.*, regexp is applied on full path;
# default value is empty list, but default dirs are skipped independently
# from this option's value (see skip-dirs-use-default).
# "/" will be replaced by current OS file path separator to properly work
# on Windows.
skip-dirs:
- util
- .*~
- api/swagger/docs
- server/docs
# default is true. Enables skipping of directories: # default is true. Enables skipping of directories:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs-use-default: true skip-dirs-use-default: true
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
# "/" will be replaced by current OS file path separator to properly work
# on Windows.
skip-files:
- ".*\\.my\\.go$"
- _test.go
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules": # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
# If invoked with -mod=readonly, the go command is disallowed from the implicit # If invoked with -mod=readonly, the go command is disallowed from the implicit
# automatic updating of go.mod described above. Instead, it fails when any changes # automatic updating of go.mod described above. Instead, it fails when any changes
@@ -30,6 +73,7 @@ run:
# If false (default) - golangci-lint acquires file lock on start. # If false (default) - golangci-lint acquires file lock on start.
allow-parallel-runners: true allow-parallel-runners: true
# output configuration options # output configuration options
output: output:
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
@@ -44,9 +88,26 @@ output:
# make issues output unique by line, default is true # make issues output unique by line, default is true
uniq-by-line: true uniq-by-line: true
# add a prefix to the output file references; default is no prefix
path-prefix: ""
# sorts results by: filepath, line and column
sort-results: true
# all available settings of specific linters # all available settings of specific linters
linters-settings: linters-settings:
bidichk:
# The following configurations check for all mentioned invisible unicode
# runes. It can be omitted because all runes are enabled by default.
left-to-right-embedding: true
right-to-left-embedding: true
pop-directional-formatting: true
left-to-right-override: true
right-to-left-override: true
left-to-right-isolate: true
right-to-left-isolate: true
first-strong-isolate: true
pop-directional-isolate: true
dogsled: dogsled:
# checks assignments with too many blank identifiers; default is 2 # checks assignments with too many blank identifiers; default is 2
max-blank-identifiers: 2 max-blank-identifiers: 2
@@ -62,47 +123,217 @@ linters-settings:
# default is false: such cases aren't reported by default. # default is false: such cases aren't reported by default.
check-blank: false check-blank: false
# [deprecated] comma-separated list of pairs of the form pkg:regex
# the regex is used to ignore names within pkg. (default "fmt:.*").
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
#ignore: GenMarkdownTree,os:.*,BindPFlags,WriteTo,Help
#ignore: (os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv
# path to a file containing a list of functions to exclude from checking # path to a file containing a list of functions to exclude from checking
# see https://github.com/kisielk/errcheck#excluding-functions for details # see https://github.com/kisielk/errcheck#excluding-functions for details
#exclude: errcheck.txt #exclude: errcheck.txt
errorlint:
# Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats
errorf: true
# Check for plain type assertions and type switches
asserts: true
# Check for plain error comparisons
comparison: true
exhaustive: exhaustive:
# check switch statements in generated files also
check-generated: false
# indicates that switch statements are to be considered exhaustive if a # indicates that switch statements are to be considered exhaustive if a
# 'default' case is present, even if all enum members aren't listed in the # 'default' case is present, even if all enum members aren't listed in the
# switch # switch
default-signifies-exhaustive: false default-signifies-exhaustive: false
# enum members matching the supplied regex do not have to be listed in
# switch statements to satisfy exhaustiveness
ignore-enum-members: ""
# consider enums only in package scopes, not in inner scopes
package-scope-only: false
exhaustivestruct:
struct-patterns:
- '*.Test'
- '*.Test2'
- '*.Embedded'
- '*.External'
# forbidigo:
# # Forbid the following identifiers (identifiers are written using regexp):
# forbid:
# - ^print.*$
# - 'fmt\.Print.*'
# - fmt.Println.* # too much log noise
# - ginkgo\\.F.* # these are used just for local development
# # Exclude godoc examples from forbidigo checks. Default is true.
# exclude_godoc_examples: false
funlen: funlen:
lines: 150 lines: 150
statements: 40 statements: 50
gci:
# put imports beginning with prefix after 3rd-party packages;
# only support one prefix
# if not set, use goimports.local-prefixes
prefix: github.com/OpenIMSDK/OpenKF
gocognit: gocognit:
# minimal code complexity to report, 30 by default (but we recommend 10-20) # minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 30 min-complexity: 30
nestif:
# minimal complexity of if statements to report, 5 by default
min-complexity: 4
goconst: goconst:
# minimal length of string constant, 3 by default # minimal length of string constant, 3 by default
min-len: 5 min-len: 3
# minimal occurrences count to trigger, 3 by default # minimal occurrences count to trigger, 3 by default
min-occurrences: 5 min-occurrences: 3
# ignore test files, false by default
ignore-tests: false
# look for existing constants matching the values, true by default
match-constant: true
# search also for duplicated numbers, false by default
numbers: false
# minimum value, only works with goconst.numbers, 3 by default
min: 3
# maximum value, only works with goconst.numbers, 3 by default
max: 3
# ignore when constant is not used as function argument, true by default
ignore-calls: true
gocritic:
# Which checks should be enabled; can't be combined with 'disabled-checks';
# See https://go-critic.github.io/overview#checks-overview
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
# By default list of stable checks is used.
enabled-checks:
#- rangeValCopy
- nestingreduce
- truncatecmp
- unnamedresult
- ruleguard
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
disabled-checks:
- regexpMust
- ifElseChain
#- exitAfterDefer
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
enabled-tags:
- performance
disabled-tags:
- experimental
# Settings passed to gocritic.
# The settings key is the name of a supported gocritic checker.
# The list of supported checkers can be find in https://go-critic.github.io/overview.
settings:
captLocal: # must be valid enabled check name
# whether to restrict checker to params only (default true)
paramsOnly: true
elseif:
# whether to skip balanced if-else pairs (default true)
skipBalanced: true
hugeParam:
# size in bytes that makes the warning trigger (default 80)
sizeThreshold: 80
nestingReduce:
# min number of statements inside a branch to trigger a warning (default 5)
bodyWidth: 5
rangeExprCopy:
# size in bytes that makes the warning trigger (default 512)
sizeThreshold: 512
# whether to check test functions (default true)
skipTestFuncs: true
rangeValCopy:
# size in bytes that makes the warning trigger (default 128)
sizeThreshold: 32
# whether to check test functions (default true)
skipTestFuncs: true
ruleguard:
# path to a gorules file for the ruleguard checker
rules: ''
truncateCmp:
# whether to skip int/uint/uintptr types (default true)
skipArchDependent: true
underef:
# whether to skip (*x).method() calls where x is a pointer receiver (default true)
skipRecvDeref: true
unnamedResult:
# whether to check exported functions
checkExported: true
gocyclo: gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20) # minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 30 min-complexity: 30
cyclop:
# the maximal code complexity to report
max-complexity: 50
# the maximal average package complexity. If it's higher than 0.0 (float) the check is enabled (default 0.0)
package-average: 0.0
# should ignore tests (default false)
skip-tests: false
godot: godot:
# check all top-level comments, not only declarations # comments to be checked: `declarations`, `toplevel`, or `all`
check-all: false scope: declarations
# list of regexps for excluding particular comment lines from check
exclude:
# example: exclude comments which contain numbers
# - '[0-9]+'
# check that each sentence starts with a capital letter
capital: false
godox: godox:
# report any comments starting with keywords, this is useful for TODO or FIXME comments that # report any comments starting with keywords, this is useful for TODO or FIXME comments that
# might be left in the code accidentally and should be resolved before merging # might be left in the code accidentally and should be resolved before merging
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
#- TODO
- BUG
- FIXME
#- NOTE
- OPTIMIZE # marks code that should be optimized before merging - OPTIMIZE # marks code that should be optimized before merging
- HACK # marks hack-arounds that should be removed before merging - HACK # marks hack-arounds that should be removed before merging
gofmt: gofmt:
# simplify code: gofmt with `-s` option, true by default # simplify code: gofmt with `-s` option, true by default
simplify: true simplify: true
gofumpt:
# Select the Go version to target. The default is `1.18`.
lang-version: "1.20"
# Choose whether or not to use the extra rules that are disabled
# by default
extra-rules: false
goheader:
values:
const:
# define here const type values in format k:v, for example:
# COMPANY: MY COMPANY
regexp:
# define here regexp type values, for example
# AUTHOR: .*@mycompany\.com
template: # |-
# put here copyright header template for source code files, for example:
# Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
#
# {{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
# SPDX-License-Identifier: Apache-2.0
# 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.
template-path:
# also as alternative of directive 'template' you may put the path to file with the template source
goimports: goimports:
# put imports beginning with prefix after 3rd-party packages; # put imports beginning with prefix after 3rd-party packages;
# it's a comma-separated list of prefixes # it's a comma-separated list of prefixes
local-prefixes: github.com/org/project local-prefixes: github.com/OpenIMSDK/OpenKF
golint: golint:
# minimal confidence for issues, default is 0.8 # minimal confidence for issues, default is 0.8
min-confidence: 0.9 min-confidence: 0.9
@@ -111,16 +342,91 @@ linters-settings:
mnd: mnd:
# the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description. # the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
checks: argument,case,condition,operation,return,assign checks: argument,case,condition,operation,return,assign
# ignored-numbers: 1000
# ignored-files: magic_.*.go
# ignored-functions: math.*
gomoddirectives:
# Allow local `replace` directives. Default is false.
replace-local: true
# List of allowed `replace` directives. Default is empty.
replace-allow-list:
- google.golang.org/grpc
# Allow to not explain why the version has been retracted in the `retract` directives. Default is false.
retract-allow-no-explanation: false
# Forbid the use of the `exclude` directives. Default is false.
exclude-forbidden: false
gomodguard: gomodguard:
allowed: allowed:
modules: # List of allowed modules modules:
- gorm.io/gen # List of allowed modules
- gorm.io/gorm
- gorm.io/driver/mysql
- k8s.io/klog
# - gopkg.in/yaml.v2 # - gopkg.in/yaml.v2
domains: # List of allowed module domains domains: # List of allowed module domains
# - golang.org - google.golang.org
- gopkg.in
- golang.org
- github.com
- go.uber.org
- go.etcd.io
blocked:
versions:
- github.com/MakeNowJust/heredoc:
version: "> 2.0.9"
reason: "use the latest version"
local_replace_directives: false # Set to true to raise lint issues for packages that are loaded from a local path via replace directive
gosec:
# To select a subset of rules to run.
# Available rules: https://github.com/securego/gosec#available-rules
includes:
- G401
- G306
- G101
# To specify a set of rules to explicitly exclude.
# Available rules: https://github.com/securego/gosec#available-rules
excludes:
- G204
# Exclude generated files
exclude-generated: true
# Filter out the issues with a lower severity than the given value. Valid options are: low, medium, high.
severity: "low"
# Filter out the issues with a lower confidence than the given value. Valid options are: low, medium, high.
confidence: "low"
# To specify the configuration of rules.
# The configuration of rules is not fully documented by gosec:
# https://github.com/securego/gosec#configuration
# https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/rules/rulelist.go#L60-L102
config:
G306: "0600"
G101:
pattern: "(?i)example"
ignore_entropy: false
entropy_threshold: "80.0"
per_char_threshold: "3.0"
truncate: "32"
gosimple:
# Select the Go version to target. The default is '1.13'.
go: "1.20"
# https://staticcheck.io/docs/options#checks
checks: [ "all" ]
govet: govet:
# report about shadowed variables # report about shadowed variables
check-shadowing: true check-shadowing: true
# settings per analyzer
settings:
printf: # analyzer name, run `go tool vet help` to see all analyzers
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
# enable or disable analyzers by name # enable or disable analyzers by name
enable: enable:
- atomicalign - atomicalign
@@ -128,17 +434,69 @@ linters-settings:
disable: disable:
- shadow - shadow
disable-all: false disable-all: false
depguard: # depguard:
list-type: blacklist # list-type: blacklist
include-go-root: false # include-go-root: false
packages: # packages:
packages-with-error-message: # - github.com/Sirupsen/logrus
# packages-with-error-message:
# # specify an error message to output when a blacklisted package is used
# - github.com/Sirupsen/logrus: "logging is allowed only by logutils.Log"
ifshort:
# Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax.
# Has higher priority than max-decl-chars.
max-decl-lines: 1
# Maximum length of variable declaration measured in number of characters, after which linter won't suggest using short syntax.
max-decl-chars: 30
importas:
# if set to `true`, force to use alias.
no-unaliased: true
# List of aliases
alias:
# using `servingv1` alias for `knative.dev/serving/pkg/apis/serving/v1` package
- pkg: knative.dev/serving/pkg/apis/serving/v1
alias: servingv1
# using `autoscalingv1alpha1` alias for `knative.dev/serving/pkg/apis/autoscaling/v1alpha1` package
- pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1
alias: autoscalingv1alpha1
# You can specify the package path by regular expression,
# and alias by regular expression expansion syntax like below.
# see https://github.com/julz/importas#use-regular-expression for details
- pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
alias: $1$2
# using `jwt` alias for `github.com/appleboy/gin-jwt/v2` package
jwt: github.com/appleboy/gin-jwt/v2
ireturn:
# ireturn allows using `allow` and `reject` settings at the same time.
# Both settings are lists of the keywords and regular expressions matched to interface or package names.
# keywords:
# - `empty` for `interface{}`
# - `error` for errors
# - `stdlib` for standard library
# - `anon` for anonymous interfaces
# By default, it allows using errors, empty interfaces, anonymous interfaces,
# and interfaces provided by the standard library.
allow:
- anon
- error
- empty
- stdlib
# You can specify idiomatic endings for interface
- (or|er)$
# Reject patterns
reject:
- github.com\/user\/package\/v4\.Type
lll: lll:
# max line length, lines longer will be reported. Default is 120. # max line length, lines longer will be reported. Default is 120.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option # '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 120 line-length: 240
# tab width in spaces. Default to 1. # tab width in spaces. Default to 1.
tab-width: 1 tab-width: 4
maligned: maligned:
# print struct with more effective memory layout or not, false by default # print struct with more effective memory layout or not, false by default
suggest-new: true suggest-new: true
@@ -152,6 +510,37 @@ linters-settings:
nakedret: nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30 # make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 30 max-func-lines: 30
nestif:
# minimal complexity of if statements to report, 5 by default
min-complexity: 4
nilnil:
# By default, nilnil checks all returned types below.
checked-types:
- ptr
- func
- iface
- map
- chan
nlreturn:
# size of the block (including return statement that is still "OK")
# so no return split required.
block-size: 1
nolintlint:
# Disable to ensure that all nolint directives actually have an effect. Default is true.
allow-unused: false
# Disable to ensure that nolint directives don't have a leading space. Default is true.
allow-leading-space: true
# Exclude following linters from requiring an explanation. Default is [].
allow-no-explanation: [ ]
# Enable to require an explanation of nonzero length after each nolint directive. Default is false.
require-explanation: false
# Enable to require nolint directives to mention the specific linter being suppressed. Default is false.
require-specific: true
prealloc: prealloc:
# XXX: we don't recommend using this linter before doing performance profiling. # XXX: we don't recommend using this linter before doing performance profiling.
# For most programs usage of prealloc will be a premature optimization. # For most programs usage of prealloc will be a premature optimization.
@@ -161,17 +550,97 @@ linters-settings:
simple: true simple: true
range-loops: true # Report preallocation suggestions on range loops, true by default range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default for-loops: false # Report preallocation suggestions on for loops, false by default
nolintlint:
# Enable to ensure that nolint directives are all used. Default is true. promlinter:
allow-unused: false # Promlinter cannot infer all metrics name in static analysis.
# Disable to ensure that nolint directives don't have a leading space. Default is true. # Enable strict mode will also include the errors caused by failing to parse the args.
allow-leading-space: true strict: false
# Exclude following linters from requiring an explanation. Default is []. # Please refer to https://github.com/yeya24/promlinter#usage for detailed usage.
allow-no-explanation: [] disabled-linters:
# Enable to require an explanation of nonzero length after each nolint directive. Default is false. # - "Help"
require-explanation: true # - "MetricUnits"
# Enable to require nolint directives to mention the specific linter being suppressed. Default is false. # - "Counter"
require-specific: true # - "HistogramSummaryReserved"
# - "MetricTypeInName"
# - "ReservedChars"
# - "CamelCase"
# - "lintUnitAbbreviations"
predeclared:
# comma-separated list of predeclared identifiers to not report on
ignore: ""
# include method names and field names (i.e., qualified names) in checks
q: false
rowserrcheck:
packages:
- github.com/jmoiron/sqlx
revive:
# see https://github.com/mgechev/revive#available-rules for details.
ignore-generated-header: true
severity: warning
rules:
- name: indent-error-flow
severity: warning
staticcheck:
# Select the Go version to target. The default is '1.13'.
go: "1.16"
# https://staticcheck.io/docs/options#checks
checks: [ "all" ]
stylecheck:
# Select the Go version to target. The default is '1.13'.
go: "1.16"
# https://staticcheck.io/docs/options#checks
checks: [ "all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022" ]
# https://staticcheck.io/docs/options#dot_import_whitelist
dot-import-whitelist:
- fmt
# https://staticcheck.io/docs/options#initialisms
initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS" ]
# https://staticcheck.io/docs/options#http_status_code_whitelist
http-status-code-whitelist: [ "200", "400", "404", "500" ]
tagliatelle:
# check the struck tag name case
case:
# use the struct field name to check the name of the struct tag
use-field-name: true
rules:
# any struct tag type can be used.
# support string case: `camel`, `pascal`, `kebab`, `snake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower`
json: camel
yaml: camel
xml: camel
bson: camel
avro: snake
mapstructure: kebab
testpackage:
# regexp pattern to skip files
skip-regexp: (id|export|internal)_test\.go
thelper:
# The following configurations enable all checks. It can be omitted because all checks are enabled by default.
# You can enable only required checks deleting unnecessary checks.
test:
first: true
name: true
begin: true
benchmark:
first: true
name: true
begin: true
tb:
first: true
name: true
begin: true
tenv:
# The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.
# By default, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
all: false
unparam: unparam:
# Inspect exported functions, default is false. Set to true if no external program/library imports your code. # Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
@@ -187,6 +656,24 @@ linters-settings:
whitespace: whitespace:
multi-if: false # Enforces newlines (or comments) after every multi-line if statement multi-if: false # Enforces newlines (or comments) after every multi-line if statement
multi-func: false # Enforces newlines (or comments) after every multi-line function signature multi-func: false # Enforces newlines (or comments) after every multi-line function signature
wrapcheck:
# An array of strings that specify substrings of signatures to ignore.
# If this set, it will override the default set of ignored signatures.
# See https://github.com/tomarrell/wrapcheck#configuration for more information.
ignoreSigs:
- .Errorf(
- errors.New(
- errors.Unwrap(
- .Wrap(
- .Wrapf(
- .WithMessage(
- .WithMessagef(
- .WithStack(
ignorePackageGlobs:
- encoding/*
- github.com/pkg/*
wsl: wsl:
# If true append is only allowed to be cuddled if appending value is # If true append is only allowed to be cuddled if appending value is
# matching variables, fields or types on line above. Default is true. # matching variables, fields or types on line above. Default is true.
@@ -194,6 +681,8 @@ linters-settings:
# Allow calls and assignments to be cuddled as long as the lines have any # Allow calls and assignments to be cuddled as long as the lines have any
# matching variables, fields or types. Default is true. # matching variables, fields or types. Default is true.
allow-assign-and-call: true allow-assign-and-call: true
# Allow assignments to be cuddled with anything. Default is false.
allow-assign-and-anything: false
# Allow multiline assignments to be cuddled. Default is true. # Allow multiline assignments to be cuddled. Default is true.
allow-multiline-assign: true allow-multiline-assign: true
# Allow declarations (var) to be cuddled. # Allow declarations (var) to be cuddled.
@@ -206,65 +695,181 @@ linters-settings:
force-err-cuddling: false force-err-cuddling: false
# Allow leading comments to be separated with empty liens # Allow leading comments to be separated with empty liens
allow-separated-leading-comment: false allow-separated-leading-comment: false
makezero:
# Allow only slices initialized with a length of zero. Default is false.
always: false
# The custom section can be used to define linter plugins to be loaded at runtime. See README doc
# for more info.
#custom:
# Each custom linter should have a unique name.
#example:
# The path to the plugin *.so. Can be absolute or local. Required for each custom linter
#path: /path/to/example.so
# The description of the linter. Optional, just for documentation purposes.
#description: This is an example usage of a plugin linter.
# Intended to point to the repo location of the linter. Optional, just for documentation purposes.
#original-url: github.com/golangci/example-linter
linters: linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon. # please, do not use `enable-all`: it's deprecated and will be removed soon.
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
# enable-all: true
disable-all: true disable-all: true
enable: enable:
- typecheck
- asciicheck
- bodyclose - bodyclose
- cyclop
- deadcode - deadcode
- depguard # - depguard
- dogsled - dogsled
- dupl - dupl
- durationcheck
- errcheck - errcheck
- errorlint
- exhaustive
- exportloopref
# - forbidigo
- funlen - funlen
- gochecknoinits # - gci
# - gochecknoinits
- gocognit
- goconst - goconst
- gocritic
- gocyclo - gocyclo
- godot
- godox
- gofmt - gofmt
- gofumpt
- goheader
- goimports - goimports
- golint - gomoddirectives
- gomodguard
- goprintffuncname - goprintffuncname
- gosec - gosec
- gosimple - gosimple
- govet - govet
- ifshort
- importas
- ineffassign - ineffassign
- interfacer
- lll - lll
- makezero
- misspell - misspell
- nakedret - nakedret
- nestif
- nilerr
- nlreturn
- noctx
- nolintlint - nolintlint
- paralleltest
- prealloc
- predeclared
- promlinter
- revive
- rowserrcheck - rowserrcheck
- scopelint - sqlclosecheck
- staticcheck - staticcheck
- structcheck - structcheck
- stylecheck - stylecheck
- typecheck - thelper
- tparallel
- unconvert - unconvert
- unparam - unparam
- unused - unused
- varcheck - varcheck
- wastedassign
- whitespace - whitespace
- asciicheck - bidichk
- gocognit - wastedassign
- godot - golint
- godox - execinquery
- maligned - nosprintfhostport
- nestif - grouper
- prealloc - decorder
- gomodguard - errchkjson
# don't enable: - maintidx
#- goerr113 #- containedctx
#- wsl #- tagliatelle
#- testpackage #- nonamedreturns
#- exhaustive (TODO: enable after next release; current release at time of writing is v1.27) #- nilnil
#- gochecknoglobals #- tenv
#- gomnd #- varnamelen
#- contextcheck
#- errname
#- ForceTypeAssert
#- nilassign
fast: false
issues: issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
exclude:
- tools/.*
- test/.*
- third_party/.*
# Excluding configuration per-path, per-linter, per-text and per-source # Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
- linters:
- golint
path: (internal/api/.*)\.go # exclude golint for internal/api/... files
- linters:
- revive
path: (log/.*)\.go
- linters:
- wrapcheck
path: (cmd/.*|pkg/.*)\.go
- linters:
- typecheck
#path: (pkg/storage/.*)\.go
path: (internal/.*|pkg/.*)\.go
- path: (cmd/.*|test/.*|tools/.*|internal/pump/pumps/.*)\.go
linters:
- forbidigo
- path: (cmd/[a-z]*/.*|store/.*)\.go
linters:
- dupl
- linters:
- gocritic
text: (hugeParam:|rangeValCopy:)
- path: (cmd/[a-z]*/.*)\.go
linters:
- lll
- path: (validator/.*|code/.*|validator/.*|watcher/watcher/.*)
linters:
- gochecknoinits
- path: (internal/.*/options|internal/pump|pkg/log/options.go|internal/authzserver|tools/)
linters:
- tagliatelle
- path: (pkg/app/.*)\.go
linters:
- deadcode
- unused
- varcheck
- forbidigo
# Exclude some staticcheck messages
- linters:
- staticcheck
text: "SA9003:"
# Exclude lll issues for long lines with go:generate
- linters:
- lll
source: "^//go:generate "
# Independently from option `exclude` we use default exclude patterns, # Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all # it can be disabled by this option. To list all
@@ -300,24 +905,27 @@ issues:
# Show only new issues created in git patch with set file path. # Show only new issues created in git patch with set file path.
#new-from-patch: path/to/patch/file #new-from-patch: path/to/patch/file
# Fix found issues (if it's supported by the linter)
fix: true
severity: severity:
# Default value is empty string. # Default value is empty string.
# Set the default severity for issues. If severity rules are defined and the issues # Set the default severity for issues. If severity rules are defined and the issues
# do not match or no severity is provided to the rule this will be the default # do not match or no severity is provided to the rule this will be the default
# severity applied. Severities should match the supported severity names of the # severity applied. Severities should match the supported severity names of the
# selected out format. # selected out format.
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity
# - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message # - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
default-severity: error default-severity: error
# The default value is false. # The default value is false.
# If set to true severity-rules regular expressions become case sensitive. # If set to true severity-rules regular expressions become case sensitive.
case-sensitive: false case-sensitive: false
# Default value is empty list. # Default value is empty list.
# When a list of severity rules are provided, severity information will be added to lint # When a list of severity rules are provided, severity information will be added to lint
# issues. Severity rules have the same filtering capability as exclude rules except you # issues. Severity rules have the same filtering capability as exclude rules except you
# are allowed to specify one matcher per severity rule. # are allowed to specify one matcher per severity rule.
# Only affects out formats that support setting severity information. # Only affects out formats that support setting severity information.
rules: rules:
+8 -75
View File
@@ -1,23 +1,9 @@
# Version logging for OpenIM # Version logging for OpenIM
**3.0 Major refactoring**
<!-- BEGIN MUNGE: GENERATED_TOC --> <!-- BEGIN MUNGE: GENERATED_TOC -->
- [Version logging for OpenIM](#version-logging-for-openim) - [Version logging for OpenIM](#version-logging-for-openim)
- [\[v3.0\]](#v30) - [Unreleased](#unreleased)
- [v3.0.0 - 2023-07-10](#v300---2023-07-10)
- [v2.9.0+1.839643f - 2023-07-07](#v2901839643f---2023-07-07)
- [v2.9.0+2.35f07fe - 2023-07-06](#v290235f07fe---2023-07-06)
- [v2.9.0+1.b5072b1 - 2023-07-05](#v2901b5072b1---2023-07-05)
- [v2.9.0+3.2667a3a - 2023-07-05](#v29032667a3a---2023-07-05)
- [v2.9.0+7.04818ca - 2023-07-05](#v290704818ca---2023-07-05)
- [v2.9.0 - 2023-07-04](#v290---2023-07-04) - [v2.9.0 - 2023-07-04](#v290---2023-07-04)
- [v0.0.0+1.3714b4f - 2023-07-04](#v00013714b4f---2023-07-04)
- [v0.0.0+635.8b92c90 - 2023-07-04](#v0006358b92c90---2023-07-04)
- [v0.0.0+1.78a6d03 - 2023-07-04](#v000178a6d03---2023-07-04)
- [v0.0.0+2.e057c18 - 2023-07-04](#v0002e057c18---2023-07-04)
- [v0.0.0+630.b55ac4a - 2023-07-04](#v000630b55ac4a---2023-07-04)
- [Reverts](#reverts) - [Reverts](#reverts)
- [Pull Requests](#pull-requests) - [Pull Requests](#pull-requests)
- [v2.3.3 - 2022-09-18](#v233---2022-09-18) - [v2.3.3 - 2022-09-18](#v233---2022-09-18)
@@ -32,17 +18,15 @@
- [v2.0.9 - 2022-04-29](#v209---2022-04-29) - [v2.0.9 - 2022-04-29](#v209---2022-04-29)
- [Reverts](#reverts-1) - [Reverts](#reverts-1)
- [Pull Requests](#pull-requests-2) - [Pull Requests](#pull-requests-2)
- [v2.0.8 - 2022-04-24](#v208---2022-04-24)
- [Pull Requests](#pull-requests-3)
- [v2.0.7 - 2022-04-08](#v207---2022-04-08) - [v2.0.7 - 2022-04-08](#v207---2022-04-08)
- [Pull Requests](#pull-requests-4) - [Pull Requests](#pull-requests-3)
- [v2.0.6 - 2022-04-01](#v206---2022-04-01) - [v2.0.6 - 2022-04-01](#v206---2022-04-01)
- [Pull Requests](#pull-requests-5) - [Pull Requests](#pull-requests-4)
- [v2.0.5 - 2022-03-24](#v205---2022-03-24) - [v2.0.5 - 2022-03-24](#v205---2022-03-24)
- [v2.04 - 2022-03-18](#v204---2022-03-18) - [v2.04 - 2022-03-18](#v204---2022-03-18)
- [v2.0.3 - 2022-03-11](#v203---2022-03-11) - [v2.0.3 - 2022-03-11](#v203---2022-03-11)
- [v2.0.2 - 2022-03-04](#v202---2022-03-04) - [v2.0.2 - 2022-03-04](#v202---2022-03-04)
- [Pull Requests](#pull-requests-6) - [Pull Requests](#pull-requests-5)
- [v2.0.1 - 2022-02-25](#v201---2022-02-25) - [v2.0.1 - 2022-02-25](#v201---2022-02-25)
- [v2.0.0 - 2022-02-23](#v200---2022-02-23) - [v2.0.0 - 2022-02-23](#v200---2022-02-23)
- [v1.0.7 - 2021-12-17](#v107---2021-12-17) - [v1.0.7 - 2021-12-17](#v107---2021-12-17)
@@ -54,48 +38,14 @@
- [v1.0.0 - 2021-10-28](#v100---2021-10-28) - [v1.0.0 - 2021-10-28](#v100---2021-10-28)
- [Reverts](#reverts-2) - [Reverts](#reverts-2)
<!-- END MUNGE: GENERATED_TOC --> <!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a> <a name="unreleased"></a>
## [v3.0] ## [Unreleased]
<a name="v3.0.0"></a>
## [v3.0.0] - 2023-07-10
<a name="v2.9.0+1.839643f"></a>
## [v2.9.0+1.839643f] - 2023-07-07
<a name="v2.9.0+2.35f07fe"></a>
## [v2.9.0+2.35f07fe] - 2023-07-06
<a name="v2.9.0+1.b5072b1"></a>
## [v2.9.0+1.b5072b1] - 2023-07-05
<a name="v2.9.0+3.2667a3a"></a>
## [v2.9.0+3.2667a3a] - 2023-07-05
<a name="v2.9.0+7.04818ca"></a>
## [v2.9.0+7.04818ca] - 2023-07-05
<a name="v2.9.0"></a> <a name="v2.9.0"></a>
## [v2.9.0] - 2023-07-04 ## [v2.9.0] - 2023-07-04
<a name="v0.0.0+1.3714b4f"></a>
## [v0.0.0+1.3714b4f] - 2023-07-04
<a name="v0.0.0+635.8b92c90"></a>
## [v0.0.0+635.8b92c90] - 2023-07-04
<a name="v0.0.0+1.78a6d03"></a>
## [v0.0.0+1.78a6d03] - 2023-07-04
<a name="v0.0.0+2.e057c18"></a>
## [v0.0.0+2.e057c18] - 2023-07-04
<a name="v0.0.0+630.b55ac4a"></a>
## [v0.0.0+630.b55ac4a] - 2023-07-04
### Reverts ### Reverts
- update etcd to v3.5.2 ([#206](https://github.com/OpenIMSDK/Open-IM-Server/issues/206)) - update etcd to v3.5.2 ([#206](https://github.com/OpenIMSDK/Open-IM-Server/issues/206))
@@ -144,11 +94,6 @@
- Merge branch 'tuoyun' - Merge branch 'tuoyun'
- Merge branch 'tuoyun' - Merge branch 'tuoyun'
- Merge branch 'tuoyun' - Merge branch 'tuoyun'
<a name="v2.0.8"></a>
## [v2.0.8] - 2022-04-24
### Pull Requests
- Merge branch 'tuoyun' - Merge branch 'tuoyun'
- Merge branch 'tuoyun' - Merge branch 'tuoyun'
@@ -216,19 +161,8 @@
- update - update
[Unreleased]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.0.0...HEAD [Unreleased]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0...HEAD
[v3.0.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+1.839643f...v3.0.0 [v2.9.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.3...v2.9.0
[v2.9.0+1.839643f]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+2.35f07fe...v2.9.0+1.839643f
[v2.9.0+2.35f07fe]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+1.b5072b1...v2.9.0+2.35f07fe
[v2.9.0+1.b5072b1]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+3.2667a3a...v2.9.0+1.b5072b1
[v2.9.0+3.2667a3a]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+7.04818ca...v2.9.0+3.2667a3a
[v2.9.0+7.04818ca]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0...v2.9.0+7.04818ca
[v2.9.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v0.0.0+1.3714b4f...v2.9.0
[v0.0.0+1.3714b4f]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v0.0.0+635.8b92c90...v0.0.0+1.3714b4f
[v0.0.0+635.8b92c90]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v0.0.0+1.78a6d03...v0.0.0+635.8b92c90
[v0.0.0+1.78a6d03]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v0.0.0+2.e057c18...v0.0.0+1.78a6d03
[v0.0.0+2.e057c18]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v0.0.0+630.b55ac4a...v0.0.0+2.e057c18
[v0.0.0+630.b55ac4a]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.3...v0.0.0+630.b55ac4a
[v2.3.3]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.2...v2.3.3 [v2.3.3]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.2...v2.3.3
[v2.3.2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.0-rc2...v2.3.2 [v2.3.2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.0-rc2...v2.3.2
[v2.3.0-rc2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.0-rc1...v2.3.0-rc2 [v2.3.0-rc2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.0-rc1...v2.3.0-rc2
@@ -237,8 +171,7 @@
[v2.2.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.1.0...v2.2.0 [v2.2.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.1.0...v2.2.0
[v2.1.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.10...v2.1.0 [v2.1.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.10...v2.1.0
[v2.0.10]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.9...v2.0.10 [v2.0.10]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.9...v2.0.10
[v2.0.9]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.8...v2.0.9 [v2.0.9]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.7...v2.0.9
[v2.0.8]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.7...v2.0.8
[v2.0.7]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.6...v2.0.7 [v2.0.7]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.6...v2.0.7
[v2.0.6]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.5...v2.0.6 [v2.0.6]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.5...v2.0.6
[v2.0.5]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.04...v2.0.5 [v2.0.5]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.04...v2.0.5
+76 -1
View File
@@ -1,5 +1,16 @@
# Changelog # Changelog
- [Changelog](#changelog)
- [command](#command)
- [create next tag](#create-next-tag)
- [Release version logs](#release-version-logs)
- [Introduction](#introduction)
- [Naming Format](#naming-format)
- [Examples](#examples)
- [Version Modifiers](#version-modifiers)
- [Versioning Strategy](#versioning-strategy)
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
+ [https://github.com/OpenIMSDK/Open-IM-Server/releases](https://github.com/OpenIMSDK/Open-IM-Server/releases) + [https://github.com/OpenIMSDK/Open-IM-Server/releases](https://github.com/OpenIMSDK/Open-IM-Server/releases)
@@ -18,6 +29,14 @@ git commit -am "release 2.0.0"
git tag 2.0.0 git tag 2.0.0
``` ```
| Query | Description | Example |
| -------------- | ---------------------------------------------- | --------------------------- |
| `<old>..<new>` | Commit contained in `<new>` tags from `<old>`. | `$ git-chglog 1.0.0..2.0.0` |
| `<name>..` | Commit from the `<name>` to the latest tag. | `$ git-chglog 1.0.0..` |
| `..<name>` | Commit from the oldest tag to `<name>`. | `$ git-chglog ..2.0.0` |
| `<name>` | Commit contained in `<name>`. | `$ git-chglog 1.0.0` |
## Release version logs ## Release version logs
+ [OpenIM CHANGELOG-V1.0](CHANGELOG-1.0.md) + [OpenIM CHANGELOG-V1.0](CHANGELOG-1.0.md)
@@ -26,4 +45,60 @@ git tag 2.0.0
+ [OpenIM CHANGELOG-V2.2](CHANGELOG-2.2.md) + [OpenIM CHANGELOG-V2.2](CHANGELOG-2.2.md)
+ [OpenIM CHANGELOG-V2.3](CHANGELOG-2.3.md) + [OpenIM CHANGELOG-V2.3](CHANGELOG-2.3.md)
+ [OpenIM CHANGELOG-V2.9](CHANGELOG-2.9.md) + [OpenIM CHANGELOG-V2.9](CHANGELOG-2.9.md)
+ [OpenIM CHANGELOG-V3.0](CHANGELOG-3.0.md) + [OpenIM CHANGELOG-V3.0](CHANGELOG-3.0.md)
## Introduction
In both the open-source and closed-source software development communities, it is important to follow a consistent and understandable versioning scheme for software projects. This ensures clear communication of changes, compatibility, and stability across different releases. One widely adopted naming convention is the Semantic Versioning 2.0.0.
## Naming Format
The most common format for version numbers is as follows:
```
major.minor[.patch[.build]]
```
Let's take a closer look at each component:
1. **Major Version**: This is the first number in the versioning scheme and indicates significant changes that may not be backward compatible (specific to each project).
2. **Minor Version**: The second number signifies the addition of new features while maintaining backward compatibility.
3. **Patch Version**: The third number represents bug fixes or code optimizations without introducing new features. It is generally backward compatible.
4. **Build Version**: Typically an automatically generated number that increments with each code commit.
## Examples
Here are a few examples to illustrate the versioning scheme:
1. `1.0`
2. `2.14.0.1478`
3. `3.2.1 build-354`
## Version Modifiers
Apart from the version numbers, there are also version modifiers used to indicate specific stages or statuses of a release. Some commonly used version modifiers include:
- **alpha**: An internal testing version with numerous known bugs. It is primarily used for communication among developers.
- **beta**: A testing version released to enthusiastic users for feedback and bug detection.
- **rc (release candidate)**: The final testing version before the official release.
- **ga (general availability)**: The initial stable release for public distribution.
- **r/release** (or no modifier at all): The final released version intended for general users.
- **lts (long-term support)**: Designates a version that will receive extended maintenance and bug fixes for a specified number of years.
## Versioning Strategy
To effectively manage version numbers, the following strategies are commonly employed:
- The initial version of a project can be either `0.1` or `1.0`.
- When fixing bugs, the patch version is incremented by 1.
- When adding new features, the minor version is incremented by 1, and the patch version is reset to 0.
- In the case of significant modifications, the major version is incremented by 1.
- The build version is usually automatically generated by the compilation process and follows a defined format. It does not require manual control.
By adhering to these strategies and guidelines, developers can maintain consistency and clarity in versioning their software projects. This enables users and collaborators to understand the nature of changes between different releases and ensure compatibility with their systems.
(Note: Markdown formatting has been used to structure this article. Markdown is a lightweight markup language used to format text on platforms like GitHub.)
------
**Note**: The above article is based on the given content and aims to provide a Markdown-formatted English article explaining the naming conventions for software project versions, specifically focusing on the Semantic Versioning 2.0.0.
+23 -26
View File
@@ -1,39 +1,36 @@
FROM golang as build # Build Stage
FROM golang:1.20 AS builder
# go mod Installation source, container environment variable addition will override the default variable value LABEL org.opencontainers.image.source=https://github.com/OpenIMSDK/Open-IM-Server
ENV GO111MODULE=on LABEL org.opencontainers.image.description="OpenIM Server image"
ENV GOPROXY=https://goproxy.cn,direct LABEL org.opencontainers.image.licenses="Apache 2.0"
# Set go mod installation source and proxy
ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct
ENV GO111MODULE=$GO111MODULE
ENV GOPROXY=$GOPROXY
# Set up the working directory # Set up the working directory
WORKDIR /Open-IM-Server WORKDIR /Open-IM-Server
# add all files to the container
COPY . .
WORKDIR /Open-IM-Server/scripts # Copy all files to the container
RUN chmod +x *.sh ADD . .
RUN /bin/sh -c ./build_all_service.sh RUN /bin/sh -c "make build"
#Blank image Multi-Stage Build # Production Stage
FROM ubuntu FROM alpine
RUN rm -rf /var/lib/apt/lists/* RUN apk --no-cache add tzdata
RUN apt-get update && apt-get install apt-transport-https && apt-get install procps\
&&apt-get install net-tools
#Non-interactive operation
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get install -y vim curl tzdata gawk
#Time zone adjusted to East eighth District
RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && dpkg-reconfigure -f noninteractive tzdata
# Set directory to map logs, config files, scripts, and SDK
VOLUME ["/Open-IM-Server/logs", "/Open-IM-Server/config", "/Open-IM-Server/scripts", "/Open-IM-Server/db/sdk"]
#set directory to map logs,config file,scripts file. # Copy scripts and binary files to the production image
VOLUME ["/Open-IM-Server/logs","/Open-IM-Server/config","/Open-IM-Server/scripts","/Open-IM-Server/db/sdk"] COPY --from=builder /Open-IM-Server/scripts /Open-IM-Server/scripts
COPY --from=builder /Open-IM-Server/_output/bin/platforms/linux/amd64 /Open-IM-Server/_output/bin/platforms/linux/amd64
#Copy scripts files and binary files to the blank image
COPY --from=build /Open-IM-Server/scripts /Open-IM-Server/scripts
COPY --from=build /Open-IM-Server/_output/bin/platforms/linux/amd64 /Open-IM-Server/_output/bin/platforms/linux/amd64
WORKDIR /Open-IM-Server/scripts WORKDIR /Open-IM-Server/scripts
CMD ["./docker_start_all.sh"] CMD ["docker_start_all.sh"]
+1 -2
View File
@@ -18,12 +18,12 @@ import (
"context" "context"
"fmt" "fmt"
"net" "net"
"net/http"
"os" "os"
"runtime" "runtime"
"strconv" "strconv"
"time" "time"
"net/http"
_ "net/http/pprof" _ "net/http/pprof"
"github.com/OpenIMSDK/Open-IM-Server/internal/api" "github.com/OpenIMSDK/Open-IM-Server/internal/api"
@@ -76,7 +76,6 @@ func run(port int) error {
if err := client.CreateRpcRootNodes(config.GetServiceNames()); err != nil { if err := client.CreateRpcRootNodes(config.GetServiceNames()); err != nil {
return err return err
} }
fmt.Println("api init discov client success")
fmt.Println("api register public config to discov") fmt.Println("api register public config to discov")
if err := client.RegisterConf2Registry(constant.OpenIMCommonConfigKey, config.EncodeConfig()); err != nil { if err := client.RegisterConf2Registry(constant.OpenIMCommonConfigKey, config.EncodeConfig()); err != nil {
return err return err
+14
View File
@@ -1,3 +1,17 @@
// 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 main package main
import ( import (
+4 -4
View File
@@ -117,10 +117,10 @@ rpcRegisterName: #rpc注册服务名,不建议修改
openImThirdName: Third openImThirdName: Third
log: log:
storageLocation: ../logs/ #存放目录 storageLocation: ../../../../../logs/ #存放目录
rotationTime: 24 #日志旋转时间 rotationTime: 24 #日志旋转时间
remainRotationCount: 2 #日志数量 remainRotationCount: 2 #日志数量
remainLogLevel: 6 #日志级别 6表示全都打印, remainLogLevel: 6 #日志级别 6表示全都打印,
isStdout: false isStdout: false
isJson: false isJson: false
withStack: false withStack: false
+1 -3
View File
@@ -5,7 +5,7 @@ go 1.18
require ( require (
firebase.google.com/go v3.13.0+incompatible firebase.google.com/go v3.13.0+incompatible
github.com/OpenIMSDK/open_utils v1.0.8 github.com/OpenIMSDK/open_utils v1.0.8
github.com/Shopify/sarama v1.32.0 github.com/Shopify/sarama v1.29.0
github.com/bwmarrin/snowflake v0.3.0 github.com/bwmarrin/snowflake v0.3.0
github.com/dtm-labs/rockscache v0.1.1 github.com/dtm-labs/rockscache v0.1.1
github.com/gin-gonic/gin v1.9.1 github.com/gin-gonic/gin v1.9.1
@@ -141,5 +141,3 @@ require (
google.golang.org/genproto v0.0.0-20230525234025-438c736192d0 // indirect google.golang.org/genproto v0.0.0-20230525234025-438c736192d0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
) )
replace github.com/Shopify/sarama => github.com/Shopify/sarama v1.29.0
+4
View File
@@ -9,6 +9,10 @@ source .env
echo $MINIO_ENDPOINT echo $MINIO_ENDPOINT
# Replace local IP address with the public IP address in .env file # Replace local IP address with the public IP address in .env file
if [ $API_URL == "http://127.0.0.1:10002/object/" ]; then
sed -i "s/127.0.0.1/${internet_ip}/" .env
fi
if [ $MINIO_ENDPOINT == "http://127.0.0.1:10005" ]; then if [ $MINIO_ENDPOINT == "http://127.0.0.1:10005" ]; then
sed -i "s/127.0.0.1/${internet_ip}/" .env sed -i "s/127.0.0.1/${internet_ip}/" .env
fi fi
+2 -3
View File
@@ -18,15 +18,14 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r" "github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/auth" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/auth"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
) )
type AuthApi rpcclient.Auth type AuthApi rpcclient.Auth
func NewAuthApi(discov discoveryregistry.SvcDiscoveryRegistry) AuthApi { func NewAuthApi(client rpcclient.Auth) AuthApi {
return AuthApi(*rpcclient.NewAuth(discov)) return AuthApi(client)
} }
func (o *AuthApi) UserToken(c *gin.Context) { func (o *AuthApi) UserToken(c *gin.Context) {
+2 -3
View File
@@ -18,15 +18,14 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r" "github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
) )
type ConversationApi rpcclient.Conversation type ConversationApi rpcclient.Conversation
func NewConversationApi(discov discoveryregistry.SvcDiscoveryRegistry) ConversationApi { func NewConversationApi(client rpcclient.Conversation) ConversationApi {
return ConversationApi(*rpcclient.NewConversation(discov)) return ConversationApi(client)
} }
func (o *ConversationApi) GetAllConversations(c *gin.Context) { func (o *ConversationApi) GetAllConversations(c *gin.Context) {
+2 -3
View File
@@ -16,7 +16,6 @@ package api
import ( import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r" "github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/friend" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/friend"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
@@ -25,8 +24,8 @@ import (
type FriendApi rpcclient.Friend type FriendApi rpcclient.Friend
func NewFriendApi(discov discoveryregistry.SvcDiscoveryRegistry) FriendApi { func NewFriendApi(client rpcclient.Friend) FriendApi {
return FriendApi(*rpcclient.NewFriend(discov)) return FriendApi(client)
} }
func (o *FriendApi) ApplyToAddFriend(c *gin.Context) { func (o *FriendApi) ApplyToAddFriend(c *gin.Context) {
+6 -3
View File
@@ -16,7 +16,6 @@ package api
import ( import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r" "github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
@@ -25,8 +24,8 @@ import (
type GroupApi rpcclient.Group type GroupApi rpcclient.Group
func NewGroupApi(discov discoveryregistry.SvcDiscoveryRegistry) GroupApi { func NewGroupApi(client rpcclient.Group) GroupApi {
return GroupApi(*rpcclient.NewGroup(discov)) return GroupApi(client)
} }
func (o *GroupApi) CreateGroup(c *gin.Context) { func (o *GroupApi) CreateGroup(c *gin.Context) {
@@ -132,3 +131,7 @@ func (o *GroupApi) GetSuperGroupsInfo(c *gin.Context) {
func (o *GroupApi) GroupCreateCount(c *gin.Context) { func (o *GroupApi) GroupCreateCount(c *gin.Context) {
a2r.Call(group.GroupClient.GroupCreateCount, o.Client, c) a2r.Call(group.GroupClient.GroupCreateCount, o.Client, c)
} }
func (o *GroupApi) GetGroups(c *gin.Context) {
a2r.Call(group.GroupClient.GetGroups, o.Client, c)
}
+103 -33
View File
@@ -26,7 +26,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
@@ -35,12 +34,13 @@ import (
) )
type MessageApi struct { type MessageApi struct {
rpcclient.Message *rpcclient.Message
validate *validator.Validate validate *validator.Validate
userRpcClient *rpcclient.UserRpcClient
} }
func NewMessageApi(discov discoveryregistry.SvcDiscoveryRegistry) MessageApi { func NewMessageApi(msgRpcClient *rpcclient.Message, userRpcClient *rpcclient.User) MessageApi {
return MessageApi{Message: *rpcclient.NewMessage(discov), validate: validator.New()} return MessageApi{Message: msgRpcClient, validate: validator.New(), userRpcClient: rpcclient.NewUserRpcClientByUser(userRpcClient)}
} }
func (MessageApi) SetOptions(options map[string]bool, value bool) { func (MessageApi) SetOptions(options map[string]bool, value bool) {
@@ -50,9 +50,10 @@ func (MessageApi) SetOptions(options map[string]bool, value bool) {
utils.SetSwitchFromOptions(options, constant.IsConversationUpdate, value) utils.SetSwitchFromOptions(options, constant.IsConversationUpdate, value)
} }
func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.ManagementSendMsgReq) *msg.SendMsgReq { func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.SendMsg) *msg.SendMsgReq {
var newContent string var newContent string
var err error var err error
options := make(map[string]bool, 5)
switch params.ContentType { switch params.ContentType {
case constant.Text: case constant.Text:
newContent = params.Content["text"].(string) newContent = params.Content["text"].(string)
@@ -70,11 +71,9 @@ func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.Manageme
fallthrough fallthrough
case constant.CustomOnlineOnly: case constant.CustomOnlineOnly:
fallthrough fallthrough
case constant.Revoke:
newContent = params.Content["revokeMsgClientID"].(string)
default: default:
newContent = utils.StructToJsonString(params.Content)
} }
options := make(map[string]bool, 5)
if params.IsOnlineOnly { if params.IsOnlineOnly {
m.SetOptions(options, false) m.SetOptions(options, false)
} }
@@ -98,7 +97,6 @@ func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.Manageme
MsgFrom: constant.SysMsgType, MsgFrom: constant.SysMsgType,
ContentType: params.ContentType, ContentType: params.ContentType,
Content: []byte(newContent), Content: []byte(newContent),
RecvID: params.RecvID,
CreateTime: utils.GetCurrentTimestampByMill(), CreateTime: utils.GetCurrentTimestampByMill(),
Options: options, Options: options,
OfflinePushInfo: params.OfflinePushInfo, OfflinePushInfo: params.OfflinePushInfo,
@@ -163,19 +161,9 @@ func (m *MessageApi) DeleteMsgPhysical(c *gin.Context) {
a2r.Call(msg.MsgClient.DeleteMsgPhysical, m.Client, c) a2r.Call(msg.MsgClient.DeleteMsgPhysical, m.Client, c)
} }
func (m *MessageApi) SendMessage(c *gin.Context) { func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendMsgReq *msg.SendMsgReq, err error) {
params := apistruct.ManagementSendMsgReq{}
if err := c.BindJSON(&params); err != nil {
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
return
}
if !tokenverify.IsAppManagerUid(c) {
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
return
}
var data interface{} var data interface{}
switch params.ContentType { switch req.ContentType {
case constant.Text: case constant.Text:
data = apistruct.TextElem{} data = apistruct.TextElem{}
case constant.Picture: case constant.Picture:
@@ -192,25 +180,45 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
data = apistruct.RevokeElem{} data = apistruct.RevokeElem{}
case constant.OANotification: case constant.OANotification:
data = apistruct.OANotificationElem{} data = apistruct.OANotificationElem{}
params.SessionType = constant.NotificationChatType req.SessionType = constant.NotificationChatType
case constant.CustomNotTriggerConversation: case constant.CustomNotTriggerConversation:
data = apistruct.CustomElem{} data = apistruct.CustomElem{}
case constant.CustomOnlineOnly: case constant.CustomOnlineOnly:
data = apistruct.CustomElem{} data = apistruct.CustomElem{}
default: default:
apiresp.GinError(c, errs.ErrArgs.WithDetail("not support err contentType").Wrap()) return nil, errs.ErrArgs.WithDetail("not support err contentType")
}
if err := mapstructure.WeakDecode(req.Content, &data); err != nil {
return nil, err
}
log.ZDebug(c, "getSendMsgReq", "data", data)
if err := m.validate.Struct(data); err != nil {
return nil, err
}
return m.newUserSendMsgReq(c, &req), nil
}
func (m *MessageApi) SendMessage(c *gin.Context) {
req := apistruct.SendMsgReq{}
if err := c.BindJSON(&req); err != nil {
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
return return
} }
if err := mapstructure.WeakDecode(params.Content, &data); err != nil { log.ZInfo(c, "SendMessage", "req", req)
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error())) if !tokenverify.IsAppManagerUid(c) {
return apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
} else if err := m.validate.Struct(data); err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return return
} }
pbReq := m.newUserSendMsgReq(c, &params)
sendMsgReq, err := m.getSendMsgReq(c, req.SendMsg)
if err != nil {
log.ZError(c, "decodeData failed", err)
apiresp.GinError(c, err)
return
}
sendMsgReq.MsgData.RecvID = req.RecvID
var status int var status int
respPb, err := m.Client.SendMsg(c, pbReq) respPb, err := m.Client.SendMsg(c, sendMsgReq)
if err != nil { if err != nil {
status = constant.MsgSendFailed status = constant.MsgSendFailed
apiresp.GinError(c, err) apiresp.GinError(c, err)
@@ -226,8 +234,66 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
apiresp.GinSuccess(c, respPb) apiresp.GinSuccess(c, respPb)
} }
func (m *MessageApi) ManagementBatchSendMsg(c *gin.Context) { func (m *MessageApi) BatchSendMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.SendMsg, m.Client, c) var (
req apistruct.BatchSendMsgReq
resp apistruct.BatchSendMsgResp
)
if err := c.BindJSON(&req); err != nil {
log.ZError(c, "BatchSendMsg BindJSON failed", err)
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
return
}
log.ZInfo(c, "BatchSendMsg", "req", req)
if err := tokenverify.CheckAdmin(c); err != nil {
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
return
}
var recvIDs []string
var err error
if req.IsSendAll {
pageNumber := 1
showNumber := 500
for {
recvIDsPart, err := m.userRpcClient.GetAllUserIDs(c, int32(pageNumber), int32(showNumber))
if err != nil {
log.ZError(c, "GetAllUserIDs failed", err)
apiresp.GinError(c, err)
return
}
if len(recvIDsPart) < showNumber {
recvIDs = append(recvIDs, recvIDsPart...)
break
}
pageNumber++
}
} else {
recvIDs = req.RecvIDs
}
log.ZDebug(c, "BatchSendMsg nums", "nums ", len(recvIDs))
sendMsgReq, err := m.getSendMsgReq(c, req.SendMsg)
if err != nil {
log.ZError(c, "decodeData failed", err)
apiresp.GinError(c, err)
return
}
for _, recvID := range recvIDs {
sendMsgReq.MsgData.RecvID = recvID
rpcResp, err := m.Client.SendMsg(c, sendMsgReq)
if err != nil {
resp.FailedIDs = append(resp.FailedIDs, recvID)
continue
}
resp.Results = append(resp.Results, &apistruct.SingleReturnResult{
ServerMsgID: rpcResp.ServerMsgID,
ClientMsgID: rpcResp.ClientMsgID,
SendTime: rpcResp.SendTime,
RecvID: recvID,
})
}
apiresp.GinSuccess(c, resp)
} }
func (m *MessageApi) CheckMsgIsSendSuccess(c *gin.Context) { func (m *MessageApi) CheckMsgIsSendSuccess(c *gin.Context) {
@@ -245,3 +311,7 @@ func (m *MessageApi) GetActiveUser(c *gin.Context) {
func (m *MessageApi) GetActiveGroup(c *gin.Context) { func (m *MessageApi) GetActiveGroup(c *gin.Context) {
a2r.Call(msg.MsgClient.GetActiveGroup, m.Client, c) a2r.Call(msg.MsgClient.GetActiveGroup, m.Client, c)
} }
func (m *MessageApi) SearchMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.SearchMessage, m.Client, c)
}
+25 -13
View File
@@ -29,6 +29,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
) )
func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient) *gin.Engine { func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient) *gin.Engine {
@@ -40,8 +41,17 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
} }
log.ZInfo(context.Background(), "load config", "config", config.Config) log.ZInfo(context.Background(), "load config", "config", config.Config)
r.Use(gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID()) r.Use(gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID())
u := NewUserApi(discov) // init rpc client here
m := NewMessageApi(discov) userRpc := rpcclient.NewUser(discov)
groupRpc := rpcclient.NewGroup(discov)
friendRpc := rpcclient.NewFriend(discov)
messageRpc := rpcclient.NewMessage(discov)
conversationRpc := rpcclient.NewConversation(discov)
authRpc := rpcclient.NewAuth(discov)
thirdRpc := rpcclient.NewThird(discov)
u := NewUserApi(*userRpc)
m := NewMessageApi(messageRpc, userRpc)
if config.Config.Prometheus.Enable { if config.Config.Prometheus.Enable {
prome.NewApiRequestCounter() prome.NewApiRequestCounter()
prome.NewApiRequestFailedCounter() prome.NewApiRequestFailedCounter()
@@ -62,10 +72,10 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
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)
} }
//friend routing group // friend routing group
friendRouterGroup := r.Group("/friend", ParseToken) friendRouterGroup := r.Group("/friend", ParseToken)
{ {
f := NewFriendApi(discov) f := NewFriendApi(*friendRpc)
friendRouterGroup.POST("/delete_friend", f.DeleteFriend) friendRouterGroup.POST("/delete_friend", f.DeleteFriend)
friendRouterGroup.POST("/get_friend_apply_list", f.GetFriendApplyList) friendRouterGroup.POST("/get_friend_apply_list", f.GetFriendApplyList)
friendRouterGroup.POST("/get_self_friend_apply_list", f.GetSelfApplyList) friendRouterGroup.POST("/get_self_friend_apply_list", f.GetSelfApplyList)
@@ -79,7 +89,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
friendRouterGroup.POST("/import_friend", f.ImportFriends) friendRouterGroup.POST("/import_friend", f.ImportFriends)
friendRouterGroup.POST("/is_friend", f.IsFriend) friendRouterGroup.POST("/is_friend", f.IsFriend)
} }
g := NewGroupApi(discov) g := NewGroupApi(*groupRpc)
groupRouterGroup := r.Group("/group", ParseToken) groupRouterGroup := r.Group("/group", ParseToken)
{ {
groupRouterGroup.POST("/create_group", g.CreateGroup) groupRouterGroup.POST("/create_group", g.CreateGroup)
@@ -103,24 +113,25 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
groupRouterGroup.POST("/cancel_mute_group", g.CancelMuteGroup) groupRouterGroup.POST("/cancel_mute_group", g.CancelMuteGroup)
groupRouterGroup.POST("/set_group_member_info", g.SetGroupMemberInfo) groupRouterGroup.POST("/set_group_member_info", g.SetGroupMemberInfo)
groupRouterGroup.POST("/get_group_abstract_info", g.GetGroupAbstractInfo) groupRouterGroup.POST("/get_group_abstract_info", g.GetGroupAbstractInfo)
groupRouterGroup.POST("/get_groups", g.GetGroups)
} }
superGroupRouterGroup := r.Group("/super_group", ParseToken) superGroupRouterGroup := r.Group("/super_group", ParseToken)
{ {
superGroupRouterGroup.POST("/get_joined_group_list", g.GetJoinedSuperGroupList) superGroupRouterGroup.POST("/get_joined_group_list", g.GetJoinedSuperGroupList)
superGroupRouterGroup.POST("/get_groups_info", g.GetSuperGroupsInfo) superGroupRouterGroup.POST("/get_groups_info", g.GetSuperGroupsInfo)
} }
//certificate // certificate
authRouterGroup := r.Group("/auth") authRouterGroup := r.Group("/auth")
{ {
a := NewAuthApi(discov) a := NewAuthApi(*authRpc)
authRouterGroup.POST("/user_token", a.UserToken) authRouterGroup.POST("/user_token", a.UserToken)
authRouterGroup.POST("/parse_token", a.ParseToken) authRouterGroup.POST("/parse_token", a.ParseToken)
authRouterGroup.POST("/force_logout", ParseToken, a.ForceLogout) authRouterGroup.POST("/force_logout", ParseToken, a.ForceLogout)
} }
//Third service // Third service
thirdGroup := r.Group("/third", ParseToken) thirdGroup := r.Group("/third", ParseToken)
{ {
t := NewThirdApi(discov) t := NewThirdApi(*thirdRpc)
thirdGroup.POST("/fcm_update_token", t.FcmUpdateToken) thirdGroup.POST("/fcm_update_token", t.FcmUpdateToken)
thirdGroup.POST("/set_app_badge", t.SetAppBadge) thirdGroup.POST("/set_app_badge", t.SetAppBadge)
@@ -134,10 +145,11 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
objectGroup.POST("/access_url", t.AccessURL) objectGroup.POST("/access_url", t.AccessURL)
objectGroup.GET("/*name", t.ObjectRedirect) objectGroup.GET("/*name", t.ObjectRedirect)
} }
//Message // Message
msgGroup := r.Group("/msg", ParseToken) msgGroup := r.Group("/msg", ParseToken)
{ {
msgGroup.POST("/newest_seq", m.GetSeq) msgGroup.POST("/newest_seq", m.GetSeq)
msgGroup.POST("/search_msg", m.SearchMsg)
msgGroup.POST("/send_msg", m.SendMessage) msgGroup.POST("/send_msg", m.SendMessage)
msgGroup.POST("/pull_msg_by_seq", m.PullMsgBySeqs) msgGroup.POST("/pull_msg_by_seq", m.PullMsgBySeqs)
msgGroup.POST("/revoke_msg", m.RevokeMsg) msgGroup.POST("/revoke_msg", m.RevokeMsg)
@@ -152,13 +164,13 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
msgGroup.POST("/delete_msg_phsical_by_seq", m.DeleteMsgPhysicalBySeq) msgGroup.POST("/delete_msg_phsical_by_seq", m.DeleteMsgPhysicalBySeq)
msgGroup.POST("/delete_msg_physical", m.DeleteMsgPhysical) msgGroup.POST("/delete_msg_physical", m.DeleteMsgPhysical)
msgGroup.POST("/batch_send_msg", m.ManagementBatchSendMsg) 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)
} }
//Conversation // Conversation
conversationGroup := r.Group("/conversation", ParseToken) conversationGroup := r.Group("/conversation", ParseToken)
{ {
c := NewConversationApi(discov) c := NewConversationApi(*conversationRpc)
conversationGroup.POST("/get_all_conversations", c.GetAllConversations) conversationGroup.POST("/get_all_conversations", c.GetAllConversations)
conversationGroup.POST("/get_conversation", c.GetConversation) conversationGroup.POST("/get_conversation", c.GetConversation)
conversationGroup.POST("/get_conversations", c.GetConversations) conversationGroup.POST("/get_conversations", c.GetConversations)
+2 -3
View File
@@ -18,15 +18,14 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r" "github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
) )
type StatisticsApi rpcclient.User type StatisticsApi rpcclient.User
func NewStatisticsApi(discov discoveryregistry.SvcDiscoveryRegistry) StatisticsApi { func NewStatisticsApi(client rpcclient.User) StatisticsApi {
return StatisticsApi(*rpcclient.NewUser(discov)) return StatisticsApi(client)
} }
func (s *StatisticsApi) UserRegister(c *gin.Context) { func (s *StatisticsApi) UserRegister(c *gin.Context) {
+24 -9
View File
@@ -1,22 +1,37 @@
// 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 api package api
import ( import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/gin-gonic/gin"
"math/rand" "math/rand"
"net/http" "net/http"
"strconv" "strconv"
"github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
) )
type ThirdApi rpcclient.Third type ThirdApi rpcclient.Third
func NewThirdApi(discov discoveryregistry.SvcDiscoveryRegistry) ThirdApi { func NewThirdApi(client rpcclient.Third) ThirdApi {
return ThirdApi(*rpcclient.NewThird(discov)) return ThirdApi(client)
} }
func (o *ThirdApi) FcmUpdateToken(c *gin.Context) { func (o *ThirdApi) FcmUpdateToken(c *gin.Context) {
+6 -9
View File
@@ -22,7 +22,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msggateway" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msggateway"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user"
@@ -31,8 +30,8 @@ import (
type UserApi rpcclient.User type UserApi rpcclient.User
func NewUserApi(discov discoveryregistry.SvcDiscoveryRegistry) UserApi { func NewUserApi(client rpcclient.User) UserApi {
return UserApi(*rpcclient.NewUser(discov)) return UserApi(client)
} }
func (u *UserApi) UserRegister(c *gin.Context) { func (u *UserApi) UserRegister(c *gin.Context) {
@@ -79,12 +78,12 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
var respResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult var respResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult
flag := false flag := false
//Online push message // Online push message
for _, v := range conns { for _, v := range conns {
msgClient := msggateway.NewMsgGatewayClient(v) msgClient := msggateway.NewMsgGatewayClient(v)
reply, err := msgClient.GetUsersOnlineStatus(c, &req) reply, err := msgClient.GetUsersOnlineStatus(c, &req)
if err != nil { if err != nil {
log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) log.ZWarn(c, "GetUsersOnlineStatus rpc err", err)
continue continue
} else { } else {
wsResult = append(wsResult, reply.SuccessResult...) wsResult = append(wsResult, reply.SuccessResult...)
@@ -107,7 +106,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
} }
if !flag { if !flag {
res.UserID = v1 res.UserID = v1
res.Status = constant.OnlineStatus res.Status = constant.OfflineStatus
} }
respResult = append(respResult, res) respResult = append(respResult, res)
} }
@@ -132,7 +131,7 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
apiresp.GinError(c, err) apiresp.GinError(c, err)
return return
} }
//Online push message // Online push message
for _, v := range conns { for _, v := range conns {
msgClient := msggateway.NewMsgGatewayClient(v) msgClient := msggateway.NewMsgGatewayClient(v)
reply, err := msgClient.GetUsersOnlineStatus(c, &req) reply, err := msgClient.GetUsersOnlineStatus(c, &req)
@@ -161,7 +160,6 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
} }
} }
} }
} }
for p, tokens := range m { for p, tokens := range m {
t := new(msggateway.SinglePlatformToken) t := new(msggateway.SinglePlatformToken)
@@ -177,5 +175,4 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
} }
apiresp.GinSuccess(c, respResult) apiresp.GinSuccess(c, respResult)
} }
+34 -15
View File
@@ -21,19 +21,22 @@ import (
"runtime/debug" "runtime/debug"
"sync" "sync"
"google.golang.org/protobuf/proto"
"github.com/OpenIMSDK/Open-IM-Server/pkg/apiresp" "github.com/OpenIMSDK/Open-IM-Server/pkg/apiresp"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"google.golang.org/protobuf/proto"
) )
var ErrConnClosed = errors.New("conn has closed") var (
var ErrNotSupportMessageProtocol = errors.New("not support message protocol") ErrConnClosed = errors.New("conn has closed")
var ErrClientClosed = errors.New("client actively close the connection") ErrNotSupportMessageProtocol = errors.New("not support message protocol")
var ErrPanic = errors.New("panic error") ErrClientClosed = errors.New("client actively close the connection")
ErrPanic = errors.New("panic error")
)
const ( const (
// MessageText is for UTF-8 encoded text messages like JSON. // MessageText is for UTF-8 encoded text messages like JSON.
@@ -80,7 +83,14 @@ func newClient(ctx *UserConnContext, conn LongConn, isCompress bool) *Client {
ctx: ctx, ctx: ctx,
} }
} }
func (c *Client) ResetClient(ctx *UserConnContext, conn LongConn, isBackground, isCompress bool, longConnServer LongConnServer, token string) {
func (c *Client) ResetClient(
ctx *UserConnContext,
conn LongConn,
isBackground, isCompress bool,
longConnServer LongConnServer,
token string,
) {
c.w = new(sync.Mutex) c.w = new(sync.Mutex)
c.conn = conn c.conn = conn
c.PlatformID = utils.StringToInt(ctx.GetPlatformID()) c.PlatformID = utils.StringToInt(ctx.GetPlatformID())
@@ -94,10 +104,12 @@ func (c *Client) ResetClient(ctx *UserConnContext, conn LongConn, isBackground,
c.closedErr = nil c.closedErr = nil
c.token = token c.token = token
} }
func (c *Client) pongHandler(_ string) error { func (c *Client) pongHandler(_ string) error {
c.conn.SetReadDeadline(pongWait) c.conn.SetReadDeadline(pongWait)
return nil return nil
} }
func (c *Client) readMessage() { func (c *Client) readMessage() {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@@ -116,7 +128,7 @@ func (c *Client) readMessage() {
return return
} }
log.ZDebug(c.ctx, "readMessage", "messageType", messageType) log.ZDebug(c.ctx, "readMessage", "messageType", messageType)
if c.closed == true { //连接刚置位已经关闭,但是协程还没退出的场景 if c.closed == true { // 连接刚置位已经关闭,但是协程还没退出的场景
c.closedErr = ErrConnClosed c.closedErr = ErrConnClosed
return return
} }
@@ -140,8 +152,8 @@ func (c *Client) readMessage() {
default: default:
} }
} }
} }
func (c *Client) handleMessage(message []byte) error { func (c *Client) handleMessage(message []byte) error {
if c.IsCompress { if c.IsCompress {
var decompressErr error var decompressErr error
@@ -161,7 +173,9 @@ func (c *Client) handleMessage(message []byte) error {
if binaryReq.SendID != c.UserID { if binaryReq.SendID != c.UserID {
return utils.Wrap(errors.New("exception conn userID not same to req userID"), binaryReq.String()) return utils.Wrap(errors.New("exception conn userID not same to req userID"), binaryReq.String())
} }
ctx := mcontext.WithMustInfoCtx([]string{binaryReq.OperationID, binaryReq.SendID, constant.PlatformIDToName(c.PlatformID), c.ctx.GetConnID()}) ctx := mcontext.WithMustInfoCtx(
[]string{binaryReq.OperationID, binaryReq.SendID, constant.PlatformIDToName(c.PlatformID), c.ctx.GetConnID()},
)
log.ZDebug(ctx, "gateway req message", "req", binaryReq.String()) log.ZDebug(ctx, "gateway req message", "req", binaryReq.String())
var messageErr error var messageErr error
var resp []byte var resp []byte
@@ -179,30 +193,35 @@ func (c *Client) handleMessage(message []byte) error {
case WsSetBackgroundStatus: case WsSetBackgroundStatus:
resp, messageErr = c.setAppBackgroundStatus(ctx, binaryReq) resp, messageErr = c.setAppBackgroundStatus(ctx, binaryReq)
default: default:
return fmt.Errorf("ReqIdentifier failed,sendID:%s,msgIncr:%s,reqIdentifier:%d", binaryReq.SendID, binaryReq.MsgIncr, binaryReq.ReqIdentifier) return fmt.Errorf(
"ReqIdentifier failed,sendID:%s,msgIncr:%s,reqIdentifier:%d",
binaryReq.SendID,
binaryReq.MsgIncr,
binaryReq.ReqIdentifier,
)
} }
c.replyMessage(ctx, &binaryReq, messageErr, resp) c.replyMessage(ctx, &binaryReq, messageErr, resp)
return nil return nil
} }
func (c *Client) setAppBackgroundStatus(ctx context.Context, req Req) ([]byte, error) { func (c *Client) setAppBackgroundStatus(ctx context.Context, req Req) ([]byte, error) {
resp, isBackground, messageErr := c.longConnServer.SetUserDeviceBackground(ctx, req) resp, isBackground, messageErr := c.longConnServer.SetUserDeviceBackground(ctx, req)
if messageErr != nil { if messageErr != nil {
return nil, messageErr return nil, messageErr
} }
c.IsBackground = isBackground c.IsBackground = isBackground
//todo callback // todo callback
return resp, nil return resp, nil
} }
func (c *Client) close() { func (c *Client) close() {
c.w.Lock() c.w.Lock()
defer c.w.Unlock() defer c.w.Unlock()
c.closed = true c.closed = true
c.conn.Close() c.conn.Close()
c.longConnServer.UnRegister(c) c.longConnServer.UnRegister(c)
} }
func (c *Client) replyMessage(ctx context.Context, binaryReq *Req, err error, resp []byte) { func (c *Client) replyMessage(ctx context.Context, binaryReq *Req, err error, resp []byte) {
errResp := apiresp.ParseError(err) errResp := apiresp.ParseError(err)
mReply := Resp{ mReply := Resp{
@@ -219,6 +238,7 @@ func (c *Client) replyMessage(ctx context.Context, binaryReq *Req, err error, re
log.ZWarn(ctx, "wireBinaryMsg replyMessage", err, "resp", mReply.String()) log.ZWarn(ctx, "wireBinaryMsg replyMessage", err, "resp", mReply.String())
} }
} }
func (c *Client) PushMessage(ctx context.Context, msgData *sdkws.MsgData) error { func (c *Client) PushMessage(ctx context.Context, msgData *sdkws.MsgData) error {
var msg sdkws.PushMessages var msg sdkws.PushMessages
conversationID := utils.GetConversationIDByMsg(msgData) conversationID := utils.GetConversationIDByMsg(msgData)
@@ -281,5 +301,4 @@ func (c *Client) writePongMsg() error {
} }
_ = c.conn.SetWriteDeadline(writeWait) _ = c.conn.SetWriteDeadline(writeWait)
return c.conn.WriteMessage(PongMessage, nil) return c.conn.WriteMessage(PongMessage, nil)
} }
+1
View File
@@ -33,6 +33,7 @@ type GzipCompressor struct {
func NewGzipCompressor() *GzipCompressor { func NewGzipCompressor() *GzipCompressor {
return &GzipCompressor{compressProtocol: "gzip"} return &GzipCompressor{compressProtocol: "gzip"}
} }
func (g *GzipCompressor) Compress(rawData []byte) ([]byte, error) { func (g *GzipCompressor) Compress(rawData []byte) ([]byte, error) {
gzipBuffer := bytes.Buffer{} gzipBuffer := bytes.Buffer{}
gz := gzip.NewWriter(&gzipBuffer) gz := gzip.NewWriter(&gzipBuffer)
+3 -1
View File
@@ -27,11 +27,13 @@ const (
GzipCompressionProtocol = "gzip" GzipCompressionProtocol = "gzip"
BackgroundStatus = "isBackground" BackgroundStatus = "isBackground"
) )
const ( const (
WebSocket = iota + 1 WebSocket = iota + 1
) )
const ( const (
//Websocket Protocol // Websocket Protocol.
WSGetNewestSeq = 1001 WSGetNewestSeq = 1001
WSPullMsgBySeqList = 1002 WSPullMsgBySeqList = 1002
WSSendMsg = 1003 WSSendMsg = 1003
+11
View File
@@ -71,9 +71,11 @@ func newContext(respWriter http.ResponseWriter, req *http.Request) *UserConnCont
ConnID: utils.Md5(req.RemoteAddr + "_" + strconv.Itoa(int(utils.GetCurrentTimestampByMill()))), ConnID: utils.Md5(req.RemoteAddr + "_" + strconv.Itoa(int(utils.GetCurrentTimestampByMill()))),
} }
} }
func (c *UserConnContext) GetRemoteAddr() string { func (c *UserConnContext) GetRemoteAddr() string {
return c.RemoteAddr return c.RemoteAddr
} }
func (c *UserConnContext) Query(key string) (string, bool) { func (c *UserConnContext) Query(key string) (string, bool) {
var value string var value string
if value = c.Req.URL.Query().Get(key); value == "" { if value = c.Req.URL.Query().Get(key); value == "" {
@@ -81,6 +83,7 @@ func (c *UserConnContext) Query(key string) (string, bool) {
} }
return value, true return value, true
} }
func (c *UserConnContext) GetHeader(key string) (string, bool) { func (c *UserConnContext) GetHeader(key string) (string, bool) {
var value string var value string
if value = c.Req.Header.Get(key); value == "" { if value = c.Req.Header.Get(key); value == "" {
@@ -88,27 +91,35 @@ func (c *UserConnContext) GetHeader(key string) (string, bool) {
} }
return value, true return value, true
} }
func (c *UserConnContext) SetHeader(key, value string) { func (c *UserConnContext) SetHeader(key, value string) {
c.RespWriter.Header().Set(key, value) c.RespWriter.Header().Set(key, value)
} }
func (c *UserConnContext) ErrReturn(error string, code int) { func (c *UserConnContext) ErrReturn(error string, code int) {
http.Error(c.RespWriter, error, code) http.Error(c.RespWriter, error, code)
} }
func (c *UserConnContext) GetConnID() string { func (c *UserConnContext) GetConnID() string {
return c.ConnID return c.ConnID
} }
func (c *UserConnContext) GetUserID() string { func (c *UserConnContext) GetUserID() string {
return c.Req.URL.Query().Get(WsUserID) return c.Req.URL.Query().Get(WsUserID)
} }
func (c *UserConnContext) GetPlatformID() string { func (c *UserConnContext) GetPlatformID() string {
return c.Req.URL.Query().Get(PlatformID) return c.Req.URL.Query().Get(PlatformID)
} }
func (c *UserConnContext) GetOperationID() string { func (c *UserConnContext) GetOperationID() string {
return c.Req.URL.Query().Get(OperationID) return c.Req.URL.Query().Get(OperationID)
} }
func (c *UserConnContext) GetToken() string { func (c *UserConnContext) GetToken() string {
return c.Req.URL.Query().Get(Token) return c.Req.URL.Query().Get(Token)
} }
func (c *UserConnContext) GetBackground() bool { func (c *UserConnContext) GetBackground() bool {
b, err := strconv.ParseBool(c.Req.URL.Query().Get(BackgroundStatus)) b, err := strconv.ParseBool(c.Req.URL.Query().Get(BackgroundStatus))
if err != nil { if err != nil {
+3 -2
View File
@@ -26,12 +26,12 @@ type Encoder interface {
Decode(encodeData []byte, decodeData interface{}) error Decode(encodeData []byte, decodeData interface{}) error
} }
type GobEncoder struct { type GobEncoder struct{}
}
func NewGobEncoder() *GobEncoder { func NewGobEncoder() *GobEncoder {
return &GobEncoder{} return &GobEncoder{}
} }
func (g *GobEncoder) Encode(data interface{}) ([]byte, error) { func (g *GobEncoder) Encode(data interface{}) ([]byte, error) {
buff := bytes.Buffer{} buff := bytes.Buffer{}
enc := gob.NewEncoder(&buff) enc := gob.NewEncoder(&buff)
@@ -41,6 +41,7 @@ func (g *GobEncoder) Encode(data interface{}) ([]byte, error) {
} }
return buff.Bytes(), nil return buff.Bytes(), nil
} }
func (g *GobEncoder) Decode(encodeData []byte, decodeData interface{}) error { func (g *GobEncoder) Decode(encodeData []byte, decodeData interface{}) error {
buff := bytes.NewBuffer(encodeData) buff := bytes.NewBuffer(encodeData)
dec := gob.NewDecoder(buff) dec := gob.NewDecoder(buff)
+4 -10
View File
@@ -25,9 +25,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msggateway" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msggateway"
"github.com/OpenIMSDK/Open-IM-Server/pkg/startrpc" "github.com/OpenIMSDK/Open-IM-Server/pkg/startrpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
@@ -84,9 +82,6 @@ func (s *Server) GetUsersOnlineStatus(
ctx context.Context, ctx context.Context,
req *msggateway.GetUsersOnlineStatusReq, req *msggateway.GetUsersOnlineStatusReq,
) (*msggateway.GetUsersOnlineStatusResp, error) { ) (*msggateway.GetUsersOnlineStatusResp, error) {
if !tokenverify.IsAppManagerUid(ctx) {
return nil, errs.ErrNoPermission.Wrap("only app manager")
}
var resp msggateway.GetUsersOnlineStatusResp var resp msggateway.GetUsersOnlineStatusResp
for _, userID := range req.UserIDs { for _, userID := range req.UserIDs {
clients, ok := s.LongConnServer.GetUserAllCons(userID) clients, ok := s.LongConnServer.GetUserAllCons(userID)
@@ -181,13 +176,12 @@ func (s *Server) KickUserOffline(
if clients, _, ok := s.LongConnServer.GetUserPlatformCons(v, int(req.PlatformID)); ok { if clients, _, ok := s.LongConnServer.GetUserPlatformCons(v, int(req.PlatformID)); ok {
for _, client := range clients { for _, client := range clients {
log.ZDebug(ctx, "kick user offline", "userID", v, "platformID", req.PlatformID, "client", client) log.ZDebug(ctx, "kick user offline", "userID", v, "platformID", req.PlatformID, "client", client)
err := client.KickOnlineMessage() if err := client.longConnServer.KickUserConn(client); err != nil {
if err != nil { log.ZWarn(ctx, "kick user offline failed", err, "userID", v, "platformID", req.PlatformID)
return nil, err
} }
} }
} else { } else {
log.ZWarn(ctx, "conn not exist", nil, "userID", v, "platformID", req.PlatformID) log.ZInfo(ctx, "conn not exist", "userID", v, "platformID", req.PlatformID)
} }
} }
return &msggateway.KickUserOfflineResp{}, nil return &msggateway.KickUserOfflineResp{}, nil
@@ -197,6 +191,6 @@ func (s *Server) MultiTerminalLoginCheck(
ctx context.Context, ctx context.Context,
req *msggateway.MultiTerminalLoginCheckReq, req *msggateway.MultiTerminalLoginCheckReq,
) (*msggateway.MultiTerminalLoginCheckResp, error) { ) (*msggateway.MultiTerminalLoginCheckResp, error) {
//TODO implement me // TODO implement me
panic("implement me") panic("implement me")
} }
+8 -5
View File
@@ -22,14 +22,14 @@ import (
) )
type LongConn interface { type LongConn interface {
//Close this connection // Close this connection
Close() error Close() error
// WriteMessage Write message to connection,messageType means data type,can be set binary(2) and text(1). // WriteMessage Write message to connection,messageType means data type,can be set binary(2) and text(1).
WriteMessage(messageType int, message []byte) error WriteMessage(messageType int, message []byte) error
// ReadMessage Read message from connection. // ReadMessage Read message from connection.
ReadMessage() (int, []byte, error) ReadMessage() (int, []byte, error)
// SetReadDeadline sets the read deadline on the underlying network connection, // SetReadDeadline sets the read deadline on the underlying network connection,
//after a read has timed out, will return an error. // after a read has timed out, will return an error.
SetReadDeadline(timeout time.Duration) error SetReadDeadline(timeout time.Duration) error
// SetWriteDeadline sets to write deadline when send message,when read has timed out,will return error. // SetWriteDeadline sets to write deadline when send message,when read has timed out,will return error.
SetWriteDeadline(timeout time.Duration) error SetWriteDeadline(timeout time.Duration) error
@@ -58,6 +58,7 @@ func newGWebSocket(protocolType int, handshakeTimeout time.Duration) *GWebSocket
func (d *GWebSocket) Close() error { func (d *GWebSocket) Close() error {
return d.conn.Close() return d.conn.Close()
} }
func (d *GWebSocket) GenerateLongConn(w http.ResponseWriter, r *http.Request) error { func (d *GWebSocket) GenerateLongConn(w http.ResponseWriter, r *http.Request) error {
upgrader := &websocket.Upgrader{ upgrader := &websocket.Upgrader{
HandshakeTimeout: d.handshakeTimeout, HandshakeTimeout: d.handshakeTimeout,
@@ -69,10 +70,10 @@ func (d *GWebSocket) GenerateLongConn(w http.ResponseWriter, r *http.Request) er
} }
d.conn = conn d.conn = conn
return nil return nil
} }
func (d *GWebSocket) WriteMessage(messageType int, message []byte) error { func (d *GWebSocket) WriteMessage(messageType int, message []byte) error {
//d.setSendConn(d.conn) // d.setSendConn(d.conn)
return d.conn.WriteMessage(messageType, message) return d.conn.WriteMessage(messageType, message)
} }
@@ -83,6 +84,7 @@ func (d *GWebSocket) WriteMessage(messageType int, message []byte) error {
func (d *GWebSocket) ReadMessage() (int, []byte, error) { func (d *GWebSocket) ReadMessage() (int, []byte, error) {
return d.conn.ReadMessage() return d.conn.ReadMessage()
} }
func (d *GWebSocket) SetReadDeadline(timeout time.Duration) error { func (d *GWebSocket) SetReadDeadline(timeout time.Duration) error {
return d.conn.SetReadDeadline(time.Now().Add(timeout)) return d.conn.SetReadDeadline(time.Now().Add(timeout))
} }
@@ -97,7 +99,6 @@ func (d *GWebSocket) Dial(urlStr string, requestHeader http.Header) (*http.Respo
d.conn = conn d.conn = conn
} }
return httpResp, err return httpResp, err
} }
func (d *GWebSocket) IsNil() bool { func (d *GWebSocket) IsNil() bool {
@@ -110,9 +111,11 @@ func (d *GWebSocket) IsNil() bool {
func (d *GWebSocket) SetConnNil() { func (d *GWebSocket) SetConnNil() {
d.conn = nil d.conn = nil
} }
func (d *GWebSocket) SetReadLimit(limit int64) { func (d *GWebSocket) SetReadLimit(limit int64) {
d.conn.SetReadLimit(limit) d.conn.SetReadLimit(limit)
} }
func (d *GWebSocket) SetPongHandler(handler PongHandler) { func (d *GWebSocket) SetPongHandler(handler PongHandler) {
d.conn.SetPongHandler(handler) d.conn.SetPongHandler(handler)
} }
+5 -2
View File
@@ -75,8 +75,10 @@ type GrpcHandler struct {
func NewGrpcHandler(validate *validator.Validate, client discoveryregistry.SvcDiscoveryRegistry) *GrpcHandler { func NewGrpcHandler(validate *validator.Validate, client discoveryregistry.SvcDiscoveryRegistry) *GrpcHandler {
msgRpcClient := rpcclient.NewMessageRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client)
pushRpcClient := rpcclient.NewPushRpcClient(client) pushRpcClient := rpcclient.NewPushRpcClient(client)
return &GrpcHandler{msgRpcClient: &msgRpcClient, return &GrpcHandler{
pushClient: &pushRpcClient, validate: validate} msgRpcClient: &msgRpcClient,
pushClient: &pushRpcClient, validate: validate,
}
} }
func (g GrpcHandler) GetSeq(context context.Context, data Req) ([]byte, error) { func (g GrpcHandler) GetSeq(context context.Context, data Req) ([]byte, error) {
@@ -164,6 +166,7 @@ func (g GrpcHandler) UserLogout(context context.Context, data Req) ([]byte, erro
} }
return c, nil return c, nil
} }
func (g GrpcHandler) SetUserDeviceBackground(_ context.Context, data Req) ([]byte, bool, error) { func (g GrpcHandler) SetUserDeviceBackground(_ context.Context, data Req) ([]byte, bool, error) {
req := sdkws.SetAppBackgroundStatusReq{} req := sdkws.SetAppBackgroundStatusReq{}
if err := proto.Unmarshal(data.Data, &req); err != nil { if err := proto.Unmarshal(data.Data, &req); err != nil {
+34 -35
View File
@@ -47,6 +47,7 @@ type LongConnServer interface {
Validate(s interface{}) error Validate(s interface{}) error
SetCacheHandler(cache cache.MsgModel) SetCacheHandler(cache cache.MsgModel)
SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry) SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry)
KickUserConn(client *Client) error
UnRegister(c *Client) UnRegister(c *Client)
Compressor Compressor
Encoder Encoder
@@ -86,6 +87,7 @@ type kickHandler struct {
func (ws *WsServer) SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry) { func (ws *WsServer) SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry) {
ws.MessageHandler = NewGrpcHandler(ws.validate, client) ws.MessageHandler = NewGrpcHandler(ws.validate, client)
} }
func (ws *WsServer) SetCacheHandler(cache cache.MsgModel) { func (ws *WsServer) SetCacheHandler(cache cache.MsgModel) {
ws.cache = cache ws.cache = cache
} }
@@ -113,7 +115,6 @@ func NewWsServer(opts ...Option) (*WsServer, error) {
} }
if config.port < 1024 { if config.port < 1024 {
return nil, errors.New("port not allow to listen") return nil, errors.New("port not allow to listen")
} }
v := validator.New() v := validator.New()
return &WsServer{ return &WsServer{
@@ -134,6 +135,7 @@ func NewWsServer(opts ...Option) (*WsServer, error) {
Encoder: NewGobEncoder(), Encoder: NewGobEncoder(),
}, nil }, nil
} }
func (ws *WsServer) Run() error { func (ws *WsServer) Run() error {
var client *Client var client *Client
go func() { go func() {
@@ -144,13 +146,13 @@ func (ws *WsServer) Run() error {
case client = <-ws.unregisterChan: case client = <-ws.unregisterChan:
ws.unregisterClient(client) ws.unregisterClient(client)
case onlineInfo := <-ws.kickHandlerChan: case onlineInfo := <-ws.kickHandlerChan:
ws.multiTerminalLoginChecker(onlineInfo) ws.multiTerminalLoginChecker(onlineInfo.clientOK, onlineInfo.oldClients, onlineInfo.newClient)
} }
} }
}() }()
http.HandleFunc("/", ws.wsHandler) http.HandleFunc("/", ws.wsHandler)
// http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) {}) // http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) {})
return http.ListenAndServe(":"+utils.IntToString(ws.port), nil) //Start listening return http.ListenAndServe(":"+utils.IntToString(ws.port), nil) // Start listening
} }
func (ws *WsServer) registerClient(client *Client) { func (ws *WsServer) registerClient(client *Client) {
@@ -165,7 +167,6 @@ func (ws *WsServer) registerClient(client *Client) {
log.ZDebug(client.ctx, "user not exist", "userID", client.UserID, "platformID", client.PlatformID) log.ZDebug(client.ctx, "user not exist", "userID", client.UserID, "platformID", client.PlatformID)
atomic.AddInt64(&ws.onlineUserNum, 1) atomic.AddInt64(&ws.onlineUserNum, 1)
atomic.AddInt64(&ws.onlineUserConnNum, 1) atomic.AddInt64(&ws.onlineUserConnNum, 1)
} else { } else {
i := &kickHandler{ i := &kickHandler{
clientOK: clientOK, clientOK: clientOK,
@@ -176,7 +177,7 @@ func (ws *WsServer) registerClient(client *Client) {
log.ZDebug(client.ctx, "user exist", "userID", client.UserID, "platformID", client.PlatformID) log.ZDebug(client.ctx, "user exist", "userID", client.UserID, "platformID", client.PlatformID)
if clientOK { if clientOK {
ws.clients.Set(client.UserID, client) ws.clients.Set(client.UserID, client)
//已经有同平台的连接存在 // 已经有同平台的连接存在
log.ZInfo(client.ctx, "repeat login", "userID", client.UserID, "platformID", client.PlatformID, "old remote addr", getRemoteAdders(oldClients)) log.ZInfo(client.ctx, "repeat login", "userID", client.UserID, "platformID", client.PlatformID, "old remote addr", getRemoteAdders(oldClients))
atomic.AddInt64(&ws.onlineUserConnNum, 1) atomic.AddInt64(&ws.onlineUserConnNum, 1)
} else { } else {
@@ -194,6 +195,7 @@ func (ws *WsServer) registerClient(client *Client) {
ws.onlineUserConnNum, ws.onlineUserConnNum,
) )
} }
func getRemoteAdders(client []*Client) string { func getRemoteAdders(client []*Client) string {
var ret string var ret string
for i, c := range client { for i, c := range client {
@@ -206,86 +208,83 @@ func getRemoteAdders(client []*Client) string {
return ret return ret
} }
func (ws *WsServer) multiTerminalLoginChecker(info *kickHandler) { func (ws *WsServer) KickUserConn(client *Client) error {
ws.clients.deleteClients(client.UserID, []*Client{client})
return client.KickOnlineMessage()
}
func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) {
switch config.Config.MultiLoginPolicy { switch config.Config.MultiLoginPolicy {
case constant.DefalutNotKick: case constant.DefalutNotKick:
case constant.PCAndOther: case constant.PCAndOther:
if constant.PlatformIDToClass(info.newClient.PlatformID) == constant.TerminalPC { if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC {
return return
} }
fallthrough fallthrough
case constant.AllLoginButSameTermKick: case constant.AllLoginButSameTermKick:
if info.clientOK { if clientOK {
ws.clients.deleteClients(info.newClient.UserID, info.oldClients) ws.clients.deleteClients(newClient.UserID, oldClients)
for _, c := range info.oldClients { for _, c := range oldClients {
err := c.KickOnlineMessage() err := c.KickOnlineMessage()
if err != nil { if err != nil {
log.ZWarn(c.ctx, "KickOnlineMessage", err) log.ZWarn(c.ctx, "KickOnlineMessage", err)
} }
} }
m, err := ws.cache.GetTokensWithoutError( m, err := ws.cache.GetTokensWithoutError(
info.newClient.ctx, newClient.ctx,
info.newClient.UserID, newClient.UserID,
info.newClient.PlatformID, newClient.PlatformID,
) )
if err != nil && err != redis.Nil { if err != nil && err != redis.Nil {
log.ZWarn( log.ZWarn(
info.newClient.ctx, newClient.ctx,
"get token from redis err", "get token from redis err",
err, err,
"userID", "userID",
info.newClient.UserID, newClient.UserID,
"platformID", "platformID",
info.newClient.PlatformID, newClient.PlatformID,
) )
return return
} }
if m == nil { if m == nil {
log.ZWarn( log.ZWarn(
info.newClient.ctx, newClient.ctx,
"m is nil", "m is nil",
errors.New("m is nil"), errors.New("m is nil"),
"userID", "userID",
info.newClient.UserID, newClient.UserID,
"platformID", "platformID",
info.newClient.PlatformID, newClient.PlatformID,
) )
return return
} }
log.ZDebug( log.ZDebug(
info.newClient.ctx, newClient.ctx,
"get token from redis", "get token from redis",
"userID", "userID",
info.newClient.UserID, newClient.UserID,
"platformID", "platformID",
info.newClient.PlatformID, newClient.PlatformID,
"tokenMap", "tokenMap",
m, m,
) )
for k := range m { for k := range m {
if k != info.newClient.ctx.GetToken() { if k != newClient.ctx.GetToken() {
m[k] = constant.KickedToken m[k] = constant.KickedToken
} }
} }
log.ZDebug(info.newClient.ctx, "set token map is ", "token map", m, "userID", info.newClient.UserID) log.ZDebug(newClient.ctx, "set token map is ", "token map", m, "userID", newClient.UserID)
err = ws.cache.SetTokenMapByUidPid(info.newClient.ctx, info.newClient.UserID, info.newClient.PlatformID, m) err = ws.cache.SetTokenMapByUidPid(newClient.ctx, newClient.UserID, newClient.PlatformID, m)
if err != nil { if err != nil {
log.ZWarn( log.ZWarn(newClient.ctx, "SetTokenMapByUidPid err", err, "userID", newClient.UserID, "platformID", newClient.PlatformID)
info.newClient.ctx,
"SetTokenMapByUidPid err",
err,
"userID",
info.newClient.UserID,
"platformID",
info.newClient.PlatformID,
)
return return
} }
} }
} }
} }
func (ws *WsServer) unregisterClient(client *Client) { func (ws *WsServer) unregisterClient(client *Client) {
defer ws.clientPool.Put(client) defer ws.clientPool.Put(client)
isDeleteUser := ws.clients.delete(client.UserID, client.ctx.GetRemoteAddr()) isDeleteUser := ws.clients.delete(client.UserID, client.ctx.GetRemoteAddr())
+16 -11
View File
@@ -16,33 +16,38 @@ package msggateway
import "time" import "time"
type Option func(opt *configs) type (
type configs struct { Option func(opt *configs)
//长连接监听端口 configs struct {
port int // 长连接监听端口
//长连接允许最大链接数 port int
maxConnNum int64 // 长连接允许最大链接数
//连接握手超时时间 maxConnNum int64
handshakeTimeout time.Duration // 连接握手超时时间
//允许消息最大长度 handshakeTimeout time.Duration
messageMaxMsgLength int // 允许消息最大长度
} messageMaxMsgLength int
}
)
func WithPort(port int) Option { func WithPort(port int) Option {
return func(opt *configs) { return func(opt *configs) {
opt.port = port opt.port = port
} }
} }
func WithMaxConnNum(num int64) Option { func WithMaxConnNum(num int64) Option {
return func(opt *configs) { return func(opt *configs) {
opt.maxConnNum = num opt.maxConnNum = num
} }
} }
func WithHandshakeTimeout(t time.Duration) Option { func WithHandshakeTimeout(t time.Duration) Option {
return func(opt *configs) { return func(opt *configs) {
opt.handshakeTimeout = t opt.handshakeTimeout = t
} }
} }
func WithMessageMaxMsgLength(length int) Option { func WithMessageMaxMsgLength(length int) Option {
return func(opt *configs) { return func(opt *configs) {
opt.messageMaxMsgLength = length opt.messageMaxMsgLength = length
+6 -1
View File
@@ -29,6 +29,7 @@ type UserMap struct {
func newUserMap() *UserMap { func newUserMap() *UserMap {
return &UserMap{} return &UserMap{}
} }
func (u *UserMap) GetAll(key string) ([]*Client, bool) { func (u *UserMap) GetAll(key string) ([]*Client, bool) {
allClients, ok := u.m.Load(key) allClients, ok := u.m.Load(key)
if ok { if ok {
@@ -36,6 +37,7 @@ func (u *UserMap) GetAll(key string) ([]*Client, bool) {
} }
return nil, ok return nil, ok
} }
func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) { func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
allClients, userExisted := u.m.Load(key) allClients, userExisted := u.m.Load(key)
if userExisted { if userExisted {
@@ -47,12 +49,12 @@ func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
} }
if len(clients) > 0 { if len(clients) > 0 {
return clients, userExisted, true return clients, userExisted, true
} }
return clients, userExisted, false return clients, userExisted, false
} }
return nil, userExisted, false return nil, userExisted, false
} }
func (u *UserMap) Set(key string, v *Client) { func (u *UserMap) Set(key string, v *Client) {
allClients, existed := u.m.Load(key) allClients, existed := u.m.Load(key)
if existed { if existed {
@@ -67,6 +69,7 @@ func (u *UserMap) Set(key string, v *Client) {
u.m.Store(key, clients) u.m.Store(key, clients)
} }
} }
func (u *UserMap) delete(key string, connRemoteAddr string) (isDeleteUser bool) { func (u *UserMap) delete(key string, connRemoteAddr string) (isDeleteUser bool) {
allClients, existed := u.m.Load(key) allClients, existed := u.m.Load(key)
if existed { if existed {
@@ -87,6 +90,7 @@ func (u *UserMap) delete(key string, connRemoteAddr string) (isDeleteUser bool)
} }
return existed return existed
} }
func (u *UserMap) deleteClients(key string, clients []*Client) (isDeleteUser bool) { func (u *UserMap) deleteClients(key string, clients []*Client) (isDeleteUser bool) {
m := utils.SliceToMapAny(clients, func(c *Client) (string, struct{}) { m := utils.SliceToMapAny(clients, func(c *Client) (string, struct{}) {
return c.ctx.GetRemoteAddr(), struct{}{} return c.ctx.GetRemoteAddr(), struct{}{}
@@ -110,6 +114,7 @@ func (u *UserMap) deleteClients(key string, clients []*Client) (isDeleteUser boo
} }
return existed return existed
} }
func (u *UserMap) DeleteAll(key string) { func (u *UserMap) DeleteAll(key string) {
u.m.Delete(key) u.m.Delete(key)
} }
+25 -6
View File
@@ -1,3 +1,17 @@
// 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 msgtransfer package msgtransfer
import ( import (
@@ -5,6 +19,9 @@ import (
"sync" "sync"
"time" "time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
@@ -16,8 +33,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
openKeeper "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry/zookeeper" openKeeper "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry/zookeeper"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
) )
type MsgTransfer struct { type MsgTransfer struct {
@@ -58,7 +73,8 @@ func StartTransfer(prometheusPort int) error {
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials())) client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
msgModel := cache.NewMsgCacheModel(rdb) msgModel := cache.NewMsgCacheModel(rdb)
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase()) msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
chatLogDatabase := controller.NewChatLogDatabase(relation.NewChatLogGorm(db)) msgMysModel := relation.NewChatLogGorm(db)
chatLogDatabase := controller.NewChatLogDatabase(msgMysModel)
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, msgModel) msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, msgModel)
conversationRpcClient := rpcclient.NewConversationRpcClient(client) conversationRpcClient := rpcclient.NewConversationRpcClient(client)
groupRpcClient := rpcclient.NewGroupRpcClient(client) groupRpcClient := rpcclient.NewGroupRpcClient(client)
@@ -69,9 +85,12 @@ func StartTransfer(prometheusPort int) error {
func NewMsgTransfer(chatLogDatabase controller.ChatLogDatabase, func NewMsgTransfer(chatLogDatabase controller.ChatLogDatabase,
msgDatabase controller.CommonMsgDatabase, msgDatabase controller.CommonMsgDatabase,
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) *MsgTransfer { conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient,
return &MsgTransfer{persistentCH: NewPersistentConsumerHandler(chatLogDatabase), historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient), ) *MsgTransfer {
historyMongoCH: NewOnlineHistoryMongoConsumerHandler(msgDatabase)} return &MsgTransfer{
persistentCH: NewPersistentConsumerHandler(chatLogDatabase), historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient),
historyMongoCH: NewOnlineHistoryMongoConsumerHandler(msgDatabase),
}
} }
func (m *MsgTransfer) initPrometheus() { func (m *MsgTransfer) initPrometheus() {
@@ -38,10 +38,12 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
) )
const ConsumerMsgs = 3 const (
const SourceMessages = 4 ConsumerMsgs = 3
const MongoMessages = 5 SourceMessages = 4
const ChannelNum = 100 MongoMessages = 5
ChannelNum = 100
)
type MsgChannelValue struct { type MsgChannelValue struct {
uniqueKey string uniqueKey string
@@ -85,7 +87,7 @@ func NewOnlineHistoryRedisConsumerHandler(
) *OnlineHistoryRedisConsumerHandler { ) *OnlineHistoryRedisConsumerHandler {
var och OnlineHistoryRedisConsumerHandler var och OnlineHistoryRedisConsumerHandler
och.msgDatabase = database och.msgDatabase = database
och.msgDistributionCh = make(chan Cmd2Value) //no buffer channel och.msgDistributionCh = make(chan Cmd2Value) // no buffer channel
go och.MessagesDistributionHandle() go och.MessagesDistributionHandle()
for i := 0; i < ChannelNum; i++ { for i := 0; i < ChannelNum; i++ {
och.chArrays[i] = make(chan Cmd2Value, 50) och.chArrays[i] = make(chan Cmd2Value, 50)
@@ -93,8 +95,10 @@ func NewOnlineHistoryRedisConsumerHandler(
} }
och.conversationRpcClient = conversationRpcClient och.conversationRpcClient = conversationRpcClient
och.groupRpcClient = groupRpcClient och.groupRpcClient = groupRpcClient
och.historyConsumerGroup = kafka.NewMConsumerGroup(&kafka.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0, och.historyConsumerGroup = kafka.NewMConsumerGroup(&kafka.MConsumerGroupConfig{
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.LatestMsgToRedis.Topic}, KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToRedis) config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToRedis)
// statistics.NewStatistics(&och.singleMsgSuccessCount, config.Config.ModuleName.MsgTransferName, fmt.Sprintf("%d // statistics.NewStatistics(&och.singleMsgSuccessCount, config.Config.ModuleName.MsgTransferName, fmt.Sprintf("%d
// second singleMsgCount insert to mongo", constant.StatisticsTimeInterval), constant.StatisticsTimeInterval) // second singleMsgCount insert to mongo", constant.StatisticsTimeInterval), constant.StatisticsTimeInterval)
@@ -163,7 +167,7 @@ func (och *OnlineHistoryRedisConsumerHandler) Run(channelID int) {
} }
} }
// 获取消息/通知 存储的消息列表, 不存储并且推送的消息列表, // 获取消息/通知 存储的消息列表, 不存储并且推送的消息列表,.
func (och *OnlineHistoryRedisConsumerHandler) getPushStorageMsgList( func (och *OnlineHistoryRedisConsumerHandler) getPushStorageMsgList(
totalMsgs []*ContextMsg, totalMsgs []*ContextMsg,
) (storageMsgList, notStorageMsgList, storageNotificatoinList, notStorageNotificationList, modifyMsgList []*sdkws.MsgData) { ) (storageMsgList, notStorageMsgList, storageNotificatoinList, notStorageNotificationList, modifyMsgList []*sdkws.MsgData) {
@@ -312,7 +316,7 @@ func (och *OnlineHistoryRedisConsumerHandler) MessagesDistributionHandle() {
triggerChannelValue := cmd.Value.(TriggerChannelValue) triggerChannelValue := cmd.Value.(TriggerChannelValue)
ctx := triggerChannelValue.ctx ctx := triggerChannelValue.ctx
consumerMessages := triggerChannelValue.cMsgList consumerMessages := triggerChannelValue.cMsgList
//Aggregation map[userid]message list // Aggregation map[userid]message list
log.ZDebug(ctx, "batch messages come to distribution center", "length", len(consumerMessages)) log.ZDebug(ctx, "batch messages come to distribution center", "length", len(consumerMessages))
for i := 0; i < len(consumerMessages); i++ { for i := 0; i < len(consumerMessages); i++ {
ctxMsg := &ContextMsg{} ctxMsg := &ContextMsg{}
@@ -378,13 +382,13 @@ func (och *OnlineHistoryRedisConsumerHandler) MessagesDistributionHandle() {
} }
} }
} }
func withAggregationCtx(ctx context.Context, values []*ContextMsg) context.Context { func withAggregationCtx(ctx context.Context, values []*ContextMsg) context.Context {
var allMessageOperationID string var allMessageOperationID string
for i, v := range values { for i, v := range values {
if opid := mcontext.GetOperationID(v.ctx); opid != "" { if opid := mcontext.GetOperationID(v.ctx); opid != "" {
if i == 0 { if i == 0 {
allMessageOperationID += opid allMessageOperationID += opid
} else { } else {
allMessageOperationID += "$" + opid allMessageOperationID += "$" + opid
} }
@@ -431,13 +435,15 @@ func (och *OnlineHistoryRedisConsumerHandler) ConsumeClaim(
ctx := mcontext.WithTriggerIDContext(context.Background(), utils.OperationIDGenerator()) ctx := mcontext.WithTriggerIDContext(context.Background(), utils.OperationIDGenerator())
log.ZDebug(ctx, "timer trigger msg consumer start", "length", len(ccMsg)) log.ZDebug(ctx, "timer trigger msg consumer start", "length", len(ccMsg))
for i := 0; i < len(ccMsg)/split; i++ { for i := 0; i < len(ccMsg)/split; i++ {
//log.Debug() // log.Debug()
och.msgDistributionCh <- Cmd2Value{Cmd: ConsumerMsgs, Value: TriggerChannelValue{ och.msgDistributionCh <- Cmd2Value{Cmd: ConsumerMsgs, Value: TriggerChannelValue{
ctx: ctx, cMsgList: ccMsg[i*split : (i+1)*split]}} ctx: ctx, cMsgList: ccMsg[i*split : (i+1)*split],
}}
} }
if (len(ccMsg) % split) > 0 { if (len(ccMsg) % split) > 0 {
och.msgDistributionCh <- Cmd2Value{Cmd: ConsumerMsgs, Value: TriggerChannelValue{ och.msgDistributionCh <- Cmd2Value{Cmd: ConsumerMsgs, Value: TriggerChannelValue{
ctx: ctx, cMsgList: ccMsg[split*(len(ccMsg)/split):]}} ctx: ctx, cMsgList: ccMsg[split*(len(ccMsg)/split):],
}}
} }
log.ZDebug(ctx, "timer trigger msg consumer end", "length", len(ccMsg)) log.ZDebug(ctx, "timer trigger msg consumer end", "length", len(ccMsg))
} }
@@ -34,8 +34,10 @@ type OnlineHistoryMongoConsumerHandler struct {
func NewOnlineHistoryMongoConsumerHandler(database controller.CommonMsgDatabase) *OnlineHistoryMongoConsumerHandler { func NewOnlineHistoryMongoConsumerHandler(database controller.CommonMsgDatabase) *OnlineHistoryMongoConsumerHandler {
mc := &OnlineHistoryMongoConsumerHandler{ mc := &OnlineHistoryMongoConsumerHandler{
historyConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0, historyConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.MsgToMongo.Topic}, KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
}, []string{config.Config.Kafka.MsgToMongo.Topic},
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMongo), config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMongo),
msgDatabase: database, msgDatabase: database,
} }
@@ -36,8 +36,10 @@ type PersistentConsumerHandler struct {
func NewPersistentConsumerHandler(database controller.ChatLogDatabase) *PersistentConsumerHandler { func NewPersistentConsumerHandler(database controller.ChatLogDatabase) *PersistentConsumerHandler {
return &PersistentConsumerHandler{ return &PersistentConsumerHandler{
persistentConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0, persistentConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.LatestMsgToRedis.Topic}, KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMySql), config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMySql),
chatLogDatabase: database, chatLogDatabase: database,
} }
@@ -59,9 +61,9 @@ func (pc *PersistentConsumerHandler) handleChatWs2Mysql(
} }
return return
log.ZDebug(ctx, "handleChatWs2Mysql", "msg", msgFromMQ.MsgData) log.ZDebug(ctx, "handleChatWs2Mysql", "msg", msgFromMQ.MsgData)
//Control whether to store history messages (mysql) // Control whether to store history messages (mysql)
isPersist := utils.GetSwitchFromOptions(msgFromMQ.MsgData.Options, constant.IsPersistent) isPersist := utils.GetSwitchFromOptions(msgFromMQ.MsgData.Options, constant.IsPersistent)
//Only process receiver data // Only process receiver data
if isPersist { if isPersist {
switch msgFromMQ.MsgData.SessionType { switch msgFromMQ.MsgData.SessionType {
case constant.SingleChatType, constant.NotificationChatType: case constant.SingleChatType, constant.NotificationChatType:
+3 -3
View File
@@ -95,7 +95,7 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
if err == nil { if err == nil {
apns.Payload.Aps.Badge = &unreadCountSum apns.Payload.Aps.Badge = &unreadCountSum
} else { } else {
//log.Error(operationID, "IncrUserBadgeUnreadCountSum redis err", err.Error(), uid) // log.Error(operationID, "IncrUserBadgeUnreadCountSum redis err", err.Error(), uid)
Fail++ Fail++
continue continue
} }
@@ -107,7 +107,7 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
zero := 1 zero := 1
apns.Payload.Aps.Badge = &zero apns.Payload.Aps.Badge = &zero
} else { } else {
//log.Error(operationID, "GetUserBadgeUnreadCountSum redis err", err.Error(), uid) // log.Error(operationID, "GetUserBadgeUnreadCountSum redis err", err.Error(), uid)
Fail++ Fail++
continue continue
} }
@@ -127,7 +127,7 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
response, err := f.fcmMsgCli.SendAll(ctx, messages) response, err := f.fcmMsgCli.SendAll(ctx, messages)
if err != nil { if err != nil {
Fail = Fail + messageCount Fail = Fail + messageCount
//log.Info(operationID, "some token push err", err.Error(), messageCount) // log.Info(operationID, "some token push err", err.Error(), messageCount)
} else { } else {
Success = Success + response.SuccessCount Success = Success + response.SuccessCount
Fail = Fail + response.FailureCount Fail = Fail + response.FailureCount
+1 -1
View File
@@ -145,7 +145,7 @@ func newPushReq(title, content string) PushReq {
} }
func newBatchPushReq(userIDs []string, taskID string) PushReq { func newBatchPushReq(userIDs []string, taskID string) PushReq {
var IsAsync = true IsAsync := true
return PushReq{Audience: &Audience{Alias: userIDs}, IsAsync: &IsAsync, TaskID: &taskID} return PushReq{Audience: &Audience{Alias: userIDs}, IsAsync: &IsAsync, TaskID: &taskID}
} }
+5 -6
View File
@@ -15,17 +15,16 @@
package getui package getui
import ( import (
"sync"
"github.com/go-redis/redis"
"context" "context"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"errors" "errors"
"strconv" "strconv"
"sync"
"time" "time"
"github.com/go-redis/redis"
"github.com/OpenIMSDK/Open-IM-Server/internal/push/offlinepush" "github.com/OpenIMSDK/Open-IM-Server/internal/push/offlinepush"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
@@ -49,7 +48,7 @@ const (
taskURL = "/push/list/message" taskURL = "/push/list/message"
batchPushURL = "/push/list/alias" batchPushURL = "/push/list/alias"
// codes // codes.
tokenExpireCode = 10001 tokenExpireCode = 10001
tokenExpireTime = 60 * 60 * 23 tokenExpireTime = 60 * 60 * 23
taskIDTTL = 1000 * 60 * 60 * 24 taskIDTTL = 1000 * 60 * 60 * 24
@@ -142,7 +141,7 @@ func (g *Client) GetTaskID(ctx context.Context, token string, pushReq PushReq) (
return respTask.TaskID, nil return respTask.TaskID, nil
} }
// max num is 999 // max num is 999.
func (g *Client) batchPush(ctx context.Context, token string, userIDs []string, pushReq PushReq) error { func (g *Client) batchPush(ctx context.Context, token string, userIDs []string, pushReq PushReq) error {
taskID, err := g.GetTaskID(ctx, token, pushReq) taskID, err := g.GetTaskID(ctx, token, pushReq)
if err != nil { if err != nil {
@@ -66,6 +66,7 @@ func (p *Platform) Set(os string) error {
return nil return nil
} }
func (p *Platform) SetPlatform(platform string) error { func (p *Platform) SetPlatform(platform string) error {
switch platform { switch platform {
case constant.AndroidPlatformStr: case constant.AndroidPlatformStr:
@@ -75,8 +76,8 @@ func (p *Platform) SetPlatform(platform string) error {
default: default:
return errors.New("platform err") return errors.New("platform err")
} }
} }
func (p *Platform) SetIOS() error { func (p *Platform) SetIOS() error {
return p.Set(IOS) return p.Set(IOS)
} }
@@ -37,6 +37,7 @@ func (p *PushObj) SetNotification(no *Notification) {
func (p *PushObj) SetMessage(m *Message) { func (p *PushObj) SetMessage(m *Message) {
p.Message = m p.Message = m
} }
func (p *PushObj) SetOptions(o *Options) { func (p *PushObj) SetOptions(o *Options) {
p.Options = o p.Options = o
} }
@@ -18,10 +18,12 @@ import (
"context" "context"
) )
// OfflinePusher Offline Pusher
type OfflinePusher interface { type OfflinePusher interface {
Push(ctx context.Context, userIDs []string, title, content string, opts *Opts) error Push(ctx context.Context, userIDs []string, title, content string, opts *Opts) error
} }
// Opts opts
type Opts struct { type Opts struct {
Signal *Signal Signal *Signal
IOSPushSound string IOSPushSound string
@@ -29,6 +31,7 @@ type Opts struct {
Ex string Ex string
} }
// Signal message id
type Signal struct { type Signal struct {
ClientMsgID string ClientMsgID string
} }
+6 -3
View File
@@ -37,8 +37,10 @@ type ConsumerHandler struct {
func NewConsumerHandler(pusher *Pusher) *ConsumerHandler { func NewConsumerHandler(pusher *Pusher) *ConsumerHandler {
var consumerHandler ConsumerHandler var consumerHandler ConsumerHandler
consumerHandler.pusher = pusher consumerHandler.pusher = pusher
consumerHandler.pushConsumerGroup = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0, consumerHandler.pushConsumerGroup = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.MsgToPush.Topic}, config.Config.Kafka.Addr, KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
}, []string{config.Config.Kafka.MsgToPush.Topic}, config.Config.Kafka.Addr,
config.Config.Kafka.ConsumerGroupID.MsgToPush) config.Config.Kafka.ConsumerGroupID.MsgToPush)
return &consumerHandler return &consumerHandler
} }
@@ -76,7 +78,8 @@ func (c *ConsumerHandler) handleMs2PsChat(ctx context.Context, msg []byte) {
func (ConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil } func (ConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
func (ConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil } func (ConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
func (c *ConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession, func (c *ConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession,
claim sarama.ConsumerGroupClaim) error { claim sarama.ConsumerGroupClaim,
) error {
for msg := range claim.Messages() { for msg := range claim.Messages() {
ctx := c.pushConsumerGroup.GetContextFromMsg(msg) ctx := c.pushConsumerGroup.GetContextFromMsg(msg)
c.handleMs2PsChat(ctx, msg.Value) c.handleMs2PsChat(ctx, msg.Value)
+18 -4
View File
@@ -1,3 +1,17 @@
// 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 push package push
import ( import (
@@ -40,7 +54,8 @@ var errNoOfflinePusher = errors.New("no offlinePusher is configured")
func NewPusher(discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offlinepush.OfflinePusher, database controller.PushDatabase, func NewPusher(discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offlinepush.OfflinePusher, database controller.PushDatabase,
groupLocalCache *localcache.GroupLocalCache, conversationLocalCache *localcache.ConversationLocalCache, groupLocalCache *localcache.GroupLocalCache, conversationLocalCache *localcache.ConversationLocalCache,
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient) *Pusher { conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient,
) *Pusher {
return &Pusher{ return &Pusher{
discov: discov, discov: discov,
database: database, database: database,
@@ -209,7 +224,7 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
} }
needOfflinePushUserIDs = utils.DifferenceString(notNotificationUserIDs, needOfflinePushUserIDs) needOfflinePushUserIDs = utils.DifferenceString(notNotificationUserIDs, needOfflinePushUserIDs)
} }
//Use offline push messaging // Use offline push messaging
if len(needOfflinePushUserIDs) > 0 { if len(needOfflinePushUserIDs) > 0 {
var offlinePushUserIDs []string var offlinePushUserIDs []string
err = callbackOfflinePush(ctx, needOfflinePushUserIDs, msg, &offlinePushUserIDs) err = callbackOfflinePush(ctx, needOfflinePushUserIDs, msg, &offlinePushUserIDs)
@@ -240,7 +255,7 @@ func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData,
if err != nil { if err != nil {
return nil, err return nil, err
} }
//Online push message // Online push message
for _, v := range conns { for _, v := range conns {
msgClient := msggateway.NewMsgGatewayClient(v) msgClient := msggateway.NewMsgGatewayClient(v)
reply, err := msgClient.SuperGroupOnlineBatchPushOneMsg(ctx, &msggateway.OnlineBatchPushOneMsgReq{MsgData: msg, PushToUserIDs: pushToUserIDs}) reply, err := msgClient.SuperGroupOnlineBatchPushOneMsg(ctx, &msggateway.OnlineBatchPushOneMsgReq{MsgData: msg, PushToUserIDs: pushToUserIDs})
@@ -251,7 +266,6 @@ func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData,
if reply != nil && reply.SinglePushResult != nil { if reply != nil && reply.SinglePushResult != nil {
wsResults = append(wsResults, reply.SinglePushResult...) wsResults = append(wsResults, reply.SinglePushResult...)
} }
} }
return wsResults, nil return wsResults, nil
} }
+7 -1
View File
@@ -23,6 +23,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
@@ -129,11 +130,16 @@ func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID
if err != nil { if err != nil {
return err return err
} }
for _, v := range conns {
log.ZDebug(ctx, "forceKickOff", "conn", v.(*grpc.ClientConn).Target())
}
for _, v := range conns { for _, v := range conns {
client := msggateway.NewMsgGatewayClient(v) client := msggateway.NewMsgGatewayClient(v)
kickReq := &msggateway.KickUserOfflineReq{KickUserIDList: []string{userID}, PlatformID: platformID} kickReq := &msggateway.KickUserOfflineReq{KickUserIDList: []string{userID}, PlatformID: platformID}
_, err := client.KickUserOffline(ctx, kickReq) _, err := client.KickUserOffline(ctx, kickReq)
return utils.Wrap(err, "") if err != nil {
log.ZError(ctx, "forceKickOff", err, "kickReq", kickReq)
}
} }
return nil return nil
} }
+22 -4
View File
@@ -1,8 +1,24 @@
// 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 conversation package conversation
import ( import (
"context" "context"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
@@ -17,7 +33,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"google.golang.org/grpc"
) )
type conversationServer struct { type conversationServer struct {
@@ -170,7 +185,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbConver
return &pbConversation.SetConversationsResp{}, nil return &pbConversation.SetConversationsResp{}, nil
} }
// 获取超级大群开启免打扰的用户ID // 获取超级大群开启免打扰的用户ID.
func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req *pbConversation.GetRecvMsgNotNotifyUserIDsReq) (*pbConversation.GetRecvMsgNotNotifyUserIDsResp, error) { func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req *pbConversation.GetRecvMsgNotNotifyUserIDsReq) (*pbConversation.GetRecvMsgNotNotifyUserIDsResp, error) {
userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID) userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID)
if err != nil { if err != nil {
@@ -179,7 +194,7 @@ func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req
return &pbConversation.GetRecvMsgNotNotifyUserIDsResp{UserIDs: userIDs}, nil return &pbConversation.GetRecvMsgNotNotifyUserIDsResp{UserIDs: userIDs}, nil
} }
// create conversation without notification for msg redis transfer // create conversation without notification for msg redis transfer.
func (c *conversationServer) CreateSingleChatConversations(ctx context.Context, req *pbConversation.CreateSingleChatConversationsReq) (*pbConversation.CreateSingleChatConversationsResp, error) { func (c *conversationServer) CreateSingleChatConversations(ctx context.Context, req *pbConversation.CreateSingleChatConversationsReq) (*pbConversation.CreateSingleChatConversationsResp, error) {
var conversation tableRelation.ConversationModel var conversation tableRelation.ConversationModel
conversation.ConversationID = utils.GetConversationIDBySessionType(constant.SingleChatType, req.RecvID, req.SendID) conversation.ConversationID = utils.GetConversationIDBySessionType(constant.SingleChatType, req.RecvID, req.SendID)
@@ -233,7 +248,10 @@ func (c *conversationServer) GetUserConversationIDsHash(ctx context.Context, req
return &pbConversation.GetUserConversationIDsHashResp{Hash: hash}, nil return &pbConversation.GetUserConversationIDsHashResp{Hash: hash}, nil
} }
func (c *conversationServer) GetConversationsByConversationID(ctx context.Context, req *pbConversation.GetConversationsByConversationIDReq) (*pbConversation.GetConversationsByConversationIDResp, error) { func (c *conversationServer) GetConversationsByConversationID(
ctx context.Context,
req *pbConversation.GetConversationsByConversationIDReq,
) (*pbConversation.GetConversationsByConversationIDResp, error) {
conversations, err := c.conversationDatabase.GetConversationsByConversationID(ctx, req.ConversationIDs) conversations, err := c.conversationDatabase.GetConversationsByConversationID(ctx, req.ConversationIDs)
if err != nil { if err != nil {
return nil, err return nil, err
+11 -11
View File
@@ -83,7 +83,7 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
return nil return nil
} }
// ok // ok.
func (s *friendServer) ApplyToAddFriend( func (s *friendServer) ApplyToAddFriend(
ctx context.Context, ctx context.Context,
req *pbfriend.ApplyToAddFriendReq, req *pbfriend.ApplyToAddFriendReq,
@@ -116,7 +116,7 @@ func (s *friendServer) ApplyToAddFriend(
return resp, nil return resp, nil
} }
// ok // ok.
func (s *friendServer) ImportFriends( func (s *friendServer) ImportFriends(
ctx context.Context, ctx context.Context,
req *pbfriend.ImportFriendReq, req *pbfriend.ImportFriendReq,
@@ -142,7 +142,7 @@ func (s *friendServer) ImportFriends(
return &pbfriend.ImportFriendResp{}, nil return &pbfriend.ImportFriendResp{}, nil
} }
// ok // ok.
func (s *friendServer) RespondFriendApply( func (s *friendServer) RespondFriendApply(
ctx context.Context, ctx context.Context,
req *pbfriend.RespondFriendApplyReq, req *pbfriend.RespondFriendApplyReq,
@@ -178,7 +178,7 @@ func (s *friendServer) RespondFriendApply(
return nil, errs.ErrArgs.Wrap("req.HandleResult != -1/1") return nil, errs.ErrArgs.Wrap("req.HandleResult != -1/1")
} }
// ok // ok.
func (s *friendServer) DeleteFriend( func (s *friendServer) DeleteFriend(
ctx context.Context, ctx context.Context,
req *pbfriend.DeleteFriendReq, req *pbfriend.DeleteFriendReq,
@@ -199,7 +199,7 @@ func (s *friendServer) DeleteFriend(
return resp, nil return resp, nil
} }
// ok // ok.
func (s *friendServer) SetFriendRemark( func (s *friendServer) SetFriendRemark(
ctx context.Context, ctx context.Context,
req *pbfriend.SetFriendRemarkReq, req *pbfriend.SetFriendRemarkReq,
@@ -220,7 +220,7 @@ func (s *friendServer) SetFriendRemark(
return resp, nil return resp, nil
} }
// ok // ok.
func (s *friendServer) GetDesignatedFriends( func (s *friendServer) GetDesignatedFriends(
ctx context.Context, ctx context.Context,
req *pbfriend.GetDesignatedFriendsReq, req *pbfriend.GetDesignatedFriendsReq,
@@ -240,13 +240,12 @@ func (s *friendServer) GetDesignatedFriends(
return resp, nil return resp, nil
} }
// ok 获取接收到的好友申请(即别人主动申请的) // ok 获取接收到的好友申请(即别人主动申请的).
func (s *friendServer) GetPaginationFriendsApplyTo( func (s *friendServer) GetPaginationFriendsApplyTo(
ctx context.Context, ctx context.Context,
req *pbfriend.GetPaginationFriendsApplyToReq, req *pbfriend.GetPaginationFriendsApplyToReq,
) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) { ) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) {
defer log.ZInfo(ctx, utils.GetFuncName()+" Return") defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
resp = &pbfriend.GetPaginationFriendsApplyToResp{}
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil { if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
return nil, err return nil, err
} }
@@ -255,6 +254,7 @@ func (s *friendServer) GetPaginationFriendsApplyTo(
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp = &pbfriend.GetPaginationFriendsApplyToResp{}
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userRpcClient.GetUsersInfoMap) resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userRpcClient.GetUsersInfoMap)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -263,7 +263,7 @@ func (s *friendServer) GetPaginationFriendsApplyTo(
return resp, nil return resp, nil
} }
// ok 获取主动发出去的好友申请列表 // ok 获取主动发出去的好友申请列表.
func (s *friendServer) GetPaginationFriendsApplyFrom( func (s *friendServer) GetPaginationFriendsApplyFrom(
ctx context.Context, ctx context.Context,
req *pbfriend.GetPaginationFriendsApplyFromReq, req *pbfriend.GetPaginationFriendsApplyFromReq,
@@ -286,7 +286,7 @@ func (s *friendServer) GetPaginationFriendsApplyFrom(
return resp, nil return resp, nil
} }
// ok // ok.
func (s *friendServer) IsFriend( func (s *friendServer) IsFriend(
ctx context.Context, ctx context.Context,
req *pbfriend.IsFriendReq, req *pbfriend.IsFriendReq,
@@ -300,7 +300,7 @@ func (s *friendServer) IsFriend(
return resp, nil return resp, nil
} }
// ok // ok.
func (s *friendServer) GetPaginationFriends( func (s *friendServer) GetPaginationFriends(
ctx context.Context, ctx context.Context,
req *pbfriend.GetPaginationFriendsReq, req *pbfriend.GetPaginationFriendsReq,
+2 -1
View File
@@ -16,9 +16,10 @@ package group
import ( import (
"context" "context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"time" "time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
pbGroup "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group" pbGroup "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
) )
+23 -8
View File
@@ -1,22 +1,39 @@
// 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 group package group
import ( import (
"context" "context"
"fmt" "fmt"
pbConversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
"math/big" "math/big"
"math/rand" "math/rand"
"strconv" "strconv"
"strings" "strings"
"time" "time"
pbConversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw/specialerror" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw/specialerror"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
@@ -31,7 +48,6 @@ import (
pbGroup "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group" pbGroup "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"google.golang.org/grpc"
) )
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error { func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
@@ -215,7 +231,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR
} }
}() }()
} else { } else {
//s.Notification.GroupCreatedNotification(ctx, group, groupMembers, userMap) // s.Notification.GroupCreatedNotification(ctx, group, groupMembers, userMap)
tips := &sdkws.GroupCreatedTips{ tips := &sdkws.GroupCreatedTips{
Group: resp.GroupInfo, Group: resp.GroupInfo,
OperationTime: group.CreateTime.UnixMilli(), OperationTime: group.CreateTime.UnixMilli(),
@@ -244,7 +260,7 @@ func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbGroup.GetJo
pageNumber = req.Pagination.PageNumber pageNumber = req.Pagination.PageNumber
showNumber = req.Pagination.ShowNumber showNumber = req.Pagination.ShowNumber
} }
//total, members, err := s.GroupDatabase.PageGroupMember(ctx, nil, []string{req.FromUserID}, nil, pageNumber, showNumber) // total, members, err := s.GroupDatabase.PageGroupMember(ctx, nil, []string{req.FromUserID}, nil, pageNumber, showNumber)
total, members, err := s.GroupDatabase.PageGetJoinGroup(ctx, req.FromUserID, pageNumber, showNumber) total, members, err := s.GroupDatabase.PageGetJoinGroup(ctx, req.FromUserID, pageNumber, showNumber)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -501,7 +517,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGrou
Notification: group.Notification, Notification: group.Notification,
Introduction: group.Introduction, Introduction: group.Introduction,
FaceURL: group.FaceURL, FaceURL: group.FaceURL,
//OwnerUserID: owner[0].UserID, // OwnerUserID: owner[0].UserID,
CreateTime: group.CreateTime.UnixMilli(), CreateTime: group.CreateTime.UnixMilli(),
MemberCount: num, MemberCount: num,
Ex: group.Ex, Ex: group.Ex,
@@ -886,7 +902,6 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbGroup.SetGroupInf
}() }()
num++ num++
s.Notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}) s.Notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser})
} }
switch len(data) - num { switch len(data) - num {
case 0: case 0:
@@ -1090,7 +1105,7 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbGroup.DismissGrou
if err != nil { if err != nil {
return nil, err return nil, err
} }
//s.Notification.GroupDismissedNotification(ctx, req) // s.Notification.GroupDismissedNotification(ctx, req)
tips := &sdkws.GroupDismissedTips{ tips := &sdkws.GroupDismissedTips{
Group: s.groupDB2PB(group, owner.UserID, num), Group: s.groupDB2PB(group, owner.UserID, num),
OpUser: &sdkws.GroupMemberFullInfo{}, OpUser: &sdkws.GroupMemberFullInfo{},
+16 -1
View File
@@ -1,10 +1,25 @@
// 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 group package group
import ( import (
"context" "context"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
"time"
) )
func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCreateCountReq) (*group.GroupCreateCountResp, error) { func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCreateCountReq) (*group.GroupCreateCountResp, error) {
+2 -5
View File
@@ -26,10 +26,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
) )
func (m *msgServer) GetConversationsHasReadAndMaxSeq( func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (*msg.GetConversationsHasReadAndMaxSeqResp, error) {
ctx context.Context,
req *msg.GetConversationsHasReadAndMaxSeqReq,
) (*msg.GetConversationsHasReadAndMaxSeqResp, error) {
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID) conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -42,7 +39,7 @@ func (m *msgServer) GetConversationsHasReadAndMaxSeq(
if err != nil { if err != nil {
return nil, err return nil, err
} }
var conversationMaxSeqMap = make(map[string]int64) conversationMaxSeqMap := make(map[string]int64)
for _, conversation := range conversations { for _, conversation := range conversations {
if conversation.MaxSeq != 0 { if conversation.MaxSeq != 0 {
conversationMaxSeqMap[conversation.ConversationID] = conversation.MaxSeq conversationMaxSeqMap[conversation.ConversationID] = conversation.MaxSeq
+4 -2
View File
@@ -36,6 +36,7 @@ type LockerMessage struct {
func NewLockerMessage(cache cache.MsgModel) *LockerMessage { func NewLockerMessage(cache cache.MsgModel) *LockerMessage {
return &LockerMessage{cache: cache} return &LockerMessage{cache: cache}
} }
func (l *LockerMessage) LockMessageTypeKey(ctx context.Context, clientMsgID, typeKey string) (err error) { func (l *LockerMessage) LockMessageTypeKey(ctx context.Context, clientMsgID, typeKey string) (err error) {
for i := 0; i < 3; i++ { for i := 0; i < 3; i++ {
err = l.cache.LockMessageTypeKey(ctx, clientMsgID, typeKey) err = l.cache.LockMessageTypeKey(ctx, clientMsgID, typeKey)
@@ -47,8 +48,8 @@ func (l *LockerMessage) LockMessageTypeKey(ctx context.Context, clientMsgID, typ
} }
} }
return err return err
} }
func (l *LockerMessage) LockGlobalMessage(ctx context.Context, clientMsgID string) (err error) { func (l *LockerMessage) LockGlobalMessage(ctx context.Context, clientMsgID string) (err error) {
for i := 0; i < 3; i++ { for i := 0; i < 3; i++ {
err = l.cache.LockMessageTypeKey(ctx, clientMsgID, GlOBALLOCK) err = l.cache.LockMessageTypeKey(ctx, clientMsgID, GlOBALLOCK)
@@ -60,11 +61,12 @@ func (l *LockerMessage) LockGlobalMessage(ctx context.Context, clientMsgID strin
} }
} }
return err return err
} }
func (l *LockerMessage) UnLockMessageTypeKey(ctx context.Context, clientMsgID string, typeKey string) error { func (l *LockerMessage) UnLockMessageTypeKey(ctx context.Context, clientMsgID string, typeKey string) error {
return l.cache.UnLockMessageTypeKey(ctx, clientMsgID, typeKey) return l.cache.UnLockMessageTypeKey(ctx, clientMsgID, typeKey)
} }
func (l *LockerMessage) UnLockGlobalMessage(ctx context.Context, clientMsgID string) error { func (l *LockerMessage) UnLockGlobalMessage(ctx context.Context, clientMsgID string) error {
return l.cache.UnLockMessageTypeKey(ctx, clientMsgID, GlOBALLOCK) return l.cache.UnLockMessageTypeKey(ctx, clientMsgID, GlOBALLOCK)
} }
+6 -3
View File
@@ -16,7 +16,6 @@ package msg
import ( import (
"context" "context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
@@ -84,6 +83,7 @@ func (m *msgServer) sendMsgSuperGroupChat(
resp.ClientMsgID = req.MsgData.ClientMsgID resp.ClientMsgID = req.MsgData.ClientMsgID
return resp, nil return resp, nil
} }
func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgData) { func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgData) {
log.ZDebug(nctx, "setConversationAtInfo", "msg", msg) log.ZDebug(nctx, "setConversationAtInfo", "msg", msg)
ctx := mcontext.NewCtx("@@@" + mcontext.GetOperationID(nctx)) ctx := mcontext.NewCtx("@@@" + mcontext.GetOperationID(nctx))
@@ -101,7 +101,7 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
return return
} }
atUserID = utils.DifferenceString([]string{constant.AtAllString}, msg.AtUserIDList) atUserID = utils.DifferenceString([]string{constant.AtAllString}, msg.AtUserIDList)
if len(atUserID) == 0 { //just @everyone if len(atUserID) == 0 { // just @everyone
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll} conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll}
} else { //@Everyone and @other people } else { //@Everyone and @other people
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAllAtMe} conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAllAtMe}
@@ -123,7 +123,6 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
log.ZWarn(ctx, "SetConversations", err, msg.AtUserIDList, conversation) log.ZWarn(ctx, "SetConversations", err, msg.AtUserIDList, conversation)
} }
} }
} }
func (m *msgServer) sendMsgNotification( func (m *msgServer) sendMsgNotification(
@@ -189,3 +188,7 @@ func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbMsg.SendMsgReq
return resp, nil return resp, nil
} }
} }
func (m *msgServer) BatchSendMsg(ctx context.Context, in *pbMsg.BatchSendMessageReq) (*pbMsg.BatchSendMessageResp, error) {
return nil, nil
}
+35 -17
View File
@@ -1,8 +1,24 @@
// 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 msg package msg
import ( import (
"context" "context"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
@@ -13,23 +29,24 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"google.golang.org/grpc"
) )
type MessageInterceptorChain []MessageInterceptorFunc type (
type msgServer struct { MessageInterceptorChain []MessageInterceptorFunc
RegisterCenter discoveryregistry.SvcDiscoveryRegistry msgServer struct {
MsgDatabase controller.CommonMsgDatabase RegisterCenter discoveryregistry.SvcDiscoveryRegistry
Group *rpcclient.GroupRpcClient MsgDatabase controller.CommonMsgDatabase
User *rpcclient.UserRpcClient Group *rpcclient.GroupRpcClient
Conversation *rpcclient.ConversationRpcClient User *rpcclient.UserRpcClient
friend *rpcclient.FriendRpcClient Conversation *rpcclient.ConversationRpcClient
GroupLocalCache *localcache.GroupLocalCache friend *rpcclient.FriendRpcClient
ConversationLocalCache *localcache.ConversationLocalCache GroupLocalCache *localcache.GroupLocalCache
MessageLocker MessageLocker ConversationLocalCache *localcache.ConversationLocalCache
Handlers MessageInterceptorChain MessageLocker MessageLocker
notificationSender *rpcclient.NotificationSender Handlers MessageInterceptorChain
} notificationSender *rpcclient.NotificationSender
}
)
func (m *msgServer) addInterceptorHandler(interceptorFunc ...MessageInterceptorFunc) { func (m *msgServer) addInterceptorHandler(interceptorFunc ...MessageInterceptorFunc) {
m.Handlers = append(m.Handlers, interceptorFunc...) m.Handlers = append(m.Handlers, interceptorFunc...)
@@ -60,11 +77,11 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
} }
cacheModel := cache.NewMsgCacheModel(rdb) cacheModel := cache.NewMsgCacheModel(rdb)
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase()) msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, cacheModel)
conversationClient := rpcclient.NewConversationRpcClient(client) conversationClient := rpcclient.NewConversationRpcClient(client)
userRpcClient := rpcclient.NewUserRpcClient(client) userRpcClient := rpcclient.NewUserRpcClient(client)
groupRpcClient := rpcclient.NewGroupRpcClient(client) groupRpcClient := rpcclient.NewGroupRpcClient(client)
friendRpcClient := rpcclient.NewFriendRpcClient(client) friendRpcClient := rpcclient.NewFriendRpcClient(client)
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, cacheModel)
s := &msgServer{ s := &msgServer{
Conversation: &conversationClient, Conversation: &conversationClient,
User: &userRpcClient, User: &userRpcClient,
@@ -100,7 +117,8 @@ func (m *msgServer) initPrometheus() {
} }
func (m *msgServer) conversationAndGetRecvID(conversation *conversation.Conversation, userID string) (recvID string) { func (m *msgServer) conversationAndGetRecvID(conversation *conversation.Conversation, userID string) (recvID string) {
if conversation.ConversationType == constant.SingleChatType || conversation.ConversationType == constant.NotificationChatType { if conversation.ConversationType == constant.SingleChatType ||
conversation.ConversationType == constant.NotificationChatType {
if userID == conversation.OwnerUserID { if userID == conversation.OwnerUserID {
recvID = conversation.UserID recvID = conversation.UserID
} else { } else {
+33 -3
View File
@@ -1,16 +1,39 @@
// 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 msg package msg
import ( import (
"context" "context"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"time"
) )
func (m *msgServer) GetActiveUser(ctx context.Context, req *msg.GetActiveUserReq) (*msg.GetActiveUserResp, error) { func (m *msgServer) GetActiveUser(ctx context.Context, req *msg.GetActiveUserReq) (*msg.GetActiveUserResp, error) {
msgCount, userCount, users, dateCount, err := m.MsgDatabase.RangeUserSendCount(ctx, time.UnixMilli(req.Start), time.UnixMilli(req.End), req.Group, req.Ase, req.Pagination.PageNumber, req.Pagination.ShowNumber) msgCount, userCount, users, dateCount, err := m.MsgDatabase.RangeUserSendCount(
ctx,
time.UnixMilli(req.Start),
time.UnixMilli(req.End),
req.Group,
req.Ase,
req.Pagination.PageNumber,
req.Pagination.ShowNumber,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -45,7 +68,14 @@ func (m *msgServer) GetActiveUser(ctx context.Context, req *msg.GetActiveUserReq
} }
func (m *msgServer) GetActiveGroup(ctx context.Context, req *msg.GetActiveGroupReq) (*msg.GetActiveGroupResp, error) { func (m *msgServer) GetActiveGroup(ctx context.Context, req *msg.GetActiveGroupReq) (*msg.GetActiveGroupResp, error) {
msgCount, groupCount, groups, dateCount, err := m.MsgDatabase.RangeGroupSendCount(ctx, time.UnixMilli(req.Start), time.UnixMilli(req.End), req.Ase, req.Pagination.PageNumber, req.Pagination.ShowNumber) msgCount, groupCount, groups, dateCount, err := m.MsgDatabase.RangeGroupSendCount(
ctx,
time.UnixMilli(req.Start),
time.UnixMilli(req.End),
req.Ase,
req.Pagination.PageNumber,
req.Pagination.ShowNumber,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
+49
View File
@@ -17,6 +17,9 @@ package msg
import ( import (
"context" "context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
@@ -102,3 +105,49 @@ func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sd
resp.MaxSeqs = maxSeqs resp.MaxSeqs = maxSeqs
return resp, nil return resp, nil
} }
func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (resp *msg.SearchMessageResp, err error) {
var chatLogs []*sdkws.MsgData
var total int32
resp = &msg.SearchMessageResp{}
if total, chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil {
return nil, err
}
for _, chatLog := range chatLogs {
pbChatLog := &msg.ChatLog{}
utils.CopyStructFields(pbChatLog, chatLog)
pbChatLog.SendTime = chatLog.SendTime
pbChatLog.CreateTime = chatLog.CreateTime
if chatLog.SenderNickname == "" {
sendUser, err := m.User.GetUserInfo(ctx, chatLog.SendID)
if err != nil {
return nil, err
}
pbChatLog.SenderNickname = sendUser.Nickname
}
switch chatLog.SessionType {
case constant.SingleChatType:
recvUser, err := m.User.GetUserInfo(ctx, chatLog.RecvID)
if err != nil {
return nil, err
}
pbChatLog.RecvNickname = recvUser.Nickname
case constant.GroupChatType, constant.SuperGroupChatType:
group, err := m.Group.GetGroupInfo(ctx, chatLog.GroupID)
if err != nil {
return nil, err
}
pbChatLog.SenderFaceURL = group.FaceURL
pbChatLog.GroupMemberCount = group.MemberCount
pbChatLog.RecvID = group.GroupID
pbChatLog.GroupName = group.GroupName
pbChatLog.GroupOwner = group.OwnerUserID
pbChatLog.GroupType = group.GroupType
}
resp.ChatLogs = append(resp.ChatLogs, pbChatLog)
}
resp.ChatLogsNum = total
return resp, nil
}
+2 -3
View File
@@ -28,9 +28,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
) )
var ( var ExcludeContentType = []int{constant.HasReadReceipt}
ExcludeContentType = []int{constant.HasReadReceipt}
)
type Validator interface { type Validator interface {
validate(pb *msg.SendMsgReq) (bool, int32, string) validate(pb *msg.SendMsgReq) (bool, int32, string)
@@ -126,6 +124,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
return nil return nil
} }
} }
func (m *msgServer) encapsulateMsgData(msg *sdkws.MsgData) { func (m *msgServer) encapsulateMsgData(msg *sdkws.MsgData) {
msg.ServerMsgID = GetMsgID(msg.SendID) msg.ServerMsgID = GetMsgID(msg.SendID)
msg.SendTime = utils.GetCurrentTimestampByMill() msg.SendTime = utils.GetCurrentTimestampByMill()
+16 -1
View File
@@ -1,7 +1,23 @@
// 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 third package third
import ( import (
"context" "context"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cont" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cont"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
@@ -9,7 +25,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"time"
) )
func (t *thirdServer) PartLimit(ctx context.Context, req *third.PartLimitReq) (*third.PartLimitResp, error) { func (t *thirdServer) PartLimit(ctx context.Context, req *third.PartLimitReq) (*third.PartLimitResp, error) {
+19 -3
View File
@@ -1,14 +1,31 @@
// 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 third package third
import ( import (
"context" "context"
"fmt" "fmt"
"net/url"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cos" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cos"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/minio" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/minio"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/oss" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/oss"
"net/url"
"time" "google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
@@ -18,7 +35,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"google.golang.org/grpc"
) )
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error { func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
+17 -2
View File
@@ -1,15 +1,30 @@
// 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 third package third
import ( import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"strings"
"unicode/utf8"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"strings"
"unicode/utf8"
) )
func toPbMapArray(m map[string][]string) []*third.KeyValues { func toPbMapArray(m map[string][]string) []*third.KeyValues {
+19 -3
View File
@@ -1,12 +1,27 @@
// 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 user package user
import ( import (
"context" "context"
"errors" "errors"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"strings" "strings"
"time" "time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
@@ -23,8 +38,9 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"google.golang.org/grpc" "google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
) )
type userServer struct { type userServer struct {
@@ -219,7 +235,7 @@ func (s *userServer) GetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Ge
} }
func (s *userServer) GetAllUserID(ctx context.Context, req *pbuser.GetAllUserIDReq) (resp *pbuser.GetAllUserIDResp, err error) { func (s *userServer) GetAllUserID(ctx context.Context, req *pbuser.GetAllUserIDReq) (resp *pbuser.GetAllUserIDResp, err error) {
userIDs, err := s.UserDatabase.GetAllUserID(ctx) userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination.PageNumber, req.Pagination.ShowNumber)
if err != nil { if err != nil {
return nil, err return nil, err
} }
+26 -1
View File
@@ -1,3 +1,17 @@
// 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 tools package tools
import ( import (
@@ -19,7 +33,18 @@ func (c *MsgTool) ConversationsDestructMsgs() {
} }
log.ZDebug(context.Background(), "nums conversations need destruct", "nums", len(conversations)) log.ZDebug(context.Background(), "nums conversations need destruct", "nums", len(conversations))
for _, conversation := range conversations { for _, conversation := range conversations {
log.ZDebug(ctx, "UserMsgsDestruct", "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID, "msgDestructTime", conversation.MsgDestructTime, "lastMsgDestructTime", conversation.LatestMsgDestructTime) log.ZDebug(
ctx,
"UserMsgsDestruct",
"conversationID",
conversation.ConversationID,
"ownerUserID",
conversation.OwnerUserID,
"msgDestructTime",
conversation.MsgDestructTime,
"lastMsgDestructTime",
conversation.LatestMsgDestructTime,
)
seqs, err := c.msgDatabase.UserMsgsDestruct(ctx, conversation.OwnerUserID, conversation.ConversationID, conversation.MsgDestructTime, conversation.LatestMsgDestructTime) seqs, err := c.msgDatabase.UserMsgsDestruct(ctx, conversation.OwnerUserID, conversation.ConversationID, conversation.MsgDestructTime, conversation.LatestMsgDestructTime)
if err != nil { if err != nil {
log.ZError(ctx, "user msg destruct failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID) log.ZError(ctx, "user msg destruct failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
+5 -5
View File
@@ -41,11 +41,11 @@ func StartCronTask() error {
panic(err) panic(err)
} }
log.ZInfo(context.Background(), "start msgDestruct cron task", "cron config", config.Config.MsgDestructTime) log.ZInfo(context.Background(), "start msgDestruct cron task", "cron config", config.Config.MsgDestructTime)
_, err = c.AddFunc(config.Config.MsgDestructTime, msgTool.ConversationsDestructMsgs) // _, err = c.AddFunc(config.Config.MsgDestructTime, msgTool.ConversationsDestructMsgs)
if err != nil { // if err != nil {
fmt.Println("start conversationsDestructMsgs cron failed", err.Error(), config.Config.ChatRecordsClearTime) // fmt.Println("start conversationsDestructMsgs cron failed", err.Error(), config.Config.ChatRecordsClearTime)
panic(err) // panic(err)
} // }
c.Start() c.Start()
wg.Wait() wg.Wait()
return nil return nil
+30 -6
View File
@@ -1,3 +1,17 @@
// 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 tools package tools
import ( import (
@@ -6,6 +20,10 @@ import (
"math" "math"
"time" "time"
"github.com/redis/go-redis/v9"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
@@ -20,9 +38,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification" "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"github.com/redis/go-redis/v9"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
) )
type MsgTool struct { type MsgTool struct {
@@ -34,7 +49,8 @@ type MsgTool struct {
} }
func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controller.UserDatabase, func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controller.UserDatabase,
groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase, msgNotificationSender *notification.MsgNotificationSender) *MsgTool { groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase, msgNotificationSender *notification.MsgNotificationSender,
) *MsgTool {
return &MsgTool{ return &MsgTool{
msgDatabase: msgDatabase, msgDatabase: msgDatabase,
userDatabase: userDatabase, userDatabase: userDatabase,
@@ -66,9 +82,17 @@ func InitMsgTool() (*MsgTool, error) {
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials())) discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
userDB := relation.NewUserGorm(db) userDB := relation.NewUserGorm(db)
msgDatabase := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase()) msgDatabase := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase())
userDatabase := controller.NewUserDatabase(userDB, cache.NewUserCacheRedis(rdb, relation.NewUserGorm(db), cache.GetDefaultOpt()), tx.NewGorm(db)) userDatabase := controller.NewUserDatabase(
userDB,
cache.NewUserCacheRedis(rdb, relation.NewUserGorm(db), cache.GetDefaultOpt()),
tx.NewGorm(db),
)
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase()) groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase())
conversationDatabase := controller.NewConversationDatabase(relation.NewConversationGorm(db), cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)), tx.NewGorm(db)) conversationDatabase := controller.NewConversationDatabase(
relation.NewConversationGorm(db),
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)),
tx.NewGorm(db),
)
msgRpcClient := rpcclient.NewMessageRpcClient(discov) msgRpcClient := rpcclient.NewMessageRpcClient(discov)
msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient)) msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient))
msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase, msgNotificationSender) msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase, msgNotificationSender)
+14
View File
@@ -1,3 +1,17 @@
// 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 apiresp package apiresp
type ApiFormat interface { type ApiFormat interface {
-69
View File
@@ -1,69 +0,0 @@
// 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 apistruct
type UserRegisterReq struct {
Secret string `json:"secret" binding:"required,max=32"`
Platform int32 `json:"platform" binding:"required,min=1,max=12"`
ApiUserInfo
OperationID string `json:"operationID" binding:"required"`
}
type UserTokenInfo struct {
UserID string `json:"userID"`
Token string `json:"token"`
ExpiredTime int64 `json:"expiredTime"`
}
type UserRegisterResp struct {
UserToken UserTokenInfo `json:"data"`
}
type UserTokenReq struct {
Secret string `json:"secret" binding:"required,max=32"`
Platform int32 `json:"platform" binding:"required,min=1,max=12"`
UserID string `json:"userID" binding:"required,min=1,max=64"`
OperationID string `json:"operationID" binding:"required"`
}
type UserTokenResp struct {
UserToken UserTokenInfo `json:"data"`
}
type ForceLogoutReq struct {
Platform int32 `json:"platform" binding:"required,min=1,max=12"`
FromUserID string `json:"fromUserID" binding:"required,min=1,max=64"`
OperationID string `json:"operationID" binding:"required"`
}
type ForceLogoutResp struct {
}
type ParseTokenReq struct {
OperationID string `json:"operationID" binding:"required"`
}
//type ParseTokenResp struct {
//
// ExpireTime int64 `json:"expireTime" binding:"required"`
//}
type ExpireTime struct {
ExpireTimeSeconds uint32 `json:"expireTimeSeconds"`
}
type ParseTokenResp struct {
Data map[string]interface{} `json:"data" swaggerignore:"true"`
ExpireTime ExpireTime `json:"-"`
}
-33
View File
@@ -1,33 +0,0 @@
// 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 apistruct
type AwsStorageCredentialReq struct {
OperationID string `json:"operationID"`
}
type AwsStorageCredentialRespData struct {
AccessKeyId string `json:"accessKeyID"`
SecretAccessKey string `json:"secretAccessKey"`
SessionToken string `json:"sessionToken"`
RegionID string `json:"regionId"`
Bucket string `json:"bucket"`
FinalHost string `json:"FinalHost"`
}
type AwsStorageCredentialResp struct {
CosData AwsStorageCredentialRespData
Data map[string]interface{} `json:"data"`
}
-134
View File
@@ -1,134 +0,0 @@
// 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 apistruct
type OptResult struct {
ConversationID string `json:"conversationID"`
Result *int32 `json:"result"`
}
type GetAllConversationMessageOptReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetAllConversationMessageOptResp struct {
ConversationOptResultList []*OptResult `json:"data"`
}
type GetReceiveMessageOptReq struct {
ConversationIDList []string `json:"conversationIDList" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetReceiveMessageOptResp struct {
ConversationOptResultList []*OptResult `json:"data"`
}
type SetReceiveMessageOptReq struct {
FromUserID string `json:"fromUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
Opt *int32 `json:"opt" binding:"required"`
ConversationIDList []string `json:"conversationIDList" binding:"required"`
}
type SetReceiveMessageOptResp struct {
ConversationOptResultList []*OptResult `json:"data"`
}
type Conversation struct {
OwnerUserID string `json:"ownerUserID" binding:"required"`
ConversationID string `json:"conversationID" binding:"required"`
ConversationType int32 `json:"conversationType" binding:"required"`
UserID string `json:"userID"`
GroupID string `json:"groupID"`
RecvMsgOpt int32 `json:"recvMsgOpt" binding:"omitempty,oneof=0 1 2"`
UnreadCount int32 `json:"unreadCount" binding:"omitempty"`
DraftTextTime int64 `json:"draftTextTime"`
IsPinned bool `json:"isPinned" binding:"omitempty"`
IsPrivateChat bool `json:"isPrivateChat"`
BurnDuration int32 `json:"burnDuration"`
GroupAtType int32 `json:"groupAtType"`
IsNotInGroup bool `json:"isNotInGroup"`
UpdateUnreadCountTime int64 `json:"updateUnreadCountTime"`
AttachedInfo string `json:"attachedInfo"`
Ex string `json:"ex"`
}
type SetConversationReq struct {
Conversation
NotificationType int32 `json:"notificationType"`
OperationID string `json:"operationID" binding:"required"`
}
type SetConversationResp struct {
}
type ModifyConversationFieldReq struct {
Conversation
FieldType int32 `json:"fieldType" binding:"required"`
UserIDList []string `json:"userIDList" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type ModifyConversationFieldResp struct {
}
type BatchSetConversationsReq struct {
Conversations []Conversation `json:"conversations" binding:"required"`
NotificationType int32 `json:"notificationType"`
OwnerUserID string `json:"ownerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type BatchSetConversationsResp struct {
Data struct {
Success []string `json:"success"`
Failed []string `json:"failed"`
} `json:"data"`
}
type GetConversationReq struct {
ConversationID string `json:"conversationID" binding:"required"`
OwnerUserID string `json:"ownerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetConversationResp struct {
Conversation Conversation `json:"data"`
}
type GetAllConversationsReq struct {
OwnerUserID string `json:"ownerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetAllConversationsResp struct {
Conversations []Conversation `json:"data"`
}
type GetConversationsReq struct {
ConversationIDs []string `json:"conversationIDs" binding:"required"`
OwnerUserID string `json:"ownerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetConversationsResp struct {
Conversations []Conversation `json:"data"`
}
type SetRecvMsgOptReq struct {
OwnerUserID string `json:"ownerUserID" binding:"required"`
ConversationID string `json:"conversationID"`
RecvMsgOpt int32 `json:"recvMsgOpt" binding:"omitempty,oneof=0 1 2"`
OperationID string `json:"operationID" binding:"required"`
NotificationType int32 `json:"notificationType"`
}
type SetRecvMsgOptResp struct {
}
-33
View File
@@ -1,33 +0,0 @@
// 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 apistruct
import sts "github.com/tencentyun/qcloud-cos-sts-sdk/go"
type TencentCloudStorageCredentialReq struct {
OperationID string `json:"operationID"`
}
type TencentCloudStorageCredentialRespData struct {
*sts.CredentialResult
Region string `json:"region"`
Bucket string `json:"bucket"`
}
type TencentCloudStorageCredentialResp struct {
CosData TencentCloudStorageCredentialRespData `json:"-"`
Data map[string]interface{} `json:"data"`
}
-287
View File
@@ -1,287 +0,0 @@
// 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 apistruct
//type ParamsCommFriend struct {
// OperationID string `json:"operationID" binding:"required"`
// ToUserID string `json:"toUserID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//
//type AddBlacklistReq struct {
// ParamsCommFriend
//}
//type AddBlacklistResp struct {
//
//}
//
//type ImportFriendReq struct {
// FriendUserIDList []string `json:"friendUserIDList" binding:"required"`
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type UserIDResult struct {
// UserID string `json:"userID"`
// Result int32 `json:"result"`
//}
//type ImportFriendResp struct {
//
// UserIDResultList []UserIDResult `json:"data"`
//}
//
//type AddFriendReq struct {
// ParamsCommFriend
// ReqMsg string `json:"reqMsg"`
//}
//type AddFriendResp struct {
//
//}
//
//type AddFriendResponseReq struct {
// ParamsCommFriend
// Flag int32 `json:"flag" binding:"required,oneof=-1 0 1"`
// HandleMsg string `json:"handleMsg"`
//}
//type AddFriendResponseResp struct {
//
//}
//
//type DeleteFriendReq struct {
// ParamsCommFriend
//}
//type DeleteFriendResp struct {
//
//}
//
//type GetBlackListReq struct {
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type GetBlackListResp struct {
//
// BlackUserInfoList []*sdkws.PublicUserInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
////type PublicUserInfo struct {
//// UserID string `json:"userID"`
//// Nickname string `json:"nickname"`
//// FaceUrl string `json:"faceUrl"`
//// Gender int32 `json:"gender"`
////}
//
//type SetFriendRemarkReq struct {
// ParamsCommFriend
// Remark string `json:"remark"`
//}
//type SetFriendRemarkResp struct {
//
//}
//
//type RemoveBlacklistReq struct {
// ParamsCommFriend
//}
//type RemoveBlacklistResp struct {
//
//}
//
//type IsFriendReq struct {
// ParamsCommFriend
//}
//type Response struct {
// Friend bool `json:"isFriend"`
//}
//type IsFriendResp struct {
//
// Response Response `json:"data"`
//}
//
//type GetFriendsInfoReq struct {
// ParamsCommFriend
//}
//type GetFriendsInfoResp struct {
//
// FriendInfoList []*sdkws.FriendInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
//type GetFriendListReq struct {
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type GetFriendListResp struct {
//
// FriendInfoList []*sdkws.FriendInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
//type GetFriendApplyListReq struct {
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type GetFriendApplyListResp struct {
//
// FriendRequestList []*sdkws.FriendRequest `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
//type GetSelfApplyListReq struct {
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type GetSelfApplyListResp struct {
//
// FriendRequestList []*sdkws.FriendRequest `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
type FriendInfo struct {
UserID string `json:"userID"`
Nickname string `json:"nickname"`
FaceURL string `json:"faceURL"`
Gender int32 `json:"gender"`
Ex string `json:"ex"`
}
type PublicUserInfo struct {
UserID string `json:"userID"`
Nickname string `json:"nickname"`
FaceURL string `json:"faceURL"`
Gender int32 `json:"gender"`
Ex string `json:"ex"`
}
type FriendRequest struct {
FromUserID string `json:"fromUserID"`
FromNickname string `json:"fromNickname"`
FromFaceURL string `json:"fromFaceURL"`
FromGender int32 `json:"fromGender"`
ToUserID string `json:"toUserID"`
ToNickname string `json:"toNickname"`
ToFaceURL string `json:"toFaceURL"`
ToGender int32 `json:"toGender"`
HandleResult int32 `json:"handleResult"`
ReqMsg string `json:"reqMsg"`
CreateTime uint32 `json:"createTime"`
HandlerUserID string `json:"handlerUserID"`
HandleMsg string `json:"handleMsg"`
HandleTime uint32 `json:"handleTime"`
Ex string `json:"ex"`
}
type AddBlacklistReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type AddBlacklistResp struct {
}
type ImportFriendReq struct {
FriendUserIDList []string `json:"friendUserIDList" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type ImportFriendResp struct {
//
}
type AddFriendReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
ReqMsg string `json:"reqMsg"`
}
type AddFriendResp struct {
//
}
type AddFriendResponseReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
HandleResult int32 `json:"flag" binding:"required,oneof=-1 0 1"`
HandleMsg string `json:"handleMsg"`
}
type AddFriendResponseResp struct {
}
type DeleteFriendReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type DeleteFriendResp struct {
}
type GetBlackListReq struct {
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetBlackListResp struct {
BlackUserInfoList []PublicUserInfo `json:"blackUserInfoList"`
}
type SetFriendRemarkReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
Remark string `json:"remark"`
}
type SetFriendRemarkResp struct {
}
type RemoveBlacklistReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type RemoveBlacklistResp struct {
}
type IsFriendReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type Response struct {
Friend bool `json:"isFriend"`
}
type IsFriendResp struct {
Response Response `json:"data"`
}
type GetFriendListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetFriendListResp struct {
OwnerUserID string `json:"ownerUserID"`
Remark string `json:"remark"`
CreateTime uint32 `json:"createTime"`
AddSource int32 `json:"addSource"`
OperatorUserID string `json:"operatorUserID"`
Ex string `json:"ex"`
//FriendUser *UserInfo // TODO
}
type GetFriendApplyListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetFriendApplyListResp struct {
FriendRequestList []FriendRequest `json:"friendRequestList"`
}
type GetSelfApplyListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetSelfApplyListResp struct {
FriendRequestList []FriendRequest `json:"friendRequestList"`
}
-285
View File
@@ -1,285 +0,0 @@
// 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 apistruct
import (
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
)
type KickGroupMemberReq struct {
GroupID string `json:"groupID" binding:"required"`
KickedUserIDList []string `json:"kickedUserIDList" binding:"required"`
Reason string `json:"reason"`
OperationID string `json:"operationID" binding:"required"`
}
type KickGroupMemberResp struct {
//UserIDResultList []*UserIDResult `json:"data"`
}
type GetGroupMembersInfoReq struct {
GroupID string `json:"groupID" binding:"required"`
MemberList []string `json:"memberList" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetGroupMembersInfoResp struct {
MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
type InviteUserToGroupReq struct {
GroupID string `json:"groupID" binding:"required"`
InvitedUserIDList []string `json:"invitedUserIDList" binding:"required"`
Reason string `json:"reason"`
OperationID string `json:"operationID" binding:"required"`
}
type InviteUserToGroupResp struct {
//UserIDResultList []*UserIDResult `json:"data"`
}
type GetJoinedGroupListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetJoinedGroupListResp struct {
GroupInfoList []*sdkws.GroupInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
type GetGroupMemberListReq struct {
GroupID string `json:"groupID"`
Filter int32 `json:"filter"`
NextSeq int32 `json:"nextSeq"`
OperationID string `json:"operationID"`
}
type GetGroupMemberListResp struct {
NextSeq int32 `json:"nextSeq"`
MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
type GetGroupAllMemberReq struct {
GroupID string `json:"groupID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
Offset int32 `json:"offset"`
Count int32 `json:"count"`
}
type GetGroupAllMemberResp struct {
MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
//
//type GetGroupAllMemberListBySplitReq struct {
// GroupID string `json:"groupID" binding:"required"`
// OperationID string `json:"operationID" binding:"required"`
// Offset int32 `json:"offset" binding:"required"`
// Count int32 `json:"count" binding:"required"`
//}
//type GetGroupAllMemberListBySplitResp struct {
//
// MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
type CreateGroupReq struct {
MemberList []*GroupAddMemberInfo `json:"memberList"`
OwnerUserID string `json:"ownerUserID"`
GroupType int32 `json:"groupType"`
GroupName string `json:"groupName"`
Notification string `json:"notification"`
Introduction string `json:"introduction"`
FaceURL string `json:"faceURL"`
Ex string `json:"ex"`
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID"`
}
type CreateGroupResp struct {
GroupInfo sdkws.GroupInfo `json:"-"`
Data map[string]interface{} `json:"data" swaggerignore:"true"`
}
type GetGroupApplicationListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"` //作为管理员或群主收到的 进群申请
}
type GetGroupApplicationListResp struct {
GroupRequestList []*sdkws.GroupRequest `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
type GetUserReqGroupApplicationListReq struct {
OperationID string `json:"operationID" binding:"required"`
UserID string `json:"userID" binding:"required"`
}
type GetUserRespGroupApplicationResp struct {
GroupRequestList []*sdkws.GroupRequest `json:"data"`
}
type GetGroupInfoReq struct {
GroupIDList []string `json:"groupIDList" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetGroupInfoResp struct {
GroupInfoList []*sdkws.GroupInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
//type GroupInfoAlias struct {
// sdkws.GroupInfo
// NeedVerification int32 `protobuf:"bytes,13,opt,name=needVerification" json:"needVerification,omitempty"`
//}
//type GroupInfoAlias struct {
// GroupID string `protobuf:"bytes,1,opt,name=groupID" json:"groupID,omitempty"`
// GroupName string `protobuf:"bytes,2,opt,name=groupName" json:"groupName,omitempty"`
// Notification string `protobuf:"bytes,3,opt,name=notification" json:"notification,omitempty"`
// Introduction string `protobuf:"bytes,4,opt,name=introduction" json:"introduction,omitempty"`
// FaceURL string `protobuf:"bytes,5,opt,name=faceURL" json:"faceURL,omitempty"`
// OwnerUserID string `protobuf:"bytes,6,opt,name=ownerUserID" json:"ownerUserID,omitempty"`
// CreateTime uint32 `protobuf:"varint,7,opt,name=createTime" json:"createTime,omitempty"`
// MemberCount uint32 `protobuf:"varint,8,opt,name=memberCount" json:"memberCount,omitempty"`
// Ex string `protobuf:"bytes,9,opt,name=ex" json:"ex,omitempty"`
// Status int32 `protobuf:"varint,10,opt,name=status" json:"status,omitempty"`
// CreatorUserID string `protobuf:"bytes,11,opt,name=creatorUserID" json:"creatorUserID,omitempty"`
// GroupType int32 `protobuf:"varint,12,opt,name=groupType" json:"groupType,omitempty"`
// NeedVerification int32 `protobuf:"bytes,13,opt,name=needVerification" json:"needVerification,omitempty"`
//}
type ApplicationGroupResponseReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"` //application from FromUserID
HandledMsg string `json:"handledMsg"`
HandleResult int32 `json:"handleResult" binding:"required,oneof=-1 1"`
}
type ApplicationGroupResponseResp struct {
}
type JoinGroupReq struct {
GroupID string `json:"groupID" binding:"required"`
ReqMessage string `json:"reqMessage"`
OperationID string `json:"operationID" binding:"required"`
JoinSource int32 `json:"joinSource"`
InviterUserID string `json:"inviterUserID"`
}
type JoinGroupResp struct {
}
type QuitGroupReq struct {
GroupID string `json:"groupID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type QuitGroupResp struct {
}
type SetGroupInfoReq struct {
GroupID string `json:"groupID" binding:"required"`
GroupName string `json:"groupName"`
Notification string `json:"notification"`
Introduction string `json:"introduction"`
FaceURL string `json:"faceURL"`
Ex string `json:"ex"`
OperationID string `json:"operationID" binding:"required"`
NeedVerification *int32 `json:"needVerification"`
LookMemberInfo *int32 `json:"lookMemberInfo"`
ApplyMemberFriend *int32 `json:"applyMemberFriend"`
}
type SetGroupInfoResp struct {
}
type TransferGroupOwnerReq struct {
GroupID string `json:"groupID" binding:"required"`
OldOwnerUserID string `json:"oldOwnerUserID" binding:"required"`
NewOwnerUserID string `json:"newOwnerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type TransferGroupOwnerResp struct {
}
type DismissGroupReq struct {
GroupID string `json:"groupID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type DismissGroupResp struct {
}
type MuteGroupMemberReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
UserID string `json:"userID" binding:"required"`
MutedSeconds uint32 `json:"mutedSeconds" binding:"required"`
}
type MuteGroupMemberResp struct {
}
type CancelMuteGroupMemberReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
UserID string `json:"userID" binding:"required"`
}
type CancelMuteGroupMemberResp struct {
}
type MuteGroupReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
}
type MuteGroupResp struct {
}
type CancelMuteGroupReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
}
type CancelMuteGroupResp struct {
}
type SetGroupMemberNicknameReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
UserID string `json:"userID" binding:"required"`
Nickname string `json:"nickname"`
}
type SetGroupMemberNicknameResp struct {
}
type SetGroupMemberInfoReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
UserID string `json:"userID" binding:"required"`
Nickname *string `json:"nickname"`
FaceURL *string `json:"userGroupFaceUrl"`
RoleLevel *int32 `json:"roleLevel" validate:"gte=1,lte=3"`
Ex *string `json:"ex"`
}
type SetGroupMemberInfoResp struct {
}
type GetGroupAbstractInfoReq struct {
OperationID string `json:"operationID"`
GroupID string `json:"groupID"`
}
type GetGroupAbstractInfoResp struct {
GroupMemberNumber int32 `json:"groupMemberNumber"`
GroupMemberListHash uint64 `json:"groupMemberListHash"`
}
+11 -62
View File
@@ -18,35 +18,7 @@ import (
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
) )
type DeleteUsersReq struct { type SendMsg struct {
OperationID string `json:"operationID" binding:"required"`
DeleteUserIDList []string `json:"deleteUserIDList" binding:"required"`
}
type DeleteUsersResp struct {
FailedUserIDList []string `json:"data"`
}
type GetAllUsersUidReq struct {
OperationID string `json:"operationID" binding:"required"`
}
type GetAllUsersUidResp struct {
UserIDList []string `json:"data"`
}
type GetUsersOnlineStatusReq struct {
OperationID string `json:"operationID" binding:"required"`
UserIDList []string `json:"userIDList" binding:"required,lte=200"`
}
type GetUsersOnlineStatusResp struct {
//SuccessResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult `json:"data"`
}
type AccountCheckReq struct {
OperationID string `json:"operationID" binding:"required"`
CheckUserIDList []string `json:"checkUserIDList" binding:"required,lte=100"`
}
type AccountCheckResp struct {
}
type ManagementSendMsg struct {
SendID string `json:"sendID" binding:"required"` SendID string `json:"sendID" binding:"required"`
GroupID string `json:"groupID" binding:"required_if=SessionType 2|required_if=SessionType 3"` GroupID string `json:"groupID" binding:"required_if=SessionType 2|required_if=SessionType 3"`
SenderNickname string `json:"senderNickname"` SenderNickname string `json:"senderNickname"`
@@ -60,48 +32,25 @@ type ManagementSendMsg struct {
OfflinePushInfo *sdkws.OfflinePushInfo `json:"offlinePushInfo"` OfflinePushInfo *sdkws.OfflinePushInfo `json:"offlinePushInfo"`
} }
type ManagementSendMsgReq struct { type SendMsgReq struct {
SendID string `json:"sendID" binding:"required"` RecvID string `json:"recvID" binding:"required_if" message:"recvID is required if sessionType is SingleChatType or NotificationChatType"`
RecvID string `json:"recvID" binding:"required_if" message:"recvID is required if sessionType is SingleChatType or NotificationChatType"` SendMsg
GroupID string `json:"groupID" binding:"required_if" message:"groupID is required if sessionType is GroupChatType or SuperGroupChatType"`
SenderNickname string `json:"senderNickname"`
SenderFaceURL string `json:"senderFaceURL"`
SenderPlatformID int32 `json:"senderPlatformID"`
Content map[string]interface{} `json:"content" binding:"required" swaggerignore:"true"`
ContentType int32 `json:"contentType" binding:"required"`
SessionType int32 `json:"sessionType" binding:"required"`
IsOnlineOnly bool `json:"isOnlineOnly"`
NotOfflinePush bool `json:"notOfflinePush"`
OfflinePushInfo *sdkws.OfflinePushInfo `json:"offlinePushInfo"`
} }
type ManagementSendMsgResp struct { type BatchSendMsgReq struct {
ResultList sdkws.UserSendMsgResp `json:"data"` SendMsg
IsSendAll bool `json:"isSendAll"`
RecvIDs []string `json:"recvIDs"`
} }
type ManagementBatchSendMsgReq struct { type BatchSendMsgResp struct {
ManagementSendMsg Results []*SingleReturnResult `json:"results"`
IsSendAll bool `json:"isSendAll"` FailedIDs []string `json:"failedUserIDs"`
RecvIDList []string `json:"recvIDList"`
} }
type ManagementBatchSendMsgResp struct {
Data struct {
ResultList []*SingleReturnResult `json:"resultList"`
FailedIDList []string
} `json:"data"`
}
type SingleReturnResult struct { type SingleReturnResult struct {
ServerMsgID string `json:"serverMsgID"` ServerMsgID string `json:"serverMsgID"`
ClientMsgID string `json:"clientMsgID"` ClientMsgID string `json:"clientMsgID"`
SendTime int64 `json:"sendTime"` SendTime int64 `json:"sendTime"`
RecvID string `json:"recvID"` RecvID string `json:"recvID"`
} }
type CheckMsgIsSendSuccessReq struct {
OperationID string `json:"operationID"`
}
type CheckMsgIsSendSuccessResp struct {
Status int32 `json:"status"`
}
+36 -66
View File
@@ -1,62 +1,32 @@
// 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 apistruct package apistruct
type DelMsgReq struct {
UserID string `json:"userID,omitempty" binding:"required"`
SeqList []uint32 `json:"seqList,omitempty" binding:"required"`
OperationID string `json:"operationID,omitempty" binding:"required"`
}
type DelMsgResp struct {
}
type CleanUpMsgReq struct {
UserID string `json:"userID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type CleanUpMsgResp struct {
}
type DelSuperGroupMsgReq struct {
UserID string `json:"userID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
SeqList []uint32 `json:"seqList,omitempty"`
IsAllDelete bool `json:"isAllDelete"`
OperationID string `json:"operationID" binding:"required"`
}
type DelSuperGroupMsgResp struct {
}
type MsgDeleteNotificationElem struct {
GroupID string `json:"groupID"`
IsAllDelete bool `json:"isAllDelete"`
SeqList []uint32 `json:"seqList"`
}
type SetMsgMinSeqReq struct {
UserID string `json:"userID" binding:"required"`
GroupID string `json:"groupID"`
MinSeq uint32 `json:"minSeq" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type SetMsgMinSeqResp struct {
}
type PictureBaseInfo struct { type PictureBaseInfo struct {
UUID string `mapstructure:"uuid"` UUID string `mapstructure:"uuid"`
Type string `mapstructure:"type" ` Type string `mapstructure:"type"`
Size int64 `mapstructure:"size" ` Size int64 `mapstructure:"size"`
Width int32 `mapstructure:"width" ` Width int32 `mapstructure:"width"`
Height int32 `mapstructure:"height"` Height int32 `mapstructure:"height"`
Url string `mapstructure:"url" ` Url string `mapstructure:"url"`
} }
type PictureElem struct { type PictureElem struct {
SourcePath string `mapstructure:"sourcePath"` SourcePath string `mapstructure:"sourcePath"`
SourcePicture PictureBaseInfo `mapstructure:"sourcePicture"` SourcePicture PictureBaseInfo `mapstructure:"sourcePicture"`
BigPicture PictureBaseInfo `mapstructure:"bigPicture" ` BigPicture PictureBaseInfo `mapstructure:"bigPicture"`
SnapshotPicture PictureBaseInfo `mapstructure:"snapshotPicture"` SnapshotPicture PictureBaseInfo `mapstructure:"snapshotPicture"`
} }
type SoundElem struct { type SoundElem struct {
@@ -98,35 +68,35 @@ type LocationElem struct {
Latitude float64 `mapstructure:"latitude"` Latitude float64 `mapstructure:"latitude"`
} }
type CustomElem struct { type CustomElem struct {
Data string `mapstructure:"data" validate:"required"` Data string `mapstructure:"data" validate:"required"`
Description string `mapstructure:"description"` Description string `mapstructure:"description"`
Extension string `mapstructure:"extension"` Extension string `mapstructure:"extension"`
} }
type TextElem struct { type TextElem struct {
Content string `mapstructure:"content" validate:"required"` Text string `mapstructure:"text" validate:"required"`
} }
type RevokeElem struct { type RevokeElem struct {
RevokeMsgClientID string `mapstructure:"revokeMsgClientID" validate:"required"` RevokeMsgClientID string `mapstructure:"revokeMsgClientID" validate:"required"`
} }
type OANotificationElem struct { type OANotificationElem struct {
NotificationName string `mapstructure:"notificationName" json:"notificationName" validate:"required"` NotificationName string `mapstructure:"notificationName" json:"notificationName" validate:"required"`
NotificationFaceURL string `mapstructure:"notificationFaceURL" json:"notificationFaceURL"` NotificationFaceURL string `mapstructure:"notificationFaceURL" json:"notificationFaceURL"`
NotificationType int32 `mapstructure:"notificationType" json:"notificationType" validate:"required"` NotificationType int32 `mapstructure:"notificationType" json:"notificationType" validate:"required"`
Text string `mapstructure:"text" json:"text" validate:"required"` Text string `mapstructure:"text" json:"text" validate:"required"`
Url string `mapstructure:"url" json:"url"` Url string `mapstructure:"url" json:"url"`
MixType int32 `mapstructure:"mixType" json:"mixType"` MixType int32 `mapstructure:"mixType" json:"mixType"`
PictureElem PictureElem `mapstructure:"pictureElem" json:"pictureElem"` PictureElem PictureElem `mapstructure:"pictureElem" json:"pictureElem"`
SoundElem SoundElem `mapstructure:"soundElem" json:"soundElem"` SoundElem SoundElem `mapstructure:"soundElem" json:"soundElem"`
VideoElem VideoElem `mapstructure:"videoElem" json:"videoElem"` VideoElem VideoElem `mapstructure:"videoElem" json:"videoElem"`
FileElem FileElem `mapstructure:"fileElem" json:"fileElem"` FileElem FileElem `mapstructure:"fileElem" json:"fileElem"`
Ex string `mapstructure:"ex" json:"ex"` Ex string `mapstructure:"ex" json:"ex"`
} }
type MessageRevoked struct { type MessageRevoked struct {
RevokerID string `mapstructure:"revokerID" json:"revokerID" validate:"required"` RevokerID string `mapstructure:"revokerID" json:"revokerID" validate:"required"`
RevokerRole int32 `mapstructure:"revokerRole" json:"revokerRole" validate:"required"` RevokerRole int32 `mapstructure:"revokerRole" json:"revokerRole" validate:"required"`
ClientMsgID string `mapstructure:"clientMsgID" json:"clientMsgID" validate:"required"` ClientMsgID string `mapstructure:"clientMsgID" json:"clientMsgID" validate:"required"`
RevokerNickname string `mapstructure:"revokerNickname" json:"revokerNickname"` RevokerNickname string `mapstructure:"revokerNickname" json:"revokerNickname"`
SessionType int32 `mapstructure:"sessionType" json:"sessionType" validate:"required"` SessionType int32 `mapstructure:"sessionType" json:"sessionType" validate:"required"`
Seq uint32 `mapstructure:"seq" json:"seq" validate:"required"` Seq uint32 `mapstructure:"seq" json:"seq" validate:"required"`
} }
-35
View File
@@ -1,35 +0,0 @@
// 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 apistruct
type OSSCredentialReq struct {
OperationID string `json:"operationID"`
Filename string `json:"filename"`
FileType string `json:"file_type"`
}
type OSSCredentialRespData struct {
Endpoint string `json:"endpoint"`
AccessKeyId string `json:"access_key_id"`
AccessKeySecret string `json:"access_key_secret"`
Token string `json:"token"`
Bucket string `json:"bucket"`
FinalHost string `json:"final_host"`
}
type OSSCredentialResp struct {
OssData OSSCredentialRespData `json:"-"`
Data map[string]interface{} `json:"data"`
}
-20
View File
@@ -1,20 +0,0 @@
// 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 apistruct
type Pagination struct {
PageNumber int32 `json:"pageNumber" binding:"required"`
ShowNumber int32 `json:"showNumber" binding:"required"`
}
-12
View File
@@ -14,18 +14,6 @@
package apistruct package apistruct
type ApiUserInfo struct {
UserID string `json:"userID" binding:"required,min=1,max=64" swaggo:"true,用户ID,"`
Nickname string `json:"nickname" binding:"omitempty,min=1,max=64" swaggo:"true,my id,19"`
FaceURL string `json:"faceURL" binding:"omitempty,max=1024"`
Gender int32 `json:"gender" binding:"omitempty,oneof=0 1 2"`
PhoneNumber string `json:"phoneNumber" binding:"omitempty,max=32"`
Birth int64 `json:"birth" binding:"omitempty"`
Email string `json:"email" binding:"omitempty,max=64"`
CreateTime int64 `json:"createTime"`
Ex string `json:"ex" binding:"omitempty,max=1024"`
}
type GroupAddMemberInfo struct { type GroupAddMemberInfo struct {
UserID string `json:"userID" binding:"required"` UserID string `json:"userID" binding:"required"`
RoleLevel int32 `json:"roleLevel" binding:"required,oneof= 1 3"` RoleLevel int32 `json:"roleLevel" binding:"required,oneof= 1 3"`
-31
View File
@@ -1,31 +0,0 @@
// 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 apistruct
type GetJoinedSuperGroupListReq struct {
GetJoinedGroupListReq
}
type GetJoinedSuperGroupListResp struct {
GetJoinedGroupListResp
}
type GetSuperGroupsInfoReq struct {
GetGroupInfoReq
}
type GetSuperGroupsInfoResp struct {
GetGroupInfoResp
}
-131
View File
@@ -1,131 +0,0 @@
// 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 apistruct
import "mime/multipart"
type MinioStorageCredentialReq struct {
OperationID string `json:"operationID"`
}
type MiniostorageCredentialResp struct {
SecretAccessKey string `json:"secretAccessKey"`
AccessKeyID string `json:"accessKeyID"`
SessionToken string `json:"sessionToken"`
BucketName string `json:"bucketName"`
StsEndpointURL string `json:"stsEndpointURL"`
StorageTime int `json:"storageTime"`
IsDistributedMod bool `json:"isDistributedMod"`
}
type MinioUploadFileReq struct {
OperationID string `form:"operationID" binding:"required"`
FileType int `form:"fileType" binding:"required"`
}
type MinioUploadFile struct {
URL string `json:"URL"`
NewName string `json:"newName"`
SnapshotURL string `json:"snapshotURL,omitempty"`
SnapshotNewName string `json:"snapshotName,omitempty"`
}
type MinioUploadFileResp struct {
Data struct {
MinioUploadFile
} `json:"data"`
}
type UploadUpdateAppReq struct {
OperationID string `form:"operationID" binding:"required"`
Type int `form:"type" binding:"required"`
Version string `form:"version" binding:"required"`
File *multipart.FileHeader `form:"file" binding:"required"`
Yaml *multipart.FileHeader `form:"yaml"`
ForceUpdate bool `form:"forceUpdate"`
UpdateLog string `form:"updateLog" binding:"required"`
}
type UploadUpdateAppResp struct {
}
type GetDownloadURLReq struct {
OperationID string `json:"operationID" binding:"required"`
Type int `json:"type" binding:"required"`
Version string `json:"version" binding:"required"`
}
type GetDownloadURLResp struct {
Data struct {
HasNewVersion bool `json:"hasNewVersion"`
ForceUpdate bool `json:"forceUpdate"`
FileURL string `json:"fileURL"`
YamlURL string `json:"yamlURL"`
Version string `json:"version"`
UpdateLog string `json:"update_log"`
} `json:"data"`
}
type GetRTCInvitationInfoReq struct {
OperationID string `json:"operationID" binding:"required"`
ClientMsgID string `json:"clientMsgID" binding:"required"`
}
type GetRTCInvitationInfoResp struct {
Data struct {
OpUserID string `json:"opUserID"`
Invitation struct {
InviterUserID string `json:"inviterUserID"`
InviteeUserIDList []string `json:"inviteeUserIDList"`
GroupID string `json:"groupID"`
RoomID string `json:"roomID"`
Timeout int32 `json:"timeout"`
MediaType string `json:"mediaType"`
SessionType int32 `json:"sessionType"`
InitiateTime int32 `json:"initiateTime"`
PlatformID int32 `json:"platformID"`
CustomData string `json:"customData"`
} `json:"invitation"`
OfflinePushInfo struct{} `json:"offlinePushInfo"`
} `json:"data"`
}
type GetRTCInvitationInfoStartAppReq struct {
OperationID string `json:"operationID" binding:"required"`
}
type GetRTCInvitationInfoStartAppResp struct {
GetRTCInvitationInfoResp
}
/**
* FCM第三方上报Token
*/
type FcmUpdateTokenReq struct {
OperationID string `json:"operationID" binding:"required"`
Platform int `json:"platform" binding:"required,min=1,max=2"` //only for ios + android
FcmToken string `json:"fcmToken" binding:"required"`
}
type FcmUpdateTokenResp struct {
}
type SetAppBadgeReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
AppUnreadCount int32 `json:"appUnreadCount"`
}
type SetAppBadgeResp struct {
}
+1 -1
View File
@@ -16,7 +16,7 @@ package callbackstruct
type CallbackUserOnlineReq struct { type CallbackUserOnlineReq struct {
UserStatusCallbackReq UserStatusCallbackReq
//Token string `json:"token"` // Token string `json:"token"`
Seq int64 `json:"seq"` Seq int64 `json:"seq"`
IsAppBackground bool `json:"isAppBackground"` IsAppBackground bool `json:"isAppBackground"`
ConnID string `json:"connID"` ConnID string `json:"connID"`
+1 -1
View File
@@ -16,7 +16,7 @@ package cmd
import ( import (
"github.com/OpenIMSDK/Open-IM-Server/internal/msggateway" "github.com/OpenIMSDK/Open-IM-Server/internal/msggateway"
//"github.com/OpenIMSDK/Open-IM-Server/internal/msggateway" //"github.com/OpenIMSDK/Open-IM-Server/internal/msggateway".
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
+21 -3
View File
@@ -1,12 +1,27 @@
// 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 cmd package cmd
import ( import (
"errors" "errors"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/startrpc"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"google.golang.org/grpc" "google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/startrpc"
) )
type RpcCmd struct { type RpcCmd struct {
@@ -26,7 +41,10 @@ func (a *RpcCmd) Exec() error {
return a.Execute() return a.Execute()
} }
func (a *RpcCmd) StartSvr(name string, rpcFn func(discov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) error { func (a *RpcCmd) StartSvr(
name string,
rpcFn func(discov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error,
) error {
if a.GetPortFlag() == 0 { if a.GetPortFlag() == 0 {
return errors.New("port is required") return errors.New("port is required")
} }
+1 -1
View File
@@ -31,7 +31,7 @@ type CallBackConfig struct {
type NotificationConf struct { type NotificationConf struct {
IsSendMsg bool `yaml:"isSendMsg"` IsSendMsg bool `yaml:"isSendMsg"`
ReliabilityLevel int `yaml:"reliabilityLevel"` // 1 online 2 presistent ReliabilityLevel int `yaml:"reliabilityLevel"` // 1 online 2 persistent
UnreadCount bool `yaml:"unreadCount"` UnreadCount bool `yaml:"unreadCount"`
OfflinePush POfflinePush `yaml:"offlinePush"` OfflinePush POfflinePush `yaml:"offlinePush"`
} }
+1 -1
View File
@@ -30,7 +30,7 @@ import (
var ( var (
_, b, _, _ = runtime.Caller(0) _, b, _, _ = runtime.Caller(0)
// Root folder of this project // Root folder of this project.
Root = filepath.Join(filepath.Dir(b), "../../..") Root = filepath.Join(filepath.Dir(b), "../../..")
) )
+67 -61
View File
@@ -17,20 +17,21 @@ package constant
const ( const (
///ContentType ///ContentType
//UserRelated //UserRelated.
Text = 101 ContentTypeBegin = 100
Picture = 102 Text = 101
Voice = 103 Picture = 102
Video = 104 Voice = 103
File = 105 Video = 104
AtText = 106 File = 105
Merger = 107 AtText = 106
Card = 108 Merger = 107
Location = 109 Card = 108
Custom = 110 Location = 109
Revoke = 111 Custom = 110
Typing = 113 Revoke = 111
Quote = 114 Typing = 113
Quote = 114
AdvancedText = 117 AdvancedText = 117
@@ -44,23 +45,23 @@ const (
SignalMsg = 202 SignalMsg = 202
CustomNotification = 203 CustomNotification = 203
//SysRelated // SysRelated.
NotificationBegin = 1000 NotificationBegin = 1000
FriendApplicationApprovedNotification = 1201 //add_friend_response FriendApplicationApprovedNotification = 1201 // add_friend_response
FriendApplicationRejectedNotification = 1202 //add_friend_response FriendApplicationRejectedNotification = 1202 // add_friend_response
FriendApplicationNotification = 1203 //add_friend FriendApplicationNotification = 1203 // add_friend
FriendAddedNotification = 1204 FriendAddedNotification = 1204
FriendDeletedNotification = 1205 //delete_friend FriendDeletedNotification = 1205 // delete_friend
FriendRemarkSetNotification = 1206 //set_friend_remark? FriendRemarkSetNotification = 1206 // set_friend_remark?
BlackAddedNotification = 1207 //add_black BlackAddedNotification = 1207 // add_black
BlackDeletedNotification = 1208 //remove_black BlackDeletedNotification = 1208 // remove_black
FriendInfoUpdatedNotification = 1209 FriendInfoUpdatedNotification = 1209
ConversationChangeNotification = 1300 // change conversation opt ConversationChangeNotification = 1300 // change conversation opt
UserNotificationBegin = 1301 UserNotificationBegin = 1301
UserInfoUpdatedNotification = 1303 //SetSelfInfoTip = 204 UserInfoUpdatedNotification = 1303 // SetSelfInfoTip = 204
UserNotificationEnd = 1399 UserNotificationEnd = 1399
OANotification = 1400 OANotification = 1400
@@ -112,37 +113,37 @@ const (
NotificationEnd = 5000 NotificationEnd = 5000
//status // status.
MsgNormal = 1 MsgNormal = 1
MsgDeleted = 4 MsgDeleted = 4
//MsgFrom // MsgFrom.
UserMsgType = 100 UserMsgType = 100
SysMsgType = 200 SysMsgType = 200
//SessionType // SessionType.
SingleChatType = 1 SingleChatType = 1
GroupChatType = 2 GroupChatType = 2
SuperGroupChatType = 3 SuperGroupChatType = 3
NotificationChatType = 4 NotificationChatType = 4
//token // token.
NormalToken = 0 NormalToken = 0
InValidToken = 1 InValidToken = 1
KickedToken = 2 KickedToken = 2
ExpiredToken = 3 ExpiredToken = 3
//MultiTerminalLogin // MultiTerminalLogin.
DefalutNotKick = 0 DefalutNotKick = 0
//Full-end login, but the same end is mutually exclusive // Full-end login, but the same end is mutually exclusive.
AllLoginButSameTermKick = 1 AllLoginButSameTermKick = 1
//Only one of the endpoints can log in // Only one of the endpoints can log in.
SingleTerminalLogin = 2 SingleTerminalLogin = 2
//The web side can be online at the same time, and the other side can only log in at one end // The web side can be online at the same time, and the other side can only log in at one end.
WebAndOther = 3 WebAndOther = 3
// The PC side is mutually exclusive, and the mobile side is mutually exclusive, but the web side can be online at // The PC side is mutually exclusive, and the mobile side is mutually exclusive, but the web side can be online at
// the same time // the same time.
PcMobileAndWeb = 4 PcMobileAndWeb = 4
//The PC terminal can be online at the same time,but other terminal only one of the endpoints can login // The PC terminal can be online at the same time,but other terminal only one of the endpoints can login.
PCAndOther = 5 PCAndOther = 5
OnlineStatus = "online" OnlineStatus = "online"
@@ -150,12 +151,12 @@ const (
Registered = "registered" Registered = "registered"
UnRegistered = "unregistered" UnRegistered = "unregistered"
//MsgReceiveOpt // MsgReceiveOpt.
ReceiveMessage = 0 ReceiveMessage = 0
NotReceiveMessage = 1 NotReceiveMessage = 1
ReceiveNotNotifyMessage = 2 ReceiveNotNotifyMessage = 2
//OptionsKey // OptionsKey.
IsHistory = "history" IsHistory = "history"
IsPersistent = "persistent" IsPersistent = "persistent"
IsOfflinePush = "offlinePush" IsOfflinePush = "offlinePush"
@@ -169,13 +170,13 @@ const (
IsNotNotification = "isNotNotification" IsNotNotification = "isNotNotification"
IsSendMsg = "isSendMsg" IsSendMsg = "isSendMsg"
//GroupStatus // GroupStatus.
GroupOk = 0 GroupOk = 0
GroupBanChat = 1 GroupBanChat = 1
GroupStatusDismissed = 2 GroupStatusDismissed = 2
GroupStatusMuted = 3 GroupStatusMuted = 3
//GroupType // GroupType.
NormalGroup = 0 NormalGroup = 0
SuperGroup = 1 SuperGroup = 1
WorkingGroup = 2 WorkingGroup = 2
@@ -183,19 +184,19 @@ const (
GroupBaned = 3 GroupBaned = 3
GroupBanPrivateChat = 4 GroupBanPrivateChat = 4
//UserJoinGroupSource // UserJoinGroupSource.
JoinByAdmin = 1 JoinByAdmin = 1
JoinByInvitation = 2 JoinByInvitation = 2
JoinBySearch = 3 JoinBySearch = 3
JoinByQRCode = 4 JoinByQRCode = 4
//Minio // Minio.
MinioDurationTimes = 3600 MinioDurationTimes = 3600
//Aws // Aws.
AwsDurationTimes = 3600 AwsDurationTimes = 3600
//callbackCommand // callbackCommand.
CallbackBeforeSendSingleMsgCommand = "callbackBeforeSendSingleMsgCommand" CallbackBeforeSendSingleMsgCommand = "callbackBeforeSendSingleMsgCommand"
CallbackAfterSendSingleMsgCommand = "callbackAfterSendSingleMsgCommand" CallbackAfterSendSingleMsgCommand = "callbackAfterSendSingleMsgCommand"
CallbackBeforeSendGroupMsgCommand = "callbackBeforeSendGroupMsgCommand" CallbackBeforeSendGroupMsgCommand = "callbackBeforeSendGroupMsgCommand"
@@ -216,19 +217,19 @@ const (
CallbackGetMessageListReactionExtensionsCommand = "callbackGetMessageListReactionExtensionsCommand" CallbackGetMessageListReactionExtensionsCommand = "callbackGetMessageListReactionExtensionsCommand"
CallbackAddMessageListReactionExtensionsCommand = "callbackAddMessageListReactionExtensionsCommand" CallbackAddMessageListReactionExtensionsCommand = "callbackAddMessageListReactionExtensionsCommand"
//callback actionCode // callback actionCode.
ActionAllow = 0 ActionAllow = 0
ActionForbidden = 1 ActionForbidden = 1
//callback callbackHandleCode // callback callbackHandleCode.
CallbackHandleSuccess = 0 CallbackHandleSuccess = 0
CallbackHandleFailed = 1 CallbackHandleFailed = 1
// minioUpload // minioUpload.
OtherType = 1 OtherType = 1
VideoType = 2 VideoType = 2
ImageType = 3 ImageType = 3
// sendMsgStaus // sendMsgStaus.
MsgStatusNotExist = 0 MsgStatusNotExist = 0
MsgIsSending = 1 MsgIsSending = 1
MsgSendSuccessed = 2 MsgSendSuccessed = 2
@@ -290,32 +291,35 @@ const (
GroupResponseAgree = 1 GroupResponseAgree = 1
GroupResponseRefuse = -1 GroupResponseRefuse = -1
FriendResponseAgree = 1 FriendResponseNotHandle = 0
FriendResponseRefuse = -1 FriendResponseAgree = 1
FriendResponseRefuse = -1
Male = 1 Male = 1
Female = 2 Female = 2
) )
const OperationID = "operationID" const (
const OpUserID = "opUserID" OperationID = "operationID"
const ConnID = "connID" OpUserID = "opUserID"
const OpUserPlatform = "platform" ConnID = "connID"
const Token = "token" OpUserPlatform = "platform"
const RpcCustomHeader = "customHeader" // rpc中间件自定义ctx参数 Token = "token"
const CheckKey = "CheckKey" RpcCustomHeader = "customHeader" // rpc中间件自定义ctx参数
const TriggerID = "triggerID" CheckKey = "CheckKey"
const RemoteAddr = "remoteAddr" TriggerID = "triggerID"
RemoteAddr = "remoteAddr"
)
const ( const (
BecomeFriendByImport = 1 //管理员导入 BecomeFriendByImport = 1 // 管理员导入
BecomeFriendByApply = 2 //申请添加 BecomeFriendByApply = 2 // 申请添加
) )
const ( const (
ApplyNeedVerificationInviteDirectly = 0 // 申请需要同意 邀请直接进 ApplyNeedVerificationInviteDirectly = 0 // 申请需要同意 邀请直接进
AllNeedVerification = 1 //所有人进群需要验证,除了群主管理员邀请进群 AllNeedVerification = 1 // 所有人进群需要验证,除了群主管理员邀请进群
Directly = 2 //直接进群 Directly = 2 // 直接进群
) )
const ( const (
@@ -343,7 +347,7 @@ const LogFileName = "OpenIM.log"
const LocalHost = "0.0.0.0" const LocalHost = "0.0.0.0"
// flag parse // flag parse.
const ( const (
FlagPort = "port" FlagPort = "port"
FlagWsPort = "ws_port" FlagWsPort = "ws_port"
@@ -355,3 +359,5 @@ const (
const OpenIMCommonConfigKey = "OpenIMServerConfig" const OpenIMCommonConfigKey = "OpenIMServerConfig"
const CallbackCommand = "command" const CallbackCommand = "command"
const BatchNum = 100
+10 -5
View File
@@ -15,10 +15,9 @@
package constant package constant
// fixme 1<--->IOS 2<--->Android 3<--->Windows // fixme 1<--->IOS 2<--->Android 3<--->Windows
//fixme 4<--->OSX 5<--->Web 6<--->MiniWeb 7<--->Linux // fixme 4<--->OSX 5<--->Web 6<--->MiniWeb 7<--->Linux.
const ( const (
//Platform ID // Platform ID.
IOSPlatformID = 1 IOSPlatformID = 1
AndroidPlatformID = 2 AndroidPlatformID = 2
WindowsPlatformID = 3 WindowsPlatformID = 3
@@ -30,7 +29,7 @@ const (
IPadPlatformID = 9 IPadPlatformID = 9
AdminPlatformID = 10 AdminPlatformID = 10
//Platform string match to Platform ID // Platform string match to Platform ID.
IOSPlatformStr = "IOS" IOSPlatformStr = "IOS"
AndroidPlatformStr = "Android" AndroidPlatformStr = "Android"
WindowsPlatformStr = "Windows" WindowsPlatformStr = "Windows"
@@ -42,7 +41,7 @@ const (
IPadPlatformStr = "IPad" IPadPlatformStr = "IPad"
AdminPlatformStr = "Admin" AdminPlatformStr = "Admin"
//terminal types // terminal types.
TerminalPC = "PC" TerminalPC = "PC"
TerminalMobile = "Mobile" TerminalMobile = "Mobile"
) )
@@ -59,6 +58,7 @@ var PlatformID2Name = map[int]string{
IPadPlatformID: IPadPlatformStr, IPadPlatformID: IPadPlatformStr,
AdminPlatformID: AdminPlatformStr, AdminPlatformID: AdminPlatformStr,
} }
var PlatformName2ID = map[string]int{ var PlatformName2ID = map[string]int{
IOSPlatformStr: IOSPlatformID, IOSPlatformStr: IOSPlatformID,
AndroidPlatformStr: AndroidPlatformID, AndroidPlatformStr: AndroidPlatformID,
@@ -71,6 +71,7 @@ var PlatformName2ID = map[string]int{
IPadPlatformStr: IPadPlatformID, IPadPlatformStr: IPadPlatformID,
AdminPlatformStr: AdminPlatformID, AdminPlatformStr: AdminPlatformID,
} }
var PlatformName2class = map[string]string{ var PlatformName2class = map[string]string{
IOSPlatformStr: TerminalMobile, IOSPlatformStr: TerminalMobile,
AndroidPlatformStr: TerminalMobile, AndroidPlatformStr: TerminalMobile,
@@ -80,6 +81,7 @@ var PlatformName2class = map[string]string{
OSXPlatformStr: TerminalPC, OSXPlatformStr: TerminalPC,
LinuxPlatformStr: TerminalPC, LinuxPlatformStr: TerminalPC,
} }
var PlatformID2class = map[int]string{ var PlatformID2class = map[int]string{
IOSPlatformID: TerminalMobile, IOSPlatformID: TerminalMobile,
AndroidPlatformID: TerminalMobile, AndroidPlatformID: TerminalMobile,
@@ -93,12 +95,15 @@ var PlatformID2class = map[int]string{
func PlatformIDToName(num int) string { func PlatformIDToName(num int) string {
return PlatformID2Name[num] return PlatformID2Name[num]
} }
func PlatformNameToID(name string) int { func PlatformNameToID(name string) int {
return PlatformName2ID[name] return PlatformName2ID[name]
} }
func PlatformNameToClass(name string) string { func PlatformNameToClass(name string) string {
return PlatformName2class[name] return PlatformName2class[name]
} }
func PlatformIDToClass(num int) string { func PlatformIDToClass(num int) string {
return PlatformID2class[num] return PlatformID2class[num]
} }
+3
View File
@@ -27,6 +27,9 @@ func BlackDB2Pb(
blackDBs []*relation.BlackModel, blackDBs []*relation.BlackModel,
f func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error), f func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error),
) (blackPbs []*sdk.BlackInfo, err error) { ) (blackPbs []*sdk.BlackInfo, err error) {
if len(blackDBs) == 0 {
return nil, nil
}
var userIDs []string var userIDs []string
for _, blackDB := range blackDBs { for _, blackDB := range blackDBs {
userIDs = append(userIDs, blackDB.BlockUserID) userIDs = append(userIDs, blackDB.BlockUserID)
+6
View File
@@ -54,6 +54,9 @@ func FriendsDB2Pb(
friendsDB []*relation.FriendModel, friendsDB []*relation.FriendModel,
getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error), getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error),
) (friendsPb []*sdkws.FriendInfo, err error) { ) (friendsPb []*sdkws.FriendInfo, err error) {
if len(friendsDB) == 0 {
return nil, nil
}
var userID []string var userID []string
for _, friendDB := range friendsDB { for _, friendDB := range friendsDB {
userID = append(userID, friendDB.FriendUserID) userID = append(userID, friendDB.FriendUserID)
@@ -80,6 +83,9 @@ func FriendRequestDB2Pb(
friendRequests []*relation.FriendRequestModel, friendRequests []*relation.FriendRequestModel,
getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error), getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error),
) ([]*sdkws.FriendRequest, error) { ) ([]*sdkws.FriendRequest, error) {
if len(friendRequests) == 0 {
return nil, nil
}
userIDMap := make(map[string]struct{}) userIDMap := make(map[string]struct{})
for _, friendRequest := range friendRequests { for _, friendRequest := range friendRequests {
userIDMap[friendRequest.ToUserID] = struct{}{} userIDMap[friendRequest.ToUserID] = struct{}{}
+1 -1
View File
@@ -76,7 +76,7 @@ func Db2PbGroupMember(m *relation.GroupMemberModel) *sdkws.GroupMemberFullInfo {
JoinTime: m.JoinTime.UnixMilli(), JoinTime: m.JoinTime.UnixMilli(),
Nickname: m.Nickname, Nickname: m.Nickname,
FaceURL: m.FaceURL, FaceURL: m.FaceURL,
//AppMangerLevel: m.AppMangerLevel, // AppMangerLevel: m.AppMangerLevel,
JoinSource: m.JoinSource, JoinSource: m.JoinSource,
OperatorUserID: m.OperatorUserID, OperatorUserID: m.OperatorUserID,
Ex: m.Ex, Ex: m.Ex,
-1
View File
@@ -54,7 +54,6 @@ func MsgPb2DB(msg *sdkws.MsgData) *unrelation.MsgDataModel {
msgDataModel.AttachedInfo = msg.AttachedInfo msgDataModel.AttachedInfo = msg.AttachedInfo
msgDataModel.Ex = msg.Ex msgDataModel.Ex = msg.Ex
return &msgDataModel return &msgDataModel
} }
func MsgDB2Pb(msgModel *unrelation.MsgDataModel) *sdkws.MsgData { func MsgDB2Pb(msgModel *unrelation.MsgDataModel) *sdkws.MsgData {
+3 -3
View File
@@ -29,13 +29,13 @@ const (
blackExpireTime = time.Second * 60 * 60 * 12 blackExpireTime = time.Second * 60 * 60 * 12
) )
// args fn will exec when no data in msgCache // args fn will exec when no data in msgCache.
type BlackCache interface { type BlackCache interface {
//get blackIDs from msgCache // get blackIDs from msgCache
metaCache metaCache
NewCache() BlackCache NewCache() BlackCache
GetBlackIDs(ctx context.Context, userID string) (blackIDs []string, err error) GetBlackIDs(ctx context.Context, userID string) (blackIDs []string, err error)
//del user's blackIDs msgCache, exec when a user's black list changed // del user's blackIDs msgCache, exec when a user's black list changed
DelBlackIDs(ctx context.Context, userID string) BlackCache DelBlackIDs(ctx context.Context, userID string) BlackCache
} }
+4 -4
View File
@@ -41,7 +41,7 @@ const (
conversationExpireTime = time.Second * 60 * 60 * 12 conversationExpireTime = time.Second * 60 * 60 * 12
) )
// arg fn will exec when no data in msgCache // arg fn will exec when no data in msgCache.
type ConversationCache interface { type ConversationCache interface {
metaCache metaCache
NewCache() ConversationCache NewCache() ConversationCache
@@ -54,7 +54,7 @@ type ConversationCache interface {
// get one conversation from msgCache // get one conversation from msgCache
GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationTb.ConversationModel, error) GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationTb.ConversationModel, error)
DelConvsersations(ownerUserID string, conversationIDs ...string) ConversationCache DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache
DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache
// get one conversation from msgCache // get one conversation from msgCache
GetConversations( GetConversations(
@@ -225,9 +225,9 @@ func (c *ConversationRedisCache) GetConversation(
) )
} }
func (c *ConversationRedisCache) DelConvsersations(ownerUserID string, convsersationIDs ...string) ConversationCache { func (c *ConversationRedisCache) DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache {
var keys []string var keys []string
for _, conversationID := range convsersationIDs { for _, conversationID := range conversationIDs {
keys = append(keys, c.getConversationKey(ownerUserID, conversationID)) keys = append(keys, c.getConversationKey(ownerUserID, conversationID))
} }
cache := c.NewCache() cache := c.NewCache()
+2 -2
View File
@@ -32,7 +32,7 @@ const (
friendKey = "FRIEND_INFO:" friendKey = "FRIEND_INFO:"
) )
// args fn will exec when no data in msgCache // args fn will exec when no data in msgCache.
type FriendCache interface { type FriendCache interface {
metaCache metaCache
NewCache() FriendCache NewCache() FriendCache
@@ -109,7 +109,7 @@ func (f *FriendCacheRedis) DelFriendIDs(ownerUserID ...string) FriendCache {
return new return new
} }
// todo // todo.
func (f *FriendCacheRedis) GetTwoWayFriendIDs( func (f *FriendCacheRedis) GetTwoWayFriendIDs(
ctx context.Context, ctx context.Context,
ownerUserID string, ownerUserID string,
+6 -5
View File
@@ -106,7 +106,8 @@ func NewGroupCacheRedis(
opts rockscache.Options, opts rockscache.Options,
) GroupCache { ) GroupCache {
rcClient := rockscache.NewClient(rdb, opts) rcClient := rockscache.NewClient(rdb, opts)
return &GroupCacheRedis{rcClient: rcClient, expireTime: groupExpireTime, return &GroupCacheRedis{
rcClient: rcClient, expireTime: groupExpireTime,
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB, groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
mongoDB: mongoClient, metaCache: NewMetaCacheRedis(rcClient), mongoDB: mongoClient, metaCache: NewMetaCacheRedis(rcClient),
} }
@@ -176,7 +177,7 @@ func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationTb.GroupMembe
return 0, errIndex return 0, errIndex
} }
// / groupInfo // / groupInfo.
func (g *GroupCacheRedis) GetGroupsInfo( func (g *GroupCacheRedis) GetGroupsInfo(
ctx context.Context, ctx context.Context,
groupIDs []string, groupIDs []string,
@@ -265,7 +266,7 @@ func (g *GroupCacheRedis) GetSuperGroupMemberIDs(
) )
} }
// userJoinSuperGroup // userJoinSuperGroup.
func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(userIDs ...string) GroupCache { func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(userIDs ...string) GroupCache {
new := g.NewCache() new := g.NewCache()
var keys []string var keys []string
@@ -286,7 +287,7 @@ func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache
return new return new
} }
// 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, ctx,
@@ -331,7 +332,7 @@ func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) GroupCache {
return cache return cache
} }
// groupMemberIDs // groupMemberIDs.
func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) { func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) {
return getCache( return getCache(
ctx, ctx,
+20 -11
View File
@@ -27,6 +27,11 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
) )
const (
maxRetry = 10 // number of retries
)
// NewRedis Initialize redis connection.
func NewRedis() (redis.UniversalClient, error) { func NewRedis() (redis.UniversalClient, error) {
if len(config.Config.Redis.Address) == 0 { if len(config.Config.Redis.Address) == 0 {
return nil, errors.New("redis address is empty") return nil, errors.New("redis address is empty")
@@ -35,25 +40,29 @@ func NewRedis() (redis.UniversalClient, error) {
var rdb redis.UniversalClient var rdb redis.UniversalClient
if len(config.Config.Redis.Address) > 1 { if len(config.Config.Redis.Address) > 1 {
rdb = redis.NewClusterClient(&redis.ClusterOptions{ rdb = redis.NewClusterClient(&redis.ClusterOptions{
Addrs: config.Config.Redis.Address, Addrs: config.Config.Redis.Address,
Username: config.Config.Redis.Username, Username: config.Config.Redis.Username,
Password: config.Config.Redis.Password, // no password set Password: config.Config.Redis.Password, // no password set
PoolSize: 50, PoolSize: 50,
MaxRetries: maxRetry,
}) })
} else { } else {
rdb = redis.NewClient(&redis.Options{ rdb = redis.NewClient(&redis.Options{
Addr: config.Config.Redis.Address[0], Addr: config.Config.Redis.Address[0],
Username: config.Config.Redis.Username, Username: config.Config.Redis.Username,
Password: config.Config.Redis.Password, // no password set Password: config.Config.Redis.Password, // no password set
DB: 0, // use default DB DB: 0, // use default DB
PoolSize: 100, // 连接池大小 PoolSize: 100, // connection pool size
MaxRetries: maxRetry,
}) })
} }
var err error = nil
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel() defer cancel()
err := rdb.Ping(ctx).Err() err = rdb.Ping(ctx).Err()
if err != nil { if err != nil {
return nil, fmt.Errorf("redis ping %w", err) return nil, fmt.Errorf("redis ping %w", err)
} }
return rdb, nil return rdb, err
} }
@@ -12,30 +12,26 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package mw package cache
import ( import (
"fmt" "fmt"
"testing" "testing"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
) )
func TestCheck(t *testing.T) { // TestNewRedis Test redis connection
// config.Config.TokenPolicy.Secret = "123456" func TestNewRedis(t *testing.T) {
err := config.InitConfig("config_folder_path")
args := []string{"1", "2", "3"} if err != nil {
fmt.Println("config load error")
key := genReqKey(args) return
fmt.Println("key:", key) }
err := verifyReqKey(args, key) redis, err := NewRedis()
if err != nil {
fmt.Println(err) fmt.Println(err)
return
args = []string{"4", "5", "6"} }
fmt.Println(redis)
key = genReqKey(args)
fmt.Println("key:", key)
err = verifyReqKey(args, key)
fmt.Println(err)
} }

Some files were not shown because too many files have changed in this diff Show More