mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-09-02 13:09:49 +08:00
Merge branch 'openimsdk:main' into main
This commit is contained in:
commit
39a6141787
2
.github/workflows/e2e-test.yml
vendored
2
.github/workflows/e2e-test.yml
vendored
@ -92,6 +92,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Exec OpenIM API test
|
- name: Exec OpenIM API test
|
||||||
run: |
|
run: |
|
||||||
|
sudo make test-api
|
||||||
mkdir -p ./tmp
|
mkdir -p ./tmp
|
||||||
touch ./tmp/test.md
|
touch ./tmp/test.md
|
||||||
echo "# OpenIM Test" >> ./tmp/test.md
|
echo "# OpenIM Test" >> ./tmp/test.md
|
||||||
@ -104,6 +105,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Exec OpenIM E2E Test
|
- name: Exec OpenIM E2E Test
|
||||||
run: |
|
run: |
|
||||||
|
sudo make test-e2e
|
||||||
echo "" >> ./tmp/test.md
|
echo "" >> ./tmp/test.md
|
||||||
echo "## OpenIM E2E Test" >> ./tmp/test.md
|
echo "## OpenIM E2E Test" >> ./tmp/test.md
|
||||||
echo "<details><summary>Command Output for OpenIM E2E Test</summary>" >> ./tmp/test.md
|
echo "<details><summary>Command Output for OpenIM E2E Test</summary>" >> ./tmp/test.md
|
||||||
|
11
.github/workflows/pull-request.yml
vendored
11
.github/workflows/pull-request.yml
vendored
@ -74,6 +74,17 @@ jobs:
|
|||||||
echo $latest_tag > pkg/common/config/version
|
echo $latest_tag > pkg/common/config/version
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Gen CHANGELOG file
|
||||||
|
run: |
|
||||||
|
current_tag=$(git describe --tags --abbrev=0)
|
||||||
|
version=$(echo "$current_tag" | sed -E 's/^v?([0-9]+)\.([0-9]+)\..*$/\1.\2/')
|
||||||
|
echo "OpenIM Version: $version"
|
||||||
|
make tools.install.git-chglog
|
||||||
|
cd CHANGELOG
|
||||||
|
git-chglog --tag-filter-pattern "v${version}.*" -o CHANGELOG-${version}.md
|
||||||
|
cd ..
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Run unit test and get test coverage
|
- name: Run unit test and get test coverage
|
||||||
run: |
|
run: |
|
||||||
make cover
|
make cover
|
||||||
|
@ -40,10 +40,14 @@ run:
|
|||||||
# "/" will be replaced by current OS file path separator to properly work
|
# "/" will be replaced by current OS file path separator to properly work
|
||||||
# on Windows.
|
# on Windows.
|
||||||
skip-dirs:
|
skip-dirs:
|
||||||
|
- components
|
||||||
|
- docs
|
||||||
- util
|
- util
|
||||||
- .*~
|
- .*~
|
||||||
- api/swagger/docs
|
- api/swagger/docs
|
||||||
- server/docs
|
- server/docs
|
||||||
|
- components/mnt/config/certs
|
||||||
|
- logs
|
||||||
|
|
||||||
# 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$
|
||||||
@ -58,6 +62,12 @@ run:
|
|||||||
skip-files:
|
skip-files:
|
||||||
- ".*\\.my\\.go$"
|
- ".*\\.my\\.go$"
|
||||||
- _test.go
|
- _test.go
|
||||||
|
- ".*_test.go"
|
||||||
|
- "mocks/"
|
||||||
|
- ".github/"
|
||||||
|
- "logs/"
|
||||||
|
- "_output/"
|
||||||
|
- "components/"
|
||||||
|
|
||||||
# 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
|
||||||
@ -108,7 +118,6 @@ linters-settings:
|
|||||||
right-to-left-isolate: true
|
right-to-left-isolate: true
|
||||||
first-strong-isolate: true
|
first-strong-isolate: true
|
||||||
pop-directional-isolate: true
|
pop-directional-isolate: true
|
||||||
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
|
||||||
dupl:
|
dupl:
|
||||||
@ -131,8 +140,8 @@ linters-settings:
|
|||||||
|
|
||||||
# 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:
|
errorlint:
|
||||||
# Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats
|
# Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats
|
||||||
errorf: true
|
errorf: true
|
||||||
@ -418,7 +427,7 @@ linters-settings:
|
|||||||
|
|
||||||
govet:
|
govet:
|
||||||
# report about shadowed variables
|
# report about shadowed variables
|
||||||
check-shadowing: true
|
check-shadowing: false
|
||||||
|
|
||||||
# settings per analyzer
|
# settings per analyzer
|
||||||
settings:
|
settings:
|
||||||
@ -489,9 +498,9 @@ linters-settings:
|
|||||||
- github.com\/user\/package\/v4\.Type
|
- 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 250.
|
||||||
# '\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: 240
|
line-length: 250
|
||||||
# tab width in spaces. Default to 1.
|
# tab width in spaces. Default to 1.
|
||||||
tab-width: 4
|
tab-width: 4
|
||||||
maligned:
|
maligned:
|
||||||
@ -715,17 +724,33 @@ linters:
|
|||||||
# enable-all: true
|
# enable-all: true
|
||||||
disable-all: true
|
disable-all: true
|
||||||
enable:
|
enable:
|
||||||
- typecheck # 基本的类型检查
|
- typecheck # Basic type checking
|
||||||
- gofmt # 格式检查
|
- gofmt # Format check
|
||||||
- govet # Go 语言的标准检查工具
|
- govet # Go's standard linting tool
|
||||||
- gosimple # 简化代码的建议
|
- gosimple # Suggestions for simplifying code
|
||||||
- misspell # 拼写错误
|
- errcheck
|
||||||
- staticcheck # 静态检查
|
- decorder
|
||||||
- unused # 未使用的代码检查
|
- ineffassign
|
||||||
- goimports # 检查导入是否正确排序和格式化
|
- revive
|
||||||
- godot # 注释句点检查
|
- reassign
|
||||||
- bodyclose # 确保 HTTP response body 被关闭
|
- tparallel
|
||||||
- errcheck # 检查是否遗漏了错误返回值
|
- unconvert
|
||||||
|
- dupl
|
||||||
|
- dupword
|
||||||
|
- errname
|
||||||
|
- gci
|
||||||
|
- goheader
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- misspell # Spelling mistakes
|
||||||
|
- staticcheck # Static analysis
|
||||||
|
- unused # Checks for unused code
|
||||||
|
- goimports # Checks if imports are correctly sorted and formatted
|
||||||
|
- godot # Checks for comment punctuation
|
||||||
|
- bodyclose # Ensures HTTP response body is closed
|
||||||
|
- stylecheck # Style checker for Go code
|
||||||
|
- unused # Checks for unused code
|
||||||
|
- errcheck # Checks for missed error returns
|
||||||
fast: true
|
fast: true
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
@ -792,6 +817,11 @@ issues:
|
|||||||
- lll
|
- lll
|
||||||
source: "^//go:generate "
|
source: "^//go:generate "
|
||||||
|
|
||||||
|
- text: ".*[\u4e00-\u9fa5]+.*"
|
||||||
|
linters:
|
||||||
|
- golint
|
||||||
|
source: "^//.*$"
|
||||||
|
|
||||||
# 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
|
||||||
# excluded by default patterns execute `golangci-lint run --help`.
|
# excluded by default patterns execute `golangci-lint run --help`.
|
||||||
@ -852,4 +882,4 @@ severity:
|
|||||||
rules:
|
rules:
|
||||||
- linters:
|
- linters:
|
||||||
- dupl
|
- dupl
|
||||||
severity: info
|
severity: info
|
||||||
|
@ -8,6 +8,12 @@
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
|
||||||
|
<a name="v3.5.1-alpha.2"></a>
|
||||||
|
## [v3.5.1-alpha.2] - 2024-01-26
|
||||||
|
|
||||||
|
<a name="v3.5.1-rc.1"></a>
|
||||||
|
## [v3.5.1-rc.1] - 2024-01-23
|
||||||
|
|
||||||
<a name="v3.5.1-alpha.1"></a>
|
<a name="v3.5.1-alpha.1"></a>
|
||||||
## [v3.5.1-alpha.1] - 2024-01-09
|
## [v3.5.1-alpha.1] - 2024-01-09
|
||||||
|
|
||||||
@ -59,7 +65,9 @@
|
|||||||
- Merge branch 'tuoyun'
|
- Merge branch 'tuoyun'
|
||||||
|
|
||||||
|
|
||||||
[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-alpha.1...HEAD
|
[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-alpha.2...HEAD
|
||||||
|
[v3.5.1-alpha.2]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-rc.1...v3.5.1-alpha.2
|
||||||
|
[v3.5.1-rc.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-alpha.1...v3.5.1-rc.1
|
||||||
[v3.5.1-alpha.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.0...v3.5.1-alpha.1
|
[v3.5.1-alpha.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.0...v3.5.1-alpha.1
|
||||||
[v3.5.0]: https://github.com/openimsdk/open-im-server/compare/v3.5.1...v3.5.0
|
[v3.5.0]: https://github.com/openimsdk/open-im-server/compare/v3.5.1...v3.5.0
|
||||||
[v3.5.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-bate.1...v3.5.1
|
[v3.5.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-bate.1...v3.5.1
|
||||||
|
2
Makefile
2
Makefile
@ -184,7 +184,7 @@ test-e2e:
|
|||||||
imports:
|
imports:
|
||||||
@$(MAKE) go.imports
|
@$(MAKE) go.imports
|
||||||
|
|
||||||
## clean: Remove all files that are created by building. ✨
|
## clean: Delete all files created by the build, as well as all log files. ✨
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@$(MAKE) go.clean
|
@$(MAKE) go.clean
|
||||||
|
21
README.md
21
README.md
@ -51,6 +51,15 @@
|
|||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
## :busts_in_silhouette: Community
|
||||||
|
|
||||||
|
+ 💬 [Follow our Twitter account](https://twitter.com/founder_im63606)
|
||||||
|
+ 👫 [Join our Reddit](https://www.reddit.com/r/OpenIMessaging)
|
||||||
|
+ 🚀 [Join our Slack community](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)
|
||||||
|
+ :eyes: [Join our wechat (微信群)](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
|
||||||
|
+ 📚 [OpenIM Community](https://github.com/OpenIMSDK/community)
|
||||||
|
+ 💕 [OpenIM Interest Group](https://github.com/Openim-sigs)
|
||||||
|
|
||||||
## Ⓜ️ About OpenIM
|
## Ⓜ️ About OpenIM
|
||||||
|
|
||||||
OpenIM is a service platform specifically designed for integrating chat, audio-video calls, notifications, and AI chatbots into applications. It provides a range of powerful APIs and Webhooks, enabling developers to easily incorporate these interactive features into their applications. OpenIM is not a standalone chat application, but rather serves as a platform to support other applications in achieving rich communication functionalities. The following diagram illustrates the interaction between AppServer, AppClient, OpenIMServer, and OpenIMSDK to explain in detail.
|
OpenIM is a service platform specifically designed for integrating chat, audio-video calls, notifications, and AI chatbots into applications. It provides a range of powerful APIs and Webhooks, enabling developers to easily incorporate these interactive features into their applications. OpenIM is not a standalone chat application, but rather serves as a platform to support other applications in achieving rich communication functionalities. The following diagram illustrates the interaction between AppServer, AppClient, OpenIMServer, and OpenIMSDK to explain in detail.
|
||||||
@ -118,6 +127,8 @@ We support many platforms. Here are the addresses for quick experience on the we
|
|||||||
|
|
||||||
[](https://vscode.dev/github/openimsdk/open-im-server)
|
[](https://vscode.dev/github/openimsdk/open-im-server)
|
||||||
|
|
||||||
|
[](https://codespaces.new/openimsdk/open-im-server)
|
||||||
|
|
||||||
OpenIM Our goal is to build a top-level open source community. We have a set of standards, in the [Community repository](https://github.com/OpenIMSDK/community).
|
OpenIM Our goal is to build a top-level open source community. We have a set of standards, in the [Community repository](https://github.com/OpenIMSDK/community).
|
||||||
|
|
||||||
If you'd like to contribute to this Open-IM-Server repository, please read our [contributor documentation](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md).
|
If you'd like to contribute to this Open-IM-Server repository, please read our [contributor documentation](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md).
|
||||||
@ -154,16 +165,6 @@ Before you start, please make sure your changes are in demand. The best for that
|
|||||||
- [Manage backend and monitor deployment](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/prometheus-grafana.md)
|
- [Manage backend and monitor deployment](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/prometheus-grafana.md)
|
||||||
- [Mac Developer Deployment Guide for OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/mac-developer-deployment-guide.md)
|
- [Mac Developer Deployment Guide for OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/mac-developer-deployment-guide.md)
|
||||||
|
|
||||||
|
|
||||||
## :busts_in_silhouette: Community
|
|
||||||
|
|
||||||
+ 📚 [OpenIM Community](https://github.com/OpenIMSDK/community)
|
|
||||||
+ 💕 [OpenIM Interest Group](https://github.com/Openim-sigs)
|
|
||||||
+ 🚀 [Join our Slack community](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)
|
|
||||||
+ :eyes: [Join our wechat (微信群)](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
|
|
||||||
+ 👫 [Join our Reddit](https://www.reddit.com/r/OpenIMessaging)
|
|
||||||
+ 💬 [Follow our Twitter account](https://twitter.com/openimsdk)
|
|
||||||
|
|
||||||
## :calendar: Community Meetings
|
## :calendar: Community Meetings
|
||||||
|
|
||||||
We want anyone to get involved in our community and contributing code, we offer gifts and rewards, and we welcome you to join us every Thursday night.
|
We want anyone to get involved in our community and contributing code, we offer gifts and rewards, and we welcome you to join us every Thursday night.
|
||||||
|
@ -15,118 +15,17 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"strconv"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/api"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
|
||||||
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
|
||||||
ginprom "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
apiCmd := cmd.NewApiCmd()
|
apiCmd := cmd.NewApiCmd()
|
||||||
apiCmd.AddPortFlag()
|
apiCmd.AddPortFlag()
|
||||||
apiCmd.AddPrometheusPortFlag()
|
apiCmd.AddPrometheusPortFlag()
|
||||||
apiCmd.AddApi(run)
|
|
||||||
if err := apiCmd.Execute(); err != nil {
|
if err := apiCmd.Execute(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(port int, proPort int) error {
|
|
||||||
if port == 0 || proPort == 0 {
|
|
||||||
err := "port or proPort is empty:" + strconv.Itoa(port) + "," + strconv.Itoa(proPort)
|
|
||||||
return errs.Wrap(fmt.Errorf(err))
|
|
||||||
}
|
|
||||||
rdb, err := cache.NewRedis()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var client discoveryregistry.SvcDiscoveryRegistry
|
|
||||||
|
|
||||||
// Determine whether zk is passed according to whether it is a clustered deployment
|
|
||||||
client, err = kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
|
||||||
if err != nil {
|
|
||||||
return errs.Wrap(err, "register discovery err")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = client.CreateRpcRootNodes(config.Config.GetServiceNames()); err != nil {
|
|
||||||
return errs.Wrap(err, "create rpc root nodes error")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = client.RegisterConf2Registry(constant.OpenIMCommonConfigKey, config.Config.EncodeConfig()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
netDone = make(chan struct{}, 1)
|
|
||||||
netErr error
|
|
||||||
)
|
|
||||||
router := api.NewGinRouter(client, rdb)
|
|
||||||
if config.Config.Prometheus.Enable {
|
|
||||||
go func() {
|
|
||||||
p := ginprom.NewPrometheus("app", prommetrics.GetGinCusMetrics("Api"))
|
|
||||||
p.SetListenAddress(fmt.Sprintf(":%d", proPort))
|
|
||||||
if err = p.Use(router); err != nil && err != http.ErrServerClosed {
|
|
||||||
netErr = errs.Wrap(err, fmt.Sprintf("prometheus start err: %d", proPort))
|
|
||||||
netDone <- struct{}{}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var address string
|
|
||||||
if config.Config.Api.ListenIP != "" {
|
|
||||||
address = net.JoinHostPort(config.Config.Api.ListenIP, strconv.Itoa(port))
|
|
||||||
} else {
|
|
||||||
address = net.JoinHostPort("0.0.0.0", strconv.Itoa(port))
|
|
||||||
}
|
|
||||||
|
|
||||||
server := http.Server{Addr: address, Handler: router}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
err = server.ListenAndServe()
|
|
||||||
if err != nil && err != http.ErrServerClosed {
|
|
||||||
netErr = errs.Wrap(err, fmt.Sprintf("api start err: %s", server.Addr))
|
|
||||||
netDone <- struct{}{}
|
|
||||||
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
sigs := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(sigs, syscall.SIGTERM)
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
select {
|
|
||||||
case <-sigs:
|
|
||||||
util.SIGUSR1Exit()
|
|
||||||
err := server.Shutdown(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return errs.Wrap(err, "shutdown err")
|
|
||||||
}
|
|
||||||
case <-netDone:
|
|
||||||
close(netDone)
|
|
||||||
return netErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -15,14 +15,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/tools"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cronTaskCmd := cmd.NewCronTaskCmd()
|
cronTaskCmd := cmd.NewCronTaskCmd()
|
||||||
if err := cronTaskCmd.Exec(tools.StartTask); err != nil {
|
if err := cronTaskCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ func main() {
|
|||||||
msgGatewayCmd.AddWsPortFlag()
|
msgGatewayCmd.AddWsPortFlag()
|
||||||
msgGatewayCmd.AddPortFlag()
|
msgGatewayCmd.AddPortFlag()
|
||||||
msgGatewayCmd.AddPrometheusPortFlag()
|
msgGatewayCmd.AddPrometheusPortFlag()
|
||||||
|
|
||||||
if err := msgGatewayCmd.Exec(); err != nil {
|
if err := msgGatewayCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push"
|
"github.com/openimsdk/open-im-server/v3/internal/push"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
pushCmd := cmd.NewRpcCmd(cmd.RpcPushServer)
|
pushCmd := cmd.NewRpcCmd(cmd.RpcPushServer, push.Start)
|
||||||
pushCmd.AddPortFlag()
|
pushCmd.AddPortFlag()
|
||||||
pushCmd.AddPrometheusPortFlag()
|
pushCmd.AddPrometheusPortFlag()
|
||||||
if err := pushCmd.Exec(); err != nil {
|
if err := pushCmd.Exec(); err != nil {
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
if err := pushCmd.StartSvr(config.Config.RpcRegisterName.OpenImPushName, push.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,19 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/auth"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/auth"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
authCmd := cmd.NewRpcCmd(cmd.RpcAuthServer)
|
authCmd := cmd.NewRpcCmd(cmd.RpcAuthServer, auth.Start)
|
||||||
authCmd.AddPortFlag()
|
authCmd.AddPortFlag()
|
||||||
authCmd.AddPrometheusPortFlag()
|
authCmd.AddPrometheusPortFlag()
|
||||||
if err := authCmd.Exec(); err != nil {
|
if err := authCmd.Exec(); err != nil {
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
if err := authCmd.StartSvr(config.Config.RpcRegisterName.OpenImAuthName, auth.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/conversation"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/conversation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcConversationServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcConversationServer, conversation.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImConversationName, conversation.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/friend"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/friend"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcFriendServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcFriendServer, friend.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImFriendName, friend.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/group"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/group"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcGroupServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcGroupServer, group.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImGroupName, group.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/msg"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/msg"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcMsgServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcMsgServer, msg.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImMsgName, msg.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/third"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/third"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcThirdServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcThirdServer, third.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImThirdName, third.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/user"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/user"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcUserServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcUserServer, user.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImUserName, user.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,6 +153,13 @@ object:
|
|||||||
accessKeySecret: ''
|
accessKeySecret: ''
|
||||||
sessionToken: ''
|
sessionToken: ''
|
||||||
publicRead: false
|
publicRead: false
|
||||||
|
aws:
|
||||||
|
endpoint: ""
|
||||||
|
region: ""
|
||||||
|
bucket: "demo-9999999"
|
||||||
|
accessKeyID: ''
|
||||||
|
accessKeySecret: ''
|
||||||
|
publicRead: false
|
||||||
|
|
||||||
###################### RPC Port Configuration ######################
|
###################### RPC Port Configuration ######################
|
||||||
# RPC service ports
|
# RPC service ports
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
},
|
},
|
||||||
"id": 16,
|
"id": 16,
|
||||||
"panels": [],
|
"panels": [],
|
||||||
"title": "openim自定义指标",
|
"title": "openim Custom Metrics",
|
||||||
"type": "row"
|
"type": "row"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -144,7 +144,7 @@
|
|||||||
"refId": "A"
|
"refId": "A"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "在线人数",
|
"title": "Online population",
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -235,7 +235,7 @@
|
|||||||
"refId": "A"
|
"refId": "A"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "登入/注册人数",
|
"title": "Login/registration numbers",
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1345,7 +1345,7 @@
|
|||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "应用服务器流量指标",
|
"title": "Traffic indicators of the application server",
|
||||||
"type": "row"
|
"type": "row"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -153,6 +153,13 @@ object:
|
|||||||
accessKeySecret: ${KODO_ACCESS_KEY_SECRET}
|
accessKeySecret: ${KODO_ACCESS_KEY_SECRET}
|
||||||
sessionToken: ${KODO_SESSION_TOKEN}
|
sessionToken: ${KODO_SESSION_TOKEN}
|
||||||
publicRead: ${KODO_PUBLIC_READ}
|
publicRead: ${KODO_PUBLIC_READ}
|
||||||
|
aws:
|
||||||
|
endpoint: "${AWS_ENDPOINT}" # This might not be necessary unless you're using a custom endpoint
|
||||||
|
region: "${AWS_REGION}"
|
||||||
|
bucket: "${AWS_BUCKET}"
|
||||||
|
accessKeyID: ${AWS_ACCESS_KEY_ID}
|
||||||
|
accessKeySecret: ${AWS_SECRET_ACCESS_KEY}
|
||||||
|
publicRead: ${AWS_PUBLIC_READ}
|
||||||
|
|
||||||
###################### RPC Port Configuration ######################
|
###################### RPC Port Configuration ######################
|
||||||
# RPC service ports
|
# RPC service ports
|
||||||
|
@ -3,7 +3,15 @@
|
|||||||
- [Code conventions](#code-conventions)
|
- [Code conventions](#code-conventions)
|
||||||
- [POSIX shell](#posix-shell)
|
- [POSIX shell](#posix-shell)
|
||||||
- [Go](#go)
|
- [Go](#go)
|
||||||
- [Directory and file conventions](#directory-and-file-conventions)
|
- [OpenIM Naming Conventions Guide](#openim-naming-conventions-guide)
|
||||||
|
- [1. General File Naming](#1-general-file-naming)
|
||||||
|
- [2. Special File Types](#2-special-file-types)
|
||||||
|
- [a. Script and Markdown Files](#a-script-and-markdown-files)
|
||||||
|
- [b. Uppercase Markdown Documentation](#b-uppercase-markdown-documentation)
|
||||||
|
- [3. Directory Naming](#3-directory-naming)
|
||||||
|
- [4. Configuration Files](#4-configuration-files)
|
||||||
|
- [Best Practices](#best-practices)
|
||||||
|
- [Directory and File Conventions](#directory-and-file-conventions)
|
||||||
- [Testing conventions](#testing-conventions)
|
- [Testing conventions](#testing-conventions)
|
||||||
|
|
||||||
## POSIX shell
|
## POSIX shell
|
||||||
@ -67,12 +75,13 @@ Files within the OpenIM project should adhere to the following rules:
|
|||||||
+ Stick to lowercase naming where possible for consistency and to prevent issues with case-sensitive systems.
|
+ Stick to lowercase naming where possible for consistency and to prevent issues with case-sensitive systems.
|
||||||
+ Include version numbers or dates in file names if the file is subject to updates, following the format: `project-plan-v1.2.md` or `backup-2023-03-15.sql`.
|
+ Include version numbers or dates in file names if the file is subject to updates, following the format: `project-plan-v1.2.md` or `backup-2023-03-15.sql`.
|
||||||
|
|
||||||
## Directory and file conventions
|
## Directory and File Conventions
|
||||||
|
|
||||||
|
- Avoid generic utility packages. Instead of naming a package "util", choose a name that clearly describes its purpose. For instance, functions related to waiting operations are contained within the `wait` package, which includes methods like `Poll`, fully named as `wait.Poll`.
|
||||||
|
- All filenames, script files, configuration files, and directories should be in lowercase and use dashes (`-`) as separators.
|
||||||
|
- For Go language files, filenames should be in lowercase and use underscores (`_`).
|
||||||
|
- Package names should match their directory names to ensure consistency. For example, within the `openim-api` directory, the Go file should be named `openim-api.go`, following the convention of using dashes for directory names and aligning package names with directory names.
|
||||||
|
|
||||||
- Avoid general utility packages. Packages called "util" are suspect. Instead, derive a name that describes your desired function. For example, the utility functions dealing with waiting for operations are in the `wait` package and include functionality like `Poll`. The full name is `wait.Poll`.
|
|
||||||
- All filenames should be lowercase.
|
|
||||||
- All source files and directories should use underscores, not dashes.
|
|
||||||
- Package directories should generally avoid using separators as much as possible. When package names are multiple words, they usually should be in nested subdirectories.
|
|
||||||
|
|
||||||
## Testing conventions
|
## Testing conventions
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ This section involves configuring the log settings, including storage location,
|
|||||||
|
|
||||||
| Parameter | Example Value | Description |
|
| Parameter | Example Value | Description |
|
||||||
| ------------------------- | ------------------------ | --------------------------------- |
|
| ------------------------- | ------------------------ | --------------------------------- |
|
||||||
| LOG_STORAGE_LOCATION | "${OPENIM_ROOT}/logs/" | Location for storing logs |
|
| LOG_STORAGE_LOCATION | "${OPENIM_ROOT}/_output/logs/" | Location for storing logs |
|
||||||
| LOG_ROTATION_TIME | "24" | Log rotation time (in hours) |
|
| LOG_ROTATION_TIME | "24" | Log rotation time (in hours) |
|
||||||
| LOG_REMAIN_ROTATION_COUNT | "2" | Number of log rotations to retain |
|
| LOG_REMAIN_ROTATION_COUNT | "2" | Number of log rotations to retain |
|
||||||
| LOG_REMAIN_LOG_LEVEL | "6" | Log level to retain |
|
| LOG_REMAIN_LOG_LEVEL | "6" | Log level to retain |
|
||||||
|
@ -26,19 +26,19 @@ jwt "github.com/dgrijalva/jwt-go/v4"
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
// go standard package
|
// go standard package
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
// third party package
|
// third party package
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
// Anonymous packages are grouped separately, and anonymous package references are explained
|
// Anonymous packages are grouped separately, and anonymous package references are explained
|
||||||
// import mysql driver
|
// import mysql driver
|
||||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
|
|
||||||
// inner package
|
// inner package
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -48,33 +48,33 @@ When multiple variables need to be used in a function, the `var` declaration can
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
var (
|
var (
|
||||||
Width int
|
Width int
|
||||||
Height int
|
Height int
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
- When initializing a structure reference, please use `&T{}` instead of `new(T)` to make it consistent with structure initialization.
|
- When initializing a structure reference, please use `&T{}` instead of `new(T)` to make it consistent with structure initialization.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
sptr := new(T)
|
sptr := new(T)
|
||||||
sptr.Name = "bar"
|
sptr.Name = "bar"
|
||||||
|
|
||||||
// good
|
// good
|
||||||
sptr := &T{Name: "bar"}
|
sptr := &T{Name: "bar"}
|
||||||
```
|
```
|
||||||
|
|
||||||
- The struct declaration and initialization format takes multiple lines and is defined as follows.
|
- The struct declaration and initialization format takes multiple lines and is defined as follows.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type User struct{
|
type User struct{
|
||||||
Username string
|
Username string
|
||||||
Email string
|
Email string
|
||||||
}
|
}
|
||||||
|
|
||||||
user := User{
|
user := User{
|
||||||
Username: "belm",
|
Username: "belm",
|
||||||
Email: "nosbelm@qq.com",
|
Email: "nosbelm@qq.com",
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -217,20 +217,20 @@ if err != nil {
|
|||||||
// bad
|
// bad
|
||||||
v, err := foo()
|
v, err := foo()
|
||||||
if err != nil || v == nil {
|
if err != nil || v == nil {
|
||||||
// error handling
|
// error handling
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//good
|
//good
|
||||||
v, err := foo()
|
v, err := foo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// error handling
|
// error handling
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if v == nil {
|
if v == nil {
|
||||||
// error handling
|
// error handling
|
||||||
return errors. New("invalid value v")
|
return errors. New("invalid value v")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -239,13 +239,14 @@ return errors. New("invalid value v")
|
|||||||
```go
|
```go
|
||||||
v, err := f()
|
v, err := f()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// error handling
|
// error handling
|
||||||
return // or continue.
|
return // or continue.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- Bug description suggestions
|
- Bug description suggestions
|
||||||
- Error descriptions start with a lowercase letter and do not end with punctuation, for example:
|
- Error descriptions start with a lowercase letter and do not end with punctuation, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
errors.New("Redis connection failed")
|
errors.New("Redis connection failed")
|
||||||
@ -254,6 +255,7 @@ errors.New("redis connection failed.")
|
|||||||
// good
|
// good
|
||||||
errors.New("redis connection failed")
|
errors.New("redis connection failed")
|
||||||
```
|
```
|
||||||
|
|
||||||
- Tell users what they can do, not what they can't.
|
- Tell users what they can do, not what they can't.
|
||||||
- When declaring a requirement, use must instead of should. For example, `must be greater than 0, must match regex '[a-z]+'`.
|
- When declaring a requirement, use must instead of should. For example, `must be greater than 0, must match regex '[a-z]+'`.
|
||||||
- When declaring that a format is incorrect, use must not. For example, `must not contain`.
|
- When declaring that a format is incorrect, use must not. For example, `must not contain`.
|
||||||
@ -359,18 +361,18 @@ u := User{
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```
|
```go
|
||||||
// Seeking to an offset before the start of the file is an error.
|
// Seeking to an offset before the start of the file is an error.
|
||||||
// Seeking to any positive offset is legal, but the behavior of subsequent
|
// Seeking to any positive offset is legal, but the behavior of subsequent
|
||||||
// I/O operations on the underlying object are implementation-dependent.
|
// I/O operations on the underlying object are implementation-dependent.
|
||||||
type Seeker interface {
|
type Seeker interface {
|
||||||
Seek(offset int64, whence int) (int64, error)
|
Seek(offset int64, whence int) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadWriter is the interface that groups the basic Read and Write methods.
|
// ReadWriter is the interface that groups the basic Read and Write methods.
|
||||||
type ReadWriter interface {
|
type ReadWriter interface {
|
||||||
reader
|
reader
|
||||||
Writer
|
Writer
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -386,7 +388,7 @@ Writer
|
|||||||
|
|
||||||
Some common nouns are listed below.
|
Some common nouns are listed below.
|
||||||
|
|
||||||
```
|
```go
|
||||||
// A GonicMapper that contains a list of common initialisms taken from golang/lint
|
// A GonicMapper that contains a list of common initialisms taken from golang/lint
|
||||||
var LintGonicMapper = GonicMapper{
|
var LintGonicMapper = GonicMapper{
|
||||||
"API": true,
|
"API": true,
|
||||||
@ -523,6 +525,7 @@ package genericclioptions
|
|||||||
// ErrSigningMethod defines invalid signing method error.
|
// ErrSigningMethod defines invalid signing method error.
|
||||||
var ErrSigningMethod = errors. New("Invalid signing method")
|
var ErrSigningMethod = errors. New("Invalid signing method")
|
||||||
```
|
```
|
||||||
|
|
||||||
- When there is a large block of constant or variable definition, you can comment a general description in front, and then comment the definition of the constant in detail before or at the end of each line of constant, for example:
|
- When there is a large block of constant or variable definition, you can comment a general description in front, and then comment the definition of the constant in detail before or at the end of each line of constant, for example:
|
||||||
```go
|
```go
|
||||||
// Code must start with 1xxxxx.
|
// Code must start with 1xxxxx.
|
||||||
@ -567,7 +570,7 @@ Each function or method that needs to be exported must have a comment, the forma
|
|||||||
// BeforeUpdate run before update database record.
|
// BeforeUpdate run before update database record.
|
||||||
func (p *Policy) BeforeUpdate() (err error) {
|
func (p *Policy) BeforeUpdate() (err error) {
|
||||||
// normal code
|
// normal code
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -743,9 +746,9 @@ for i := 0; i < 10; i++ {
|
|||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
for file := range files {
|
for file := range files {
|
||||||
fd, err := os. Open(file)
|
fd, err := os. Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer fd. Close()
|
defer fd. Close()
|
||||||
// normal code
|
// normal code
|
||||||
@ -753,14 +756,14 @@ defer fd. Close()
|
|||||||
|
|
||||||
//good
|
//good
|
||||||
for file := range files {
|
for file := range files {
|
||||||
func() {
|
func() {
|
||||||
fd, err := os. Open(file)
|
fd, err := os. Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer fd. Close()
|
defer fd. Close()
|
||||||
// normal code
|
// normal code
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -888,6 +891,7 @@ type LogHandler struct {
|
|||||||
}
|
}
|
||||||
var_http.Handler = LogHandler{}
|
var_http.Handler = LogHandler{}
|
||||||
```
|
```
|
||||||
|
|
||||||
- When the server processes a request, it should create a context, save the relevant information of the request (such as requestID), and pass it in the function call chain.
|
- When the server processes a request, it should create a context, save the relevant information of the request (such as requestID), and pass it in the function call chain.
|
||||||
|
|
||||||
### 9.1 Performance
|
### 9.1 Performance
|
||||||
@ -900,3 +904,246 @@ var_http.Handler = LogHandler{}
|
|||||||
- If you want to directly modify the value of the map, the value can only be a pointer, otherwise the original value must be overwritten.
|
- If you want to directly modify the value of the map, the value can only be a pointer, otherwise the original value must be overwritten.
|
||||||
- map needs to be locked during concurrency.
|
- map needs to be locked during concurrency.
|
||||||
- The conversion of interface{} cannot be checked during compilation, it can only be checked at runtime, be careful to cause panic.
|
- The conversion of interface{} cannot be checked during compilation, it can only be checked at runtime, be careful to cause panic.
|
||||||
|
|
||||||
|
## 10 Golang CI Lint
|
||||||
|
|
||||||
|
- Golang CI Lint is a fast Go linters runner. It runs linters in parallel, uses caching, and works well with all environments, including CI.
|
||||||
|
|
||||||
|
**In local development, you can use the following command to install Golang CI Lint: **
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make lint
|
||||||
|
```
|
||||||
|
|
||||||
|
**In CI/CD, Check the Github Actions status code below after you submit the code directly**
|
||||||
|
|
||||||
|
[](https://github.com/openimsdk/open-im-server/actions/workflows/golangci-lint.yml)
|
||||||
|
|
||||||
|
golangci lint can select the types of tools, refer to the official documentation: [https://golangci-lint.run/usage/linters/](https://golangci-lint.run/usage/linters/)
|
||||||
|
|
||||||
|
The types of comments we currently use include: [https://github.com/openimsdk/open-im-server/blob/main/.golangci.yml](https://github.com/openimsdk/open-im-server/blob/main/.golangci.yml) the `linters.enable` field in the file.
|
||||||
|
|
||||||
|
e.g:
|
||||||
|
```yaml
|
||||||
|
linters:
|
||||||
|
# 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
|
||||||
|
# enable-all: true
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- typecheck # Basic type checking
|
||||||
|
- gofmt # Format check
|
||||||
|
- govet # Go's standard linting tool
|
||||||
|
- gosimple # Suggestions for simplifying code
|
||||||
|
- misspell # Spelling mistakes
|
||||||
|
- staticcheck # Static analysis
|
||||||
|
- unused # Checks for unused code
|
||||||
|
- goimports # Checks if imports are correctly sorted and formatted
|
||||||
|
- godot # Checks for comment punctuation
|
||||||
|
- bodyclose # Ensures HTTP response body is closed
|
||||||
|
- errcheck # Checks for missed error returns
|
||||||
|
fast: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Add that Chinese comments are not allowed in go code, please write a complete golangci lint specification on the basis of the above.
|
||||||
|
|
||||||
|
|
||||||
|
### 10.1 Configuration Document
|
||||||
|
|
||||||
|
This configuration document is designed to configure the operational parameters of OpenIM (a hypothetical or specific code analysis tool), customize output formats, and provide detailed settings for specific code checkers (linters). Below is a summary of the document drafted based on the provided configuration information.
|
||||||
|
|
||||||
|
#### 10.1 Runtime Options
|
||||||
|
|
||||||
|
- **Concurrency** (`concurrency`): Default to use the available CPU count, can be manually set to 4 for parallel analysis.
|
||||||
|
- **Timeout** (`timeout`): Timeout duration for analysis operations, default is 1 minute, set here to 5 minutes.
|
||||||
|
- **Issue Exit Code** (`issues-exit-code`): Exit code defaults to 1 if at least one issue is found.
|
||||||
|
- **Test Files** (`tests`): Whether to include test files, defaults to true.
|
||||||
|
- **Build Tags** (`build-tags`): Specify build tags used by all linters, defaults to an empty list. Example adds `mytag`.
|
||||||
|
- **Skip Directories** (`skip-dirs`): Configure which directories' issues are not reported, defaults to empty, but some default directories are independently skipped.
|
||||||
|
- **Skip Files** (`skip-files`): Specify files where issues should not be reported, supports regular expressions.
|
||||||
|
|
||||||
|
#### 10.2 Output Configuration
|
||||||
|
|
||||||
|
- **Format** (`format`): Set output format, default is "colored-line-number".
|
||||||
|
- **Print Issued Lines** (`print-issued-lines`): Whether to print the lines where issues occur, defaults to true.
|
||||||
|
- **Print Linter Name** (`print-linter-name`): Whether to print the linter name at the end of issue text, defaults to true.
|
||||||
|
- **Uniqueness Filter** (`uniq-by-line`): Whether to make issue outputs unique per line, defaults to true.
|
||||||
|
- **Path Prefix** (`path-prefix`): Prefix to add to output file references, defaults to no prefix.
|
||||||
|
- **Sort Results** (`sort-results`): Sort results by file path, line number, and column number.
|
||||||
|
|
||||||
|
#### 10.3 Linters Settings
|
||||||
|
|
||||||
|
In the configuration file, the `linters-settings` section allows detailed configuration of individual linters. Below are examples of specific linters settings and their purposes:
|
||||||
|
|
||||||
|
- **bidichk**: Used to check bidirectional text characters, ensuring correct display direction of text, especially when dealing with mixed left-to-right (LTR) and right-to-left (RTL) text.
|
||||||
|
|
||||||
|
- **dogsled**: Monitors excessive use of blank identifiers (`_`) in assignment operations, which may obscure data processing errors or unclear logic.
|
||||||
|
|
||||||
|
- **dupl**: Identifies duplicate code blocks, helping developers avoid code redundancy. The `threshold` parameter in settings allows adjustment of code similarity threshold triggering warnings.
|
||||||
|
|
||||||
|
- **errcheck**: Checks for unhandled errors. In Go, error handling is achieved by checking function return values. This linter helps ensure all errors are properly handled.
|
||||||
|
|
||||||
|
- **exhaustive**: Checks if `switch` statements include all possible values of an enum type, ensuring exhaustiveness of code. This helps avoid forgetting to handle certain cases.
|
||||||
|
|
||||||
|
#### 10.4 Example: `errcheck`
|
||||||
|
|
||||||
|
**Incorrect Code Example**:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f, _ := os.Open("filename.ext")
|
||||||
|
defer f.Close()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Issue**: In the above code, the error return value of `os.Open` function is explicitly ignored. This is a common mistake as it may lead to unhandled errors and hard-to-trace bugs.
|
||||||
|
|
||||||
|
**Correct Form**:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f, err := os.Open("filename.ext")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("error opening file: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In the correct form, by checking the error (`err`) returned by `os.Open`, we gracefully handle error cases rather than simply ignoring them.
|
||||||
|
|
||||||
|
#### 10.5 Example: `gofmt`
|
||||||
|
|
||||||
|
**Incorrect Code Example**:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
import "fmt"
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello, world!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Issue**: This code snippet doesn't follow Go's standard formatting rules, for example, incorrect indentation of `fmt.Println`.
|
||||||
|
|
||||||
|
**Correct Form**:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello, world!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Using `gofmt` tool can automatically fix such formatting issues, ensuring the code adheres to the coding standards of the Go community.
|
||||||
|
|
||||||
|
#### 10.6 Example: `unused`
|
||||||
|
|
||||||
|
**Incorrect Code Example**:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
func helper() {}
|
||||||
|
|
||||||
|
func main() {}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Issue**: The `helper` function is defined but not called anywhere, indicating potential redundant code or missing functionality implementation.
|
||||||
|
|
||||||
|
**Correct Form**:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
// If the helper function is indeed needed, ensure it's used properly.
|
||||||
|
func helper() {
|
||||||
|
// Implement the function's functionality or ensure it's called elsewhere
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
helper()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To improve the section on Linters settings in the document, we'll expand with more detailed explanations and reinforce understanding through examples.
|
||||||
|
|
||||||
|
#### 10.7 Example: `dogsled`
|
||||||
|
|
||||||
|
**Incorrect Code Example**:
|
||||||
|
```go
|
||||||
|
func getValues() (int, int, int) {
|
||||||
|
return 1, 2, 3
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
_, _, val := getValues()
|
||||||
|
fmt.Println(val) // Only interested in the third return value
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Explanation**: In the above code, we use two blank identifiers to ignore the first two return values. Excessive use of blank identifiers can make code reading difficult.
|
||||||
|
|
||||||
|
**Improved Code**:
|
||||||
|
Consider refactoring the function or the usage of return values to reduce the need for blank identifiers or explicitly comment why ignoring certain values is safe.
|
||||||
|
|
||||||
|
#### 10.8: `exhaustive`
|
||||||
|
|
||||||
|
**Incorrect Code Example**:
|
||||||
|
```go
|
||||||
|
type Fruit int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Apple Fruit = iota
|
||||||
|
Banana
|
||||||
|
Orange
|
||||||
|
)
|
||||||
|
|
||||||
|
func getFruitName(f Fruit) string {
|
||||||
|
switch f {
|
||||||
|
case Apple:
|
||||||
|
return "Apple"
|
||||||
|
case Banana:
|
||||||
|
return "Banana"
|
||||||
|
// Missing handling for Orange
|
||||||
|
}
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Explanation**: In this code, the `switch` statement doesn't cover all possible values of the `Fruit` type; the case for `Orange` is missing.
|
||||||
|
|
||||||
|
**Improved Code**:
|
||||||
|
```go
|
||||||
|
func getFruitName(f Fruit) string {
|
||||||
|
switch f {
|
||||||
|
case Apple:
|
||||||
|
return "Apple"
|
||||||
|
case Banana:
|
||||||
|
return "Banana"
|
||||||
|
case Orange:
|
||||||
|
return "Orange"
|
||||||
|
}
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
By adding the missing `case`, we ensure the `switch` statement is exhaustive, handling every possible enum value.
|
||||||
|
|
||||||
|
#### 10.9 Optimization of Configuration Files and Application of Code Analysis Tools
|
||||||
|
|
||||||
|
Through these examples, we demonstrate how to improve code quality by identifying and fixing common coding issues. OpenIM's configuration files allow developers to customize linters' behavior according to project requirements, ensuring code compliance with predefined quality standards and style guidelines.
|
||||||
|
|
||||||
|
By employing these tools and configuration strategies, teams can reduce the number of bugs, enhance code maintainability, and facilitate efficient collaboration during code review processes.
|
||||||
|
186
docs/readme/README_el.md
Normal file
186
docs/readme/README_el.md
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://openim.io">
|
||||||
|
<img src="../../assets/logo-gif/openim-logo.gif" width="60%" height="30%"/>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
[](https://github.com/openimsdk/open-im-server/stargazers)
|
||||||
|
[](https://github.com/openimsdk/open-im-server/network/members)
|
||||||
|
[](https://app.codecov.io/gh/openimsdk/open-im-server)
|
||||||
|
[](https://goreportcard.com/report/github.com/openimsdk/open-im-server)
|
||||||
|
[](https://pkg.go.dev/github.com/openimsdk/open-im-server/v3)
|
||||||
|
[](https://github.com/openimsdk/open-im-server/blob/main/LICENSE)
|
||||||
|
[](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)
|
||||||
|
[](https://www.bestpractices.dev/projects/8045)
|
||||||
|
[](https://github.com/openimsdk/open-im-server/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22)
|
||||||
|
[](https://golang.org/)
|
||||||
|
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="../../README.md">Englist</a> ·
|
||||||
|
<a href="../../README_zh_CN.md">中文</a> ·
|
||||||
|
<a href="./README_uk.md">Українська</a> ·
|
||||||
|
<a href="./README_cs.md">Česky</a> ·
|
||||||
|
<a href="./README_hu.md">Magyar</a> ·
|
||||||
|
<a href="./README_es.md">Español</a> ·
|
||||||
|
<a href="./README_fa.md">فارسی</a> ·
|
||||||
|
<a href="./README_fr.md">Français</a> ·
|
||||||
|
<a href="./README_de.md">Deutsch</a> ·
|
||||||
|
<a href="./README_pl.md">Polski</a> ·
|
||||||
|
<a href="./README_id.md">Indonesian</a> ·
|
||||||
|
<a href="./README_fi.md">Suomi</a> ·
|
||||||
|
<a href="./README_ml.md">മലയാളം</a> ·
|
||||||
|
<a href="./README_ja.md">日本語</a> ·
|
||||||
|
<a href="./README_nl.md">Nederlands</a> ·
|
||||||
|
<a href="./README_it.md">Italiano</a> ·
|
||||||
|
<a href="./README_ru.md">Русский</a> ·
|
||||||
|
<a href="./README_pt_BR.md">Português (Brasil)</a> ·
|
||||||
|
<a href="./README_eo.md">Esperanto</a> ·
|
||||||
|
<a href="./README_ko.md">한국어</a> ·
|
||||||
|
<a href="./README_ar.md">العربي</a> ·
|
||||||
|
<a href="./README_vi.md">Tiếng Việt</a> ·
|
||||||
|
<a href="./README_da.md">Dansk</a> ·
|
||||||
|
<a href="./README_el.md">Ελληνικά</a> ·
|
||||||
|
<a href="./README_tr.md">Türkçe</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Ⓜ️ Σχετικά με το OpenIM
|
||||||
|
|
||||||
|
Το OpenIM είναι μια πλατφόρμα υπηρεσιών σχεδιασμένη ειδικά για την ενσωμάτωση συνομιλίας, κλήσεων ήχου-βίντεο, ειδοποιήσεων και chatbots AI σε εφαρμογές. Παρέχει μια σειρά από ισχυρά API και Webhooks, επιτρέποντας στους προγραμματιστές να ενσωματώσουν εύκολα αυτές τις αλληλεπιδραστικές λειτουργίες στις εφαρμογές τους. Το OpenIM δεν είναι μια αυτόνομη εφαρμογή συνομιλίας, αλλά λειτουργεί ως πλατφόρμα υποστήριξης άλλων εφαρμογών για την επίτευξη πλούσιων λειτουργιών επικοινωνίας. Το παρακάτω διάγραμμα απεικονίζει την αλληλεπίδραση μεταξύ AppServer, AppClient, OpenIMServer και OpenIMSDK για να εξηγήσει αναλυτικά.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 🚀 Σχετικά με το OpenIMSDK
|
||||||
|
|
||||||
|
Το **OpenIMSDK** είναι ένα SDK για αμεση ανταλλαγή μηνυμάτων σχεδιασμένο για το **OpenIMServer**, δημιουργήθηκε ειδικά για ενσωμάτωση σε εφαρμογές πελατών. Οι κύριες δυνατότητες και μονάδες του είναι οι εξής:
|
||||||
|
|
||||||
|
+ 🌟 Κύριες Δυνατότητες:
|
||||||
|
|
||||||
|
- 📦 Τοπική αποθήκευση
|
||||||
|
- 🔔 Callbacks ακροατών
|
||||||
|
- 🛡️ Περιτύλιγμα API
|
||||||
|
- 🌐 Διαχείριση σύνδεσης
|
||||||
|
|
||||||
|
+ 📚 Κύριες Μονάδες:
|
||||||
|
|
||||||
|
1. 🚀 Αρχικοποίηση και Σύνδεση
|
||||||
|
2. 👤 Διαχείριση Χρηστών
|
||||||
|
3. 👫 Διαχείριση Φίλων
|
||||||
|
4. 🤖 Λειτουργίες Ομάδας
|
||||||
|
5. 💬 Διαχείριση Συνομιλιών
|
||||||
|
|
||||||
|
Είναι κατασκευασμένο χρησιμοποιώντας Golang και υποστηρίζει διασταυρούμενη πλατφόρμα ανάπτυξης, διασφαλίζοντας μια συνεπή εμπειρία πρόσβασης σε όλες τις πλατφόρμες.
|
||||||
|
|
||||||
|
👉 **[Εξερευνήστε το GO SDK](https://github.com/openimsdk/openim-sdk-core)**
|
||||||
|
|
||||||
|
## 🌐 Σχετικά με το OpenIMServer
|
||||||
|
|
||||||
|
+ Το **OpenIMServer** έχει τις ακόλουθες χαρακτηριστικές:
|
||||||
|
- 🌐 Αρχιτεκτονική μικροϋπηρεσιών: Υποστηρίζει λειτουργία σε σύμπλεγμα, περιλαμβάνοντας έναν πύλη και πολλαπλές υπηρεσίες rpc.
|
||||||
|
- 🚀 Διάφοροι τρόποι ανάπτυξης: Υποστηρίζει ανάπτυξη μέσω πηγαίου κώδικα, Kubernetes, ή Docker.
|
||||||
|
- Υποστήριξη για τεράστια βάση χρηστών: Πολύ μεγάλες ομάδες με εκατοντάδες χιλιάδες χρήστες, δεκάδες εκατομμύρια χρήστες και δισεκατομμύρια μηνύματα.
|
||||||
|
|
||||||
|
### Ενισχυμένη Επιχειρηματική Λειτουργικότητα:
|
||||||
|
|
||||||
|
+ **REST API**: Το OpenIMServer προσφέρει REST APIs για επιχειρηματικά συστήματα, με στόχο την ενδυνάμωση των επιχειρήσεων με περισσότερες λειτουργικότητες, όπως η δημιουργία ομάδων και η αποστολή μηνυμάτων push μέσω backend διεπαφών.
|
||||||
|
+ **Webhooks**: Το OpenIMServer παρέχει δυνατότητες επανάκλησης για την επέκταση περισσότερων επιχειρηματικών μορφών. Μια επανάκληση σημαίνει ότι το OpenIMServer στέλνει ένα αίτημα στον επιχειρηματικό διακομιστή πριν ή μετά από ένα συγκεκριμένο γεγονός, όπως επανακλήσεις πριν ή μετά την αποστολή ενός μηνύματος.
|
||||||
|
|
||||||
|
👉 **[Μάθετε περισσότερα](https://docs.openim.io/guides/introduction/product)**
|
||||||
|
|
||||||
|
## :building_construction: Συνολική Αρχιτεκτονική
|
||||||
|
|
||||||
|
Εξερευνήστε σε βάθος τη λειτουργικότητα του Open-IM-Server με το διάγραμμα αρχιτεκτονικής μας.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## :rocket: Γρήγορη Εκκίνηση
|
||||||
|
|
||||||
|
Υποστηρίζουμε πολλές πλατφόρμες. Εδώ είναι οι διευθύνσεις για γρήγορη εμπειρία στην πλευρά του διαδικτύου:
|
||||||
|
|
||||||
|
👉 **[Διαδικτυακή επίδειξη του OpenIM](https://web-enterprise.rentsoft.cn/)**
|
||||||
|
|
||||||
|
🤲 Για να διευκολύνουμε την εμπειρία του χρήστη, προσφέρουμε διάφορες λύσεις ανάπτυξης. Μπορείτε να επιλέξετε τη μέθοδο ανάπτυξης σας από την παρακάτω λίστα:
|
||||||
|
|
||||||
|
+ **[Οδηγός Ανάπτυξης Κώδικα Πηγής](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
|
||||||
|
+ **[δηγός Ανάπτυξης μέσω Docker](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
|
||||||
|
+ **[Οδηγός Ανάπτυξης Kubernetes](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
|
||||||
|
+ **[Οδηγός Ανάπτυξης για Αναπτυξιακούς στο Mac](https://docs.openim.io/guides/gettingstarted/mac-deployment-guide)**
|
||||||
|
|
||||||
|
## :hammer_and_wrench: Για να Αρχίσετε την Ανάπτυξη του OpenIM
|
||||||
|
|
||||||
|
[](https://vscode.dev/github/openimsdk/open-im-server)
|
||||||
|
|
||||||
|
OpenIM Στόχος μας είναι να δημιουργήσουμε μια κορυφαίου επιπέδου ανοιχτή πηγή κοινότητας. Διαθέτουμε ένα σύνολο προτύπων, στο [Αποθετήριο Κοινότητας](https://github.com/OpenIMSDK/community).
|
||||||
|
|
||||||
|
Εάν θέλετε να συνεισφέρετε σε αυτό το αποθετήριο Open-IM-Server, παρακαλούμε διαβάστε την [τεκμηρίωση συνεισφέροντος](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
Πριν ξεκινήσετε, παρακαλούμε βεβαιωθείτε ότι οι αλλαγές σας είναι ζητούμενες. Το καλύτερο για αυτό είναι να δημιουργήσετε ένα [νέα συζήτηση](https://github.com/openimsdk/open-im-server/discussions/new/choose) ή [Επικοινωνία Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q), ή αν βρείτε ένα ζήτημα, [αναφέρετέ το](https://github.com/openimsdk/open-im-server/issues/new/choose) πρώτα.
|
||||||
|
|
||||||
|
- [Αναφορά API του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/api.md)
|
||||||
|
- [Καταγραφή Bash του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/bash-log.md)
|
||||||
|
- [Ενέργειες CI/CD του OpenIMs](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/cicd-actions.md)
|
||||||
|
- [Συμβάσεις Κώδικα του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/code-conventions.md)
|
||||||
|
- [Οδηγίες Commit του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/commit.md)
|
||||||
|
- [Οδηγός Ανάπτυξης του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/development.md)
|
||||||
|
- [Δομή Καταλόγου του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/directory.md)
|
||||||
|
- [Ρύθμιση Περιβάλλοντος του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/environment.md)
|
||||||
|
- [Αναφορά Κωδικών Σφάλματος του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/error-code.md)
|
||||||
|
- [Ροή Εργασίας Git του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/git-workflow.md)
|
||||||
|
- [Οδηγός Cherry Pick του Git του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/gitcherry-pick.md)
|
||||||
|
- [Ροή Εργασίας GitHub του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/github-workflow.md)
|
||||||
|
- [Πρότυπα Κώδικα Go του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/go-code.md)
|
||||||
|
- [Οδηγίες Εικόνας του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/images.md)
|
||||||
|
- [Αρχική Διαμόρφωση του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/init-config.md)
|
||||||
|
- [Οδηγός Εγκατάστασης Docker του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/install-docker.md)
|
||||||
|
- [Οδηγός Εγκατάστασης Συστήματος Linux του Open](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/install-openim-linux-system.md)
|
||||||
|
- [Οδηγός Ανάπτυξης Linux του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/linux-development.md)
|
||||||
|
- [Οδηγός Τοπικών Δράσεων του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/local-actions.md)
|
||||||
|
- [Συμβάσεις Καταγραφής του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/logging.md)
|
||||||
|
- [Αποστολή Εκτός Σύνδεσης του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/offline-deployment.md)
|
||||||
|
- [Εργαλεία Protoc του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/protoc-tools.md)
|
||||||
|
- [Οδηγός Δοκιμών του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/test.md)
|
||||||
|
- [Χρησιμότητα Go του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-go.md)
|
||||||
|
- [Χρησιμότητες Makefile του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-makefile.md)
|
||||||
|
- [Χρησιμότητες Σεναρίου του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-scripts.md)
|
||||||
|
- [Έκδοση του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/version.md)
|
||||||
|
- [Διαχείριση backend και παρακολούθηση ανάπτυξης](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/prometheus-grafana.md)
|
||||||
|
- [Οδηγός Ανάπτυξης για Προγραμματιστές Mac του OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/mac-developer-deployment-guide.md)
|
||||||
|
|
||||||
|
|
||||||
|
## :busts_in_silhouette: Κοινότητα
|
||||||
|
|
||||||
|
+ 📚 [Κοινότητα OpenIM](https://github.com/OpenIMSDK/community)
|
||||||
|
+ 💕 [Ομάδα Ενδιαφέροντος OpenIM](https://github.com/Openim-sigs)
|
||||||
|
+ 🚀 [Εγγραφείτε στην κοινότητα Slack μας](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)
|
||||||
|
+ :eyes: [γγραφείτε στην ομάδα μας wechat (微信群)](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
|
||||||
|
|
||||||
|
## :calendar: Συναντήσεις της κοινότητας
|
||||||
|
|
||||||
|
Θέλουμε οποιονδήποτε να εμπλακεί στην κοινότητά μας και να συνεισφέρει κώδικα. Προσφέρουμε δώρα και ανταμοιβές και σας καλωσορίζουμε να μας ενταχθείτε κάθε Πέμπτη βράδυ.
|
||||||
|
|
||||||
|
Η διάσκεψή μας είναι στο [OpenIM Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q) 🎯, στη συνέχεια μπορείτε να αναζητήσετε τη διαδικασία Open-IM-Server για να συμμετάσχετε
|
||||||
|
|
||||||
|
Κάνουμε σημειώσεις για κάθε μια [Σημειώνουμε κάθε διμηνιαία συνάντηση](https://github.com/orgs/OpenIMSDK/discussions/categories/meeting) στις [συζητήσεις του GitHub](https://github.com/openimsdk/open-im-server/discussions/categories/meeting), Οι ιστορικές μας σημειώσεις συναντήσεων, καθώς και οι επαναλήψεις των συναντήσεων είναι διαθέσιμες στο[Έγγραφα της Google :bookmark_tabs:](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing).
|
||||||
|
|
||||||
|
## :eyes: Ποιοί Χρησιμοποιούν το OpenIM
|
||||||
|
|
||||||
|
Ελέγξτε τη σελίδα με τις [μελέτες περίπτωσης χρήσης ](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) μας για μια λίστα των χρηστών του έργου. Μην διστάσετε να αφήσετε ένα[📝σχόλιο](https://github.com/openimsdk/open-im-server/issues/379) και να μοιραστείτε την περίπτωση χρήσης σας.
|
||||||
|
## :page_facing_up: Άδεια Χρήσης
|
||||||
|
|
||||||
|
Το OpenIM διατίθεται υπό την άδεια Apache 2.0. Δείτε τη [ΑΔΕΙΑ ΧΡΗΣΗΣ](https://github.com/openimsdk/open-im-server/tree/main/LICENSE) για το πλήρες κείμενο της άδειας.
|
||||||
|
|
||||||
|
Το λογότυπο του OpenIM, συμπεριλαμβανομένων των παραλλαγών και των κινούμενων εικόνων, που εμφανίζονται σε αυτό το αποθετήριο[OpenIM](https://github.com/openimsdk/open-im-server) υπό τις διευθύνσεις [assets/logo](../../assets/logo) και [assets/logo-gif](../../assets/logo-gif) προστατεύονται από τους νόμους περί πνευματικής ιδιοκτησίας.
|
||||||
|
|
||||||
|
## 🔮 Ευχαριστούμε τους συνεισφέροντες μας!
|
||||||
|
|
||||||
|
<a href="https://github.com/openimsdk/open-im-server/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=openimsdk/open-im-server" />
|
||||||
|
</a>
|
2
go.mod
2
go.mod
@ -5,7 +5,7 @@ go 1.19
|
|||||||
require (
|
require (
|
||||||
firebase.google.com/go v3.13.0+incompatible
|
firebase.google.com/go v3.13.0+incompatible
|
||||||
github.com/OpenIMSDK/protocol v0.0.55
|
github.com/OpenIMSDK/protocol v0.0.55
|
||||||
github.com/OpenIMSDK/tools v0.0.35
|
github.com/OpenIMSDK/tools v0.0.37
|
||||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||||
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
|
||||||
|
4
go.sum
4
go.sum
@ -20,8 +20,8 @@ github.com/IBM/sarama v1.42.2 h1:VoY4hVIZ+WQJ8G9KNY/SQlWguBQXQ9uvFPOnrcu8hEw=
|
|||||||
github.com/IBM/sarama v1.42.2/go.mod h1:FLPGUGwYqEs62hq2bVG6Io2+5n+pS6s/WOXVKWSLFtE=
|
github.com/IBM/sarama v1.42.2/go.mod h1:FLPGUGwYqEs62hq2bVG6Io2+5n+pS6s/WOXVKWSLFtE=
|
||||||
github.com/OpenIMSDK/protocol v0.0.55 h1:eBjg8DyuhxGmuCUjpoZjg6MJJJXU/xJ3xJwFhrn34yA=
|
github.com/OpenIMSDK/protocol v0.0.55 h1:eBjg8DyuhxGmuCUjpoZjg6MJJJXU/xJ3xJwFhrn34yA=
|
||||||
github.com/OpenIMSDK/protocol v0.0.55/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
github.com/OpenIMSDK/protocol v0.0.55/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||||
github.com/OpenIMSDK/tools v0.0.35 h1:YH8UYoaErXqfNrwpUvQxe8nhL++gFH6qCisQPyzk0w8=
|
github.com/OpenIMSDK/tools v0.0.37 h1:qvDqmA4RbEJtPjZouWCkVuf/pjm6Y8nUrG5iH2gcnOg=
|
||||||
github.com/OpenIMSDK/tools v0.0.35/go.mod h1:wBfR5CYmEyvxl03QJbTkhz1CluK6J4/lX0lviu8JAjE=
|
github.com/OpenIMSDK/tools v0.0.37/go.mod h1:wBfR5CYmEyvxl03QJbTkhz1CluK6J4/lX0lviu8JAjE=
|
||||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||||
|
1
go.work
1
go.work
@ -3,6 +3,7 @@ go 1.19
|
|||||||
use (
|
use (
|
||||||
.
|
.
|
||||||
./test/typecheck
|
./test/typecheck
|
||||||
|
./tools/codescan
|
||||||
./tools/changelog
|
./tools/changelog
|
||||||
./tools/component
|
./tools/component
|
||||||
./tools/data-conversion
|
./tools/data-conversion
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
############################## OpenIM Github ##############################
|
############################## OpenIM Github ##############################
|
||||||
# ... rest of the script ...
|
# ... rest of the script ...
|
||||||
|
@ -15,11 +15,9 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/auth"
|
"github.com/OpenIMSDK/protocol/auth"
|
||||||
"github.com/OpenIMSDK/tools/a2r"
|
"github.com/OpenIMSDK/tools/a2r"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,11 +15,9 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/conversation"
|
"github.com/OpenIMSDK/protocol/conversation"
|
||||||
"github.com/OpenIMSDK/tools/a2r"
|
"github.com/OpenIMSDK/tools/a2r"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,24 +15,20 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-playground/validator/v10"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RequiredIf validates if the specified field is required based on the session type.
|
||||||
func RequiredIf(fl validator.FieldLevel) bool {
|
func RequiredIf(fl validator.FieldLevel) bool {
|
||||||
sessionType := fl.Parent().FieldByName("SessionType").Int()
|
sessionType := fl.Parent().FieldByName("SessionType").Int()
|
||||||
|
|
||||||
switch sessionType {
|
switch sessionType {
|
||||||
case constant.SingleChatType, constant.NotificationChatType:
|
case constant.SingleChatType, constant.NotificationChatType:
|
||||||
if fl.FieldName() == "RecvID" {
|
return fl.FieldName() != "RecvID" || fl.Field().String() != ""
|
||||||
return fl.Field().String() != ""
|
|
||||||
}
|
|
||||||
case constant.GroupChatType, constant.SuperGroupChatType:
|
case constant.GroupChatType, constant.SuperGroupChatType:
|
||||||
if fl.FieldName() == "GroupID" {
|
return fl.FieldName() != "GroupID" || fl.Field().String() != ""
|
||||||
return fl.Field().String() != ""
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,8 @@ package api
|
|||||||
import (
|
import (
|
||||||
"github.com/OpenIMSDK/protocol/friend"
|
"github.com/OpenIMSDK/protocol/friend"
|
||||||
"github.com/OpenIMSDK/tools/a2r"
|
"github.com/OpenIMSDK/tools/a2r"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FriendApi rpcclient.Friend
|
type FriendApi rpcclient.Friend
|
||||||
|
@ -17,10 +17,8 @@ package api
|
|||||||
import (
|
import (
|
||||||
"github.com/OpenIMSDK/protocol/group"
|
"github.com/OpenIMSDK/protocol/group"
|
||||||
"github.com/OpenIMSDK/tools/a2r"
|
"github.com/OpenIMSDK/tools/a2r"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GroupApi rpcclient.Group
|
type GroupApi rpcclient.Group
|
||||||
|
@ -27,11 +27,9 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -200,7 +198,7 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user has the app manager role.
|
// Check if the user has the app manager role.
|
||||||
if !authverify.IsAppManagerUid(c) {
|
if !authverify.IsAppManagerUid(c, m.Config) {
|
||||||
// Respond with a permission error if the user is not an app manager.
|
// Respond with a permission error if the user is not an app manager.
|
||||||
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||||
return
|
return
|
||||||
@ -210,7 +208,6 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
|
|||||||
sendMsgReq, err := m.getSendMsgReq(c, req.SendMsg)
|
sendMsgReq, err := m.getSendMsgReq(c, req.SendMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Log and respond with an error if preparation fails.
|
// Log and respond with an error if preparation fails.
|
||||||
log.ZError(c, "decodeData failed", err)
|
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -226,7 +223,6 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// Set the status to failed and respond with an error if sending fails.
|
// Set the status to failed and respond with an error if sending fails.
|
||||||
status = constant.MsgSendFailed
|
status = constant.MsgSendFailed
|
||||||
log.ZError(c, "send message err", err)
|
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -240,7 +236,8 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Log the error if updating the status fails.
|
// Log the error if updating the status fails.
|
||||||
log.ZError(c, "SetSendMsgStatus failed", err)
|
apiresp.GinError(c, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Respond with a success message and the response payload.
|
// Respond with a success message and the response payload.
|
||||||
@ -259,7 +256,7 @@ func (m *MessageApi) SendBusinessNotification(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !authverify.IsAppManagerUid(c) {
|
if !authverify.IsAppManagerUid(c, m.Config) {
|
||||||
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -299,25 +296,22 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) {
|
|||||||
resp apistruct.BatchSendMsgResp
|
resp apistruct.BatchSendMsgResp
|
||||||
)
|
)
|
||||||
if err := c.BindJSON(&req); err != nil {
|
if err := c.BindJSON(&req); err != nil {
|
||||||
log.ZError(c, "BatchSendMsg BindJSON failed", err)
|
|
||||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.ZInfo(c, "BatchSendMsg", "req", req)
|
log.ZInfo(c, "BatchSendMsg", "req", req)
|
||||||
if err := authverify.CheckAdmin(c); err != nil {
|
if err := authverify.CheckAdmin(c, m.Config); err != nil {
|
||||||
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var recvIDs []string
|
var recvIDs []string
|
||||||
var err error
|
|
||||||
if req.IsSendAll {
|
if req.IsSendAll {
|
||||||
pageNumber := 1
|
pageNumber := 1
|
||||||
showNumber := 500
|
showNumber := 500
|
||||||
for {
|
for {
|
||||||
recvIDsPart, err := m.userRpcClient.GetAllUserIDs(c, int32(pageNumber), int32(showNumber))
|
recvIDsPart, err := m.userRpcClient.GetAllUserIDs(c, int32(pageNumber), int32(showNumber))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZError(c, "GetAllUserIDs failed", err)
|
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -333,7 +327,6 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) {
|
|||||||
log.ZDebug(c, "BatchSendMsg nums", "nums ", len(recvIDs))
|
log.ZDebug(c, "BatchSendMsg nums", "nums ", len(recvIDs))
|
||||||
sendMsgReq, err := m.getSendMsgReq(c, req.SendMsg)
|
sendMsgReq, err := m.getSendMsgReq(c, req.SendMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZError(c, "decodeData failed", err)
|
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -17,53 +17,138 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/tools/apiresp"
|
"github.com/OpenIMSDK/tools/apiresp"
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/mw"
|
||||||
"github.com/OpenIMSDK/tools/tokenverify"
|
"github.com/OpenIMSDK/tools/tokenverify"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
|
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
||||||
|
ginprom "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
"github.com/OpenIMSDK/tools/mw"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient) *gin.Engine {
|
func Start(config *config.GlobalConfig, port int, proPort int) error {
|
||||||
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin"))) // 默认RPC中间件
|
log.ZDebug(context.Background(), "configAPI1111111111111111111", config, "port", port, "javafdasfs")
|
||||||
|
if port == 0 || proPort == 0 {
|
||||||
|
err := "port or proPort is empty:" + strconv.Itoa(port) + "," + strconv.Itoa(proPort)
|
||||||
|
return errs.Wrap(fmt.Errorf(err))
|
||||||
|
}
|
||||||
|
rdb, err := cache.NewRedis(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var client discoveryregistry.SvcDiscoveryRegistry
|
||||||
|
|
||||||
|
// Determine whether zk is passed according to whether it is a clustered deployment
|
||||||
|
client, err = kdisc.NewDiscoveryRegister(config)
|
||||||
|
if err != nil {
|
||||||
|
return errs.Wrap(err, "register discovery err")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = client.CreateRpcRootNodes(config.GetServiceNames()); err != nil {
|
||||||
|
return errs.Wrap(err, "create rpc root nodes error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = client.RegisterConf2Registry(constant.OpenIMCommonConfigKey, config.EncodeConfig()); err != nil {
|
||||||
|
return errs.Wrap(err)
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
netDone = make(chan struct{}, 1)
|
||||||
|
netErr error
|
||||||
|
)
|
||||||
|
router := newGinRouter(client, rdb, config)
|
||||||
|
if config.Prometheus.Enable {
|
||||||
|
go func() {
|
||||||
|
p := ginprom.NewPrometheus("app", prommetrics.GetGinCusMetrics("Api"))
|
||||||
|
p.SetListenAddress(fmt.Sprintf(":%d", proPort))
|
||||||
|
if err = p.Use(router); err != nil && err != http.ErrServerClosed {
|
||||||
|
netErr = errs.Wrap(err, fmt.Sprintf("prometheus start err: %d", proPort))
|
||||||
|
netDone <- struct{}{}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var address string
|
||||||
|
if config.Api.ListenIP != "" {
|
||||||
|
address = net.JoinHostPort(config.Api.ListenIP, strconv.Itoa(port))
|
||||||
|
} else {
|
||||||
|
address = net.JoinHostPort("0.0.0.0", strconv.Itoa(port))
|
||||||
|
}
|
||||||
|
|
||||||
|
server := http.Server{Addr: address, Handler: router}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
err = server.ListenAndServe()
|
||||||
|
if err != nil && err != http.ErrServerClosed {
|
||||||
|
netErr = errs.Wrap(err, fmt.Sprintf("api start err: %s", server.Addr))
|
||||||
|
netDone <- struct{}{}
|
||||||
|
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
sigs := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigs, syscall.SIGTERM)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
select {
|
||||||
|
case <-sigs:
|
||||||
|
util.SIGTERMExit()
|
||||||
|
err := server.Shutdown(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return errs.Wrap(err, "shutdown err")
|
||||||
|
}
|
||||||
|
case <-netDone:
|
||||||
|
close(netDone)
|
||||||
|
return netErr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newGinRouter(disCov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient, config *config.GlobalConfig) *gin.Engine {
|
||||||
|
disCov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
r := gin.New()
|
r := gin.New()
|
||||||
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
||||||
_ = v.RegisterValidation("required_if", RequiredIf)
|
_ = v.RegisterValidation("required_if", RequiredIf)
|
||||||
}
|
}
|
||||||
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())
|
||||||
// init rpc client here
|
// init rpc client here
|
||||||
userRpc := rpcclient.NewUser(discov)
|
userRpc := rpcclient.NewUser(disCov, config)
|
||||||
groupRpc := rpcclient.NewGroup(discov)
|
groupRpc := rpcclient.NewGroup(disCov, config)
|
||||||
friendRpc := rpcclient.NewFriend(discov)
|
friendRpc := rpcclient.NewFriend(disCov, config)
|
||||||
messageRpc := rpcclient.NewMessage(discov)
|
messageRpc := rpcclient.NewMessage(disCov, config)
|
||||||
conversationRpc := rpcclient.NewConversation(discov)
|
conversationRpc := rpcclient.NewConversation(disCov, config)
|
||||||
authRpc := rpcclient.NewAuth(discov)
|
authRpc := rpcclient.NewAuth(disCov, config)
|
||||||
thirdRpc := rpcclient.NewThird(discov)
|
thirdRpc := rpcclient.NewThird(disCov, config)
|
||||||
|
|
||||||
u := NewUserApi(*userRpc)
|
u := NewUserApi(*userRpc)
|
||||||
m := NewMessageApi(messageRpc, userRpc)
|
m := NewMessageApi(messageRpc, userRpc)
|
||||||
ParseToken := GinParseToken(rdb)
|
ParseToken := GinParseToken(rdb, config)
|
||||||
userRouterGroup := r.Group("/user")
|
userRouterGroup := r.Group("/user")
|
||||||
{
|
{
|
||||||
userRouterGroup.POST("/user_register", u.UserRegister)
|
userRouterGroup.POST("/user_register", u.UserRegister)
|
||||||
@ -157,8 +242,8 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
// Third service
|
// Third service
|
||||||
thirdGroup := r.Group("/third", ParseToken)
|
thirdGroup := r.Group("/third", ParseToken)
|
||||||
{
|
{
|
||||||
thirdGroup.GET("/prometheus", GetPrometheus)
|
|
||||||
t := NewThirdApi(*thirdRpc)
|
t := NewThirdApi(*thirdRpc)
|
||||||
|
thirdGroup.GET("/prometheus", t.GetPrometheus)
|
||||||
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)
|
||||||
|
|
||||||
@ -225,11 +310,12 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func GinParseToken(rdb redis.UniversalClient) gin.HandlerFunc {
|
func GinParseToken(rdb redis.UniversalClient, config *config.GlobalConfig) gin.HandlerFunc {
|
||||||
dataBase := controller.NewAuthDatabase(
|
dataBase := controller.NewAuthDatabase(
|
||||||
cache.NewMsgCacheModel(rdb),
|
cache.NewMsgCacheModel(rdb, config),
|
||||||
config.Config.Secret,
|
config.Secret,
|
||||||
config.Config.TokenPolicy.Expire,
|
config.TokenPolicy.Expire,
|
||||||
|
config,
|
||||||
)
|
)
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
switch c.Request.Method {
|
switch c.Request.Method {
|
||||||
@ -241,7 +327,7 @@ func GinParseToken(rdb redis.UniversalClient) gin.HandlerFunc {
|
|||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
claims, err := tokenverify.GetClaimFromToken(token, authverify.Secret())
|
claims, err := tokenverify.GetClaimFromToken(token, authverify.Secret(config.Secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(c, "jwt get token error", errs.ErrTokenUnknown.Wrap())
|
log.ZWarn(c, "jwt get token error", errs.ErrTokenUnknown.Wrap())
|
||||||
apiresp.GinError(c, errs.ErrTokenUnknown.Wrap())
|
apiresp.GinError(c, errs.ErrTokenUnknown.Wrap())
|
||||||
@ -250,13 +336,11 @@ func GinParseToken(rdb redis.UniversalClient) gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
m, err := dataBase.GetTokensWithoutError(c, claims.UserID, claims.PlatformID)
|
m, err := dataBase.GetTokensWithoutError(c, claims.UserID, claims.PlatformID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(c, "cache get token error", errs.ErrTokenNotExist.Wrap())
|
|
||||||
apiresp.GinError(c, errs.ErrTokenNotExist.Wrap())
|
apiresp.GinError(c, errs.ErrTokenNotExist.Wrap())
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(m) == 0 {
|
if len(m) == 0 {
|
||||||
log.ZWarn(c, "cache do not exist token error", errs.ErrTokenNotExist.Wrap())
|
|
||||||
apiresp.GinError(c, errs.ErrTokenNotExist.Wrap())
|
apiresp.GinError(c, errs.ErrTokenNotExist.Wrap())
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
@ -265,12 +349,10 @@ func GinParseToken(rdb redis.UniversalClient) gin.HandlerFunc {
|
|||||||
switch v {
|
switch v {
|
||||||
case constant.NormalToken:
|
case constant.NormalToken:
|
||||||
case constant.KickedToken:
|
case constant.KickedToken:
|
||||||
log.ZWarn(c, "cache kicked token error", errs.ErrTokenKicked.Wrap())
|
|
||||||
apiresp.GinError(c, errs.ErrTokenKicked.Wrap())
|
apiresp.GinError(c, errs.ErrTokenKicked.Wrap())
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
log.ZWarn(c, "cache unknown token error", errs.ErrTokenUnknown.Wrap())
|
|
||||||
apiresp.GinError(c, errs.ErrTokenUnknown.Wrap())
|
apiresp.GinError(c, errs.ErrTokenUnknown.Wrap())
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
@ -286,3 +368,10 @@ func GinParseToken(rdb redis.UniversalClient) gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // handleGinError logs and returns an error response through Gin context.
|
||||||
|
// func handleGinError(c *gin.Context, logMessage string, errType errs.CodeError, detail string) {
|
||||||
|
// wrappedErr := errType.Wrap(detail)
|
||||||
|
// apiresp.GinError(c, wrappedErr)
|
||||||
|
// c.Abort()
|
||||||
|
// }
|
||||||
|
@ -15,11 +15,9 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/user"
|
"github.com/OpenIMSDK/protocol/user"
|
||||||
"github.com/OpenIMSDK/tools/a2r"
|
"github.com/OpenIMSDK/tools/a2r"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,15 +19,11 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/third"
|
"github.com/OpenIMSDK/protocol/third"
|
||||||
"github.com/OpenIMSDK/tools/a2r"
|
"github.com/OpenIMSDK/tools/a2r"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -129,6 +125,6 @@ func (o *ThirdApi) SearchLogs(c *gin.Context) {
|
|||||||
a2r.Call(third.ThirdClient.SearchLogs, o.Client, c)
|
a2r.Call(third.ThirdClient.SearchLogs, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPrometheus(c *gin.Context) {
|
func (o *ThirdApi) GetPrometheus(c *gin.Context) {
|
||||||
c.Redirect(http.StatusFound, config2.Config.Prometheus.GrafanaUrl)
|
c.Redirect(http.StatusFound, o.Config.Prometheus.GrafanaUrl)
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,6 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -68,10 +66,10 @@ func (u *UserApi) GetUsers(c *gin.Context) {
|
|||||||
func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
|
func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
|
||||||
var req msggateway.GetUsersOnlineStatusReq
|
var req msggateway.GetUsersOnlineStatusReq
|
||||||
if err := c.BindJSON(&req); err != nil {
|
if err := c.BindJSON(&req); err != nil {
|
||||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conns, err := u.Discov.GetConns(c, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := u.Discov.GetConns(c, u.Config.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
@ -86,7 +84,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
|
|||||||
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.ZDebug(c, "GetUsersOnlineStatus rpc error", err)
|
||||||
|
|
||||||
parseError := apiresp.ParseError(err)
|
parseError := apiresp.ParseError(err)
|
||||||
if parseError.ErrCode == errs.NoPermissionError {
|
if parseError.ErrCode == errs.NoPermissionError {
|
||||||
@ -135,7 +133,7 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
|
|||||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conns, err := u.Discov.GetConns(c, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := u.Discov.GetConns(c, u.Config.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
@ -145,7 +143,7 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
|
|||||||
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...)
|
||||||
|
@ -20,18 +20,13 @@ import (
|
|||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
|
|
||||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func callBackURL() string {
|
func CallbackUserOnline(ctx context.Context, globalConfig *config.GlobalConfig, userID string, platformID int, isAppBackground bool, connID string) error {
|
||||||
return config.Config.Callback.CallbackUrl
|
if !globalConfig.Callback.CallbackUserOnline.Enable {
|
||||||
}
|
|
||||||
|
|
||||||
func CallbackUserOnline(ctx context.Context, userID string, platformID int, isAppBackground bool, connID string) error {
|
|
||||||
if !config.Config.Callback.CallbackUserOnline.Enable {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := cbapi.CallbackUserOnlineReq{
|
req := cbapi.CallbackUserOnlineReq{
|
||||||
@ -49,14 +44,14 @@ func CallbackUserOnline(ctx context.Context, userID string, platformID int, isAp
|
|||||||
ConnID: connID,
|
ConnID: connID,
|
||||||
}
|
}
|
||||||
resp := cbapi.CommonCallbackResp{}
|
resp := cbapi.CommonCallbackResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, callBackURL(), &req, &resp, config.Config.Callback.CallbackUserOnline); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, &req, &resp, globalConfig.Callback.CallbackUserOnline); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackUserOffline(ctx context.Context, userID string, platformID int, connID string) error {
|
func CallbackUserOffline(ctx context.Context, globalConfig *config.GlobalConfig, userID string, platformID int, connID string) error {
|
||||||
if !config.Config.Callback.CallbackUserOffline.Enable {
|
if !globalConfig.Callback.CallbackUserOffline.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackUserOfflineReq{
|
req := &cbapi.CallbackUserOfflineReq{
|
||||||
@ -73,14 +68,14 @@ func CallbackUserOffline(ctx context.Context, userID string, platformID int, con
|
|||||||
ConnID: connID,
|
ConnID: connID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackUserOfflineResp{}
|
resp := &cbapi.CallbackUserOfflineResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, callBackURL(), req, resp, config.Config.Callback.CallbackUserOffline); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackUserOffline); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackUserKickOff(ctx context.Context, userID string, platformID int) error {
|
func CallbackUserKickOff(ctx context.Context, globalConfig *config.GlobalConfig, userID string, platformID int) error {
|
||||||
if !config.Config.Callback.CallbackUserKickOff.Enable {
|
if !globalConfig.Callback.CallbackUserKickOff.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackUserKickOffReq{
|
req := &cbapi.CallbackUserKickOffReq{
|
||||||
@ -96,7 +91,7 @@ func CallbackUserKickOff(ctx context.Context, userID string, platformID int) err
|
|||||||
Seq: time.Now().UnixMilli(),
|
Seq: time.Now().UnixMilli(),
|
||||||
}
|
}
|
||||||
resp := &cbapi.CommonCallbackResp{}
|
resp := &cbapi.CommonCallbackResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, callBackURL(), req, resp, config.Config.Callback.CallbackUserOffline); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackUserOffline); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -22,16 +22,15 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/apiresp"
|
"github.com/OpenIMSDK/tools/apiresp"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -76,25 +75,20 @@ type Client struct {
|
|||||||
token string
|
token string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newClient(ctx *UserConnContext, conn LongConn, isCompress bool) *Client {
|
// function not used
|
||||||
return &Client{
|
// func newClient(ctx *UserConnContext, conn LongConn, isCompress bool) *Client {
|
||||||
w: new(sync.Mutex),
|
// return &Client{
|
||||||
conn: conn,
|
// w: new(sync.Mutex),
|
||||||
PlatformID: utils.StringToInt(ctx.GetPlatformID()),
|
// conn: conn,
|
||||||
IsCompress: isCompress,
|
// PlatformID: utils.StringToInt(ctx.GetPlatformID()),
|
||||||
UserID: ctx.GetUserID(),
|
// IsCompress: isCompress,
|
||||||
ctx: ctx,
|
// UserID: ctx.GetUserID(),
|
||||||
}
|
// ctx: ctx,
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// ResetClient updates the client's state with new connection and context information.
|
// ResetClient updates the client's state with new connection and context information.
|
||||||
func (c *Client) ResetClient(
|
func (c *Client) ResetClient(ctx *UserConnContext, conn LongConn, isBackground, isCompress bool, longConnServer LongConnServer, token string) {
|
||||||
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())
|
||||||
@ -109,9 +103,11 @@ func (c *Client) ResetClient(
|
|||||||
c.token = token
|
c.token = token
|
||||||
}
|
}
|
||||||
|
|
||||||
// pingHandler handles ping messages and sends pong responses.
|
|
||||||
func (c *Client) pingHandler(_ string) error {
|
func (c *Client) pingHandler(_ string) error {
|
||||||
_ = c.conn.SetReadDeadline(pongWait)
|
if err := c.conn.SetReadDeadline(pongWait); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return c.writePongMsg()
|
return c.writePongMsg()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +134,8 @@ func (c *Client) readMessage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.ZDebug(c.ctx, "readMessage", "messageType", messageType)
|
log.ZDebug(c.ctx, "readMessage", "messageType", messageType)
|
||||||
if c.closed.Load() { // 连接刚置位已经关闭,但是协程还没退出的场景
|
if c.closed.Load() {
|
||||||
|
// The scenario where the connection has just been closed, but the coroutine has not exited
|
||||||
c.closedErr = ErrConnClosed
|
c.closedErr = ErrConnClosed
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -173,7 +170,7 @@ func (c *Client) handleMessage(message []byte) error {
|
|||||||
var err error
|
var err error
|
||||||
message, err = c.longConnServer.DecompressWithPool(message)
|
message, err = c.longConnServer.DecompressWithPool(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.Wrap(err, "")
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,15 +179,15 @@ func (c *Client) handleMessage(message []byte) error {
|
|||||||
|
|
||||||
err := c.longConnServer.Decode(message, binaryReq)
|
err := c.longConnServer.Decode(message, binaryReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.Wrap(err, "")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.longConnServer.Validate(binaryReq); err != nil {
|
if err := c.longConnServer.Validate(binaryReq); err != nil {
|
||||||
return utils.Wrap(err, "")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
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 errs.Wrap(errors.New("exception conn userID not same to req userID"), binaryReq.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := mcontext.WithMustInfoCtx(
|
ctx := mcontext.WithMustInfoCtx(
|
||||||
@ -236,7 +233,7 @@ func (c *Client) setAppBackgroundStatus(ctx context.Context, req *Req) ([]byte,
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.IsBackground = isBackground
|
c.IsBackground = isBackground
|
||||||
// todo callback
|
// TODO: callback
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +267,7 @@ func (c *Client) replyMessage(ctx context.Context, binaryReq *Req, err error, re
|
|||||||
}
|
}
|
||||||
|
|
||||||
if binaryReq.ReqIdentifier == WsLogoutMsg {
|
if binaryReq.ReqIdentifier == WsLogoutMsg {
|
||||||
return errors.New("user logout")
|
return errs.Wrap(errors.New("user logout"))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -313,17 +310,21 @@ func (c *Client) writeBinaryMsg(resp Resp) error {
|
|||||||
|
|
||||||
encodedBuf, err := c.longConnServer.Encode(resp)
|
encodedBuf, err := c.longConnServer.Encode(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.Wrap(err, "")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.w.Lock()
|
c.w.Lock()
|
||||||
defer c.w.Unlock()
|
defer c.w.Unlock()
|
||||||
|
|
||||||
_ = c.conn.SetWriteDeadline(writeWait)
|
err = c.conn.SetWriteDeadline(writeWait)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if c.IsCompress {
|
if c.IsCompress {
|
||||||
resultBuf, compressErr := c.longConnServer.CompressWithPool(encodedBuf)
|
resultBuf, compressErr := c.longConnServer.CompressWithPool(encodedBuf)
|
||||||
if compressErr != nil {
|
if compressErr != nil {
|
||||||
return utils.Wrap(compressErr, "")
|
return compressErr
|
||||||
}
|
}
|
||||||
return c.conn.WriteMessage(MessageBinary, resultBuf)
|
return c.conn.WriteMessage(MessageBinary, resultBuf)
|
||||||
}
|
}
|
||||||
@ -341,7 +342,7 @@ func (c *Client) writePongMsg() error {
|
|||||||
|
|
||||||
err := c.conn.SetWriteDeadline(writeWait)
|
err := c.conn.SetWriteDeadline(writeWait)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.Wrap(err, "")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.conn.WriteMessage(PongMessage, nil)
|
return c.conn.WriteMessage(PongMessage, nil)
|
||||||
|
@ -17,11 +17,10 @@ package msggateway
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"errors"
|
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -46,12 +45,15 @@ func NewGzipCompressor() *GzipCompressor {
|
|||||||
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)
|
||||||
|
|
||||||
if _, err := gz.Write(rawData); err != nil {
|
if _, err := gz.Write(rawData); err != nil {
|
||||||
return nil, utils.Wrap(err, "")
|
return nil, errs.Wrap(err, "GzipCompressor.Compress: writing to gzip writer failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gz.Close(); err != nil {
|
if err := gz.Close(); err != nil {
|
||||||
return nil, utils.Wrap(err, "")
|
return nil, errs.Wrap(err, "GzipCompressor.Compress: closing gzip writer failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return gzipBuffer.Bytes(), nil
|
return gzipBuffer.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,10 +65,10 @@ func (g *GzipCompressor) CompressWithPool(rawData []byte) ([]byte, error) {
|
|||||||
gz.Reset(&gzipBuffer)
|
gz.Reset(&gzipBuffer)
|
||||||
|
|
||||||
if _, err := gz.Write(rawData); err != nil {
|
if _, err := gz.Write(rawData); err != nil {
|
||||||
return nil, utils.Wrap(err, "")
|
return nil, errs.Wrap(err, "GzipCompressor.CompressWithPool: error writing data")
|
||||||
}
|
}
|
||||||
if err := gz.Close(); err != nil {
|
if err := gz.Close(); err != nil {
|
||||||
return nil, utils.Wrap(err, "")
|
return nil, errs.Wrap(err, "GzipCompressor.CompressWithPool: error closing gzip writer")
|
||||||
}
|
}
|
||||||
return gzipBuffer.Bytes(), nil
|
return gzipBuffer.Bytes(), nil
|
||||||
}
|
}
|
||||||
@ -75,32 +77,36 @@ func (g *GzipCompressor) DeCompress(compressedData []byte) ([]byte, error) {
|
|||||||
buff := bytes.NewBuffer(compressedData)
|
buff := bytes.NewBuffer(compressedData)
|
||||||
reader, err := gzip.NewReader(buff)
|
reader, err := gzip.NewReader(buff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, utils.Wrap(err, "NewReader failed")
|
return nil, errs.Wrap(err, "GzipCompressor.DeCompress: NewReader creation failed")
|
||||||
}
|
}
|
||||||
compressedData, err = io.ReadAll(reader)
|
decompressedData, err := io.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, utils.Wrap(err, "ReadAll failed")
|
return nil, errs.Wrap(err, "GzipCompressor.DeCompress: reading from gzip reader failed")
|
||||||
}
|
}
|
||||||
_ = reader.Close()
|
if err = reader.Close(); err != nil {
|
||||||
return compressedData, nil
|
// Even if closing the reader fails, we've successfully read the data,
|
||||||
|
// so we return the decompressed data and an error indicating the close failure.
|
||||||
|
return decompressedData, errs.Wrap(err, "GzipCompressor.DeCompress: closing gzip reader failed")
|
||||||
|
}
|
||||||
|
return decompressedData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GzipCompressor) DecompressWithPool(compressedData []byte) ([]byte, error) {
|
func (g *GzipCompressor) DecompressWithPool(compressedData []byte) ([]byte, error) {
|
||||||
reader := gzipReaderPool.Get().(*gzip.Reader)
|
reader := gzipReaderPool.Get().(*gzip.Reader)
|
||||||
if reader == nil {
|
|
||||||
return nil, errors.New("NewReader failed")
|
|
||||||
}
|
|
||||||
defer gzipReaderPool.Put(reader)
|
defer gzipReaderPool.Put(reader)
|
||||||
|
|
||||||
err := reader.Reset(bytes.NewReader(compressedData))
|
err := reader.Reset(bytes.NewReader(compressedData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, utils.Wrap(err, "NewReader failed")
|
return nil, errs.Wrap(err, "GzipCompressor.DecompressWithPool: resetting gzip reader failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
compressedData, err = io.ReadAll(reader)
|
decompressedData, err := io.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, utils.Wrap(err, "ReadAll failed")
|
return nil, errs.Wrap(err, "GzipCompressor.DecompressWithPool: reading from pooled gzip reader failed")
|
||||||
}
|
}
|
||||||
_ = reader.Close()
|
if err = reader.Close(); err != nil {
|
||||||
return compressedData, nil
|
// Similar to DeCompress, return the data and error for close failure.
|
||||||
|
return decompressedData, errs.Wrap(err, "GzipCompressor.DecompressWithPool: closing pooled gzip reader failed")
|
||||||
|
}
|
||||||
|
return decompressedData, nil
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,16 @@ func TestCompressDecompress(t *testing.T) {
|
|||||||
|
|
||||||
// compress
|
// compress
|
||||||
dest, err := compressor.CompressWithPool(src)
|
dest, err := compressor.CompressWithPool(src)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
res, err := compressor.DecompressWithPool(dest)
|
res, err := compressor.DecompressWithPool(dest)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
|
|
||||||
// check
|
// check
|
||||||
@ -60,10 +66,16 @@ func TestCompressDecompressWithConcurrency(t *testing.T) {
|
|||||||
|
|
||||||
// compress
|
// compress
|
||||||
dest, err := compressor.CompressWithPool(src)
|
dest, err := compressor.CompressWithPool(src)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
res, err := compressor.DecompressWithPool(dest)
|
res, err := compressor.DecompressWithPool(dest)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
|
|
||||||
// check
|
// check
|
||||||
@ -99,6 +111,7 @@ func BenchmarkDecompress(b *testing.B) {
|
|||||||
|
|
||||||
compressor := NewGzipCompressor()
|
compressor := NewGzipCompressor()
|
||||||
comdata, err := compressor.Compress(src)
|
comdata, err := compressor.Compress(src)
|
||||||
|
|
||||||
assert.Equal(b, nil, err)
|
assert.Equal(b, nil, err)
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Encoder interface {
|
type Encoder interface {
|
||||||
@ -37,7 +37,7 @@ func (g *GobEncoder) Encode(data any) ([]byte, error) {
|
|||||||
enc := gob.NewEncoder(&buff)
|
enc := gob.NewEncoder(&buff)
|
||||||
err := enc.Encode(data)
|
err := enc.Encode(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "GobEncoder.Encode failed")
|
||||||
}
|
}
|
||||||
return buff.Bytes(), nil
|
return buff.Bytes(), nil
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ func (g *GobEncoder) Decode(encodeData []byte, decodeData any) error {
|
|||||||
dec := gob.NewDecoder(buff)
|
dec := gob.NewDecoder(buff)
|
||||||
err := dec.Decode(decodeData)
|
err := dec.Decode(decodeData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.Wrap(err, "")
|
return errs.Wrap(err, "GobEncoder.Decode failed")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,6 @@ package msggateway
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/msggateway"
|
"github.com/OpenIMSDK/protocol/msggateway"
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
@ -26,31 +24,32 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) InitServer(disCov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func (s *Server) InitServer(config *config.GlobalConfig, disCov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
msgModel := cache.NewMsgCacheModel(rdb)
|
msgModel := cache.NewMsgCacheModel(rdb, config)
|
||||||
s.LongConnServer.SetDiscoveryRegistry(disCov)
|
s.LongConnServer.SetDiscoveryRegistry(disCov, config)
|
||||||
s.LongConnServer.SetCacheHandler(msgModel)
|
s.LongConnServer.SetCacheHandler(msgModel)
|
||||||
msggateway.RegisterMsgGatewayServer(server, s)
|
msggateway.RegisterMsgGatewayServer(server, s)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Start() error {
|
func (s *Server) Start(conf *config.GlobalConfig) error {
|
||||||
return startrpc.Start(
|
return startrpc.Start(
|
||||||
s.rpcPort,
|
s.rpcPort,
|
||||||
config.Config.RpcRegisterName.OpenImMessageGatewayName,
|
conf.RpcRegisterName.OpenImMessageGatewayName,
|
||||||
s.prometheusPort,
|
s.prometheusPort,
|
||||||
|
conf,
|
||||||
s.InitServer,
|
s.InitServer,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -60,18 +59,20 @@ type Server struct {
|
|||||||
prometheusPort int
|
prometheusPort int
|
||||||
LongConnServer LongConnServer
|
LongConnServer LongConnServer
|
||||||
pushTerminal []int
|
pushTerminal []int
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) SetLongConnServer(LongConnServer LongConnServer) {
|
func (s *Server) SetLongConnServer(LongConnServer LongConnServer) {
|
||||||
s.LongConnServer = LongConnServer
|
s.LongConnServer = LongConnServer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(rpcPort int, proPort int, longConnServer LongConnServer) *Server {
|
func NewServer(rpcPort int, proPort int, longConnServer LongConnServer, config *config.GlobalConfig) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
rpcPort: rpcPort,
|
rpcPort: rpcPort,
|
||||||
prometheusPort: proPort,
|
prometheusPort: proPort,
|
||||||
LongConnServer: longConnServer,
|
LongConnServer: longConnServer,
|
||||||
pushTerminal: []int{constant.IOSPlatformID, constant.AndroidPlatformID},
|
pushTerminal: []int{constant.IOSPlatformID, constant.AndroidPlatformID},
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ func (s *Server) GetUsersOnlineStatus(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *msggateway.GetUsersOnlineStatusReq,
|
req *msggateway.GetUsersOnlineStatusReq,
|
||||||
) (*msggateway.GetUsersOnlineStatusResp, error) {
|
) (*msggateway.GetUsersOnlineStatusResp, error) {
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
return nil, errs.ErrNoPermission.Wrap("only app manager")
|
return nil, errs.ErrNoPermission.Wrap("only app manager")
|
||||||
}
|
}
|
||||||
var resp msggateway.GetUsersOnlineStatusResp
|
var resp msggateway.GetUsersOnlineStatusResp
|
||||||
|
@ -22,33 +22,25 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// RunWsAndServer run ws server.
|
// RunWsAndServer run ws server.
|
||||||
func RunWsAndServer(rpcPort, wsPort, prometheusPort int) error {
|
func RunWsAndServer(conf *config.GlobalConfig, rpcPort, wsPort, prometheusPort int) error {
|
||||||
fmt.Println(
|
fmt.Println("start rpc/msg_gateway server, port: ", rpcPort, wsPort, prometheusPort, ", OpenIM version: ", config.Version)
|
||||||
"start rpc/msg_gateway server, port: ",
|
|
||||||
rpcPort,
|
|
||||||
wsPort,
|
|
||||||
prometheusPort,
|
|
||||||
", OpenIM version: ",
|
|
||||||
config.Version,
|
|
||||||
)
|
|
||||||
longServer, err := NewWsServer(
|
longServer, err := NewWsServer(
|
||||||
|
conf,
|
||||||
WithPort(wsPort),
|
WithPort(wsPort),
|
||||||
WithMaxConnNum(int64(config.Config.LongConnSvr.WebsocketMaxConnNum)),
|
WithMaxConnNum(int64(conf.LongConnSvr.WebsocketMaxConnNum)),
|
||||||
WithHandshakeTimeout(time.Duration(config.Config.LongConnSvr.WebsocketTimeout)*time.Second),
|
WithHandshakeTimeout(time.Duration(conf.LongConnSvr.WebsocketTimeout)*time.Second),
|
||||||
WithMessageMaxMsgLength(config.Config.LongConnSvr.WebsocketMaxMsgLen),
|
WithMessageMaxMsgLength(conf.LongConnSvr.WebsocketMaxMsgLen),
|
||||||
WithWriteBufferSize(config.Config.LongConnSvr.WebsocketWriteBufferSize),
|
WithWriteBufferSize(conf.LongConnSvr.WebsocketWriteBufferSize),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
hubServer := NewServer(rpcPort, prometheusPort, longServer)
|
hubServer := NewServer(rpcPort, prometheusPort, longServer, conf)
|
||||||
netDone := make(chan error)
|
netDone := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
err = hubServer.Start()
|
err = hubServer.Start(conf)
|
||||||
if err != nil {
|
netDone <- err
|
||||||
netDone <- err
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
return hubServer.LongConnServer.Run(netDone)
|
return hubServer.LongConnServer.Run(netDone)
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
package msggateway
|
package msggateway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -72,7 +74,8 @@ func (d *GWebSocket) GenerateLongConn(w http.ResponseWriter, r *http.Request) er
|
|||||||
|
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
// The upgrader.Upgrade method usually returns enough error messages to diagnose problems that may occur during the upgrade
|
||||||
|
return errs.Wrap(err, "GenerateLongConn: WebSocket upgrade failed")
|
||||||
}
|
}
|
||||||
d.conn = conn
|
d.conn = conn
|
||||||
return nil
|
return nil
|
||||||
@ -96,7 +99,16 @@ func (d *GWebSocket) SetReadDeadline(timeout time.Duration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *GWebSocket) SetWriteDeadline(timeout time.Duration) error {
|
func (d *GWebSocket) SetWriteDeadline(timeout time.Duration) error {
|
||||||
return d.conn.SetWriteDeadline(time.Now().Add(timeout))
|
// TODO add error
|
||||||
|
if timeout <= 0 {
|
||||||
|
return errs.Wrap(errors.New("timeout must be greater than 0"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO SetWriteDeadline Future add error handling
|
||||||
|
if err := d.conn.SetWriteDeadline(time.Now().Add(timeout)); err != nil {
|
||||||
|
return errs.Wrap(err, "GWebSocket.SetWriteDeadline failed")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *GWebSocket) Dial(urlStr string, requestHeader http.Header) (*http.Response, error) {
|
func (d *GWebSocket) Dial(urlStr string, requestHeader http.Header) (*http.Response, error) {
|
||||||
@ -108,10 +120,12 @@ func (d *GWebSocket) Dial(urlStr string, requestHeader http.Header) (*http.Respo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *GWebSocket) IsNil() bool {
|
func (d *GWebSocket) IsNil() bool {
|
||||||
if d.conn != nil {
|
return d.conn == nil
|
||||||
return false
|
//
|
||||||
}
|
// if d.conn != nil {
|
||||||
return true
|
// return false
|
||||||
|
// }
|
||||||
|
// return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *GWebSocket) SetConnNil() {
|
func (d *GWebSocket) SetConnNil() {
|
||||||
|
@ -18,17 +18,16 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/push"
|
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
|
|
||||||
"github.com/go-playground/validator/v10"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
|
"github.com/OpenIMSDK/protocol/push"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Req struct {
|
type Req struct {
|
||||||
@ -107,9 +106,9 @@ type GrpcHandler struct {
|
|||||||
validate *validator.Validate
|
validate *validator.Validate
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGrpcHandler(validate *validator.Validate, client discoveryregistry.SvcDiscoveryRegistry) *GrpcHandler {
|
func NewGrpcHandler(validate *validator.Validate, client discoveryregistry.SvcDiscoveryRegistry, config *config.GlobalConfig) *GrpcHandler {
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
pushRpcClient := rpcclient.NewPushRpcClient(client)
|
pushRpcClient := rpcclient.NewPushRpcClient(client, config)
|
||||||
return &GrpcHandler{
|
return &GrpcHandler{
|
||||||
msgRpcClient: &msgRpcClient,
|
msgRpcClient: &msgRpcClient,
|
||||||
pushClient: &pushRpcClient, validate: validate,
|
pushClient: &pushRpcClient, validate: validate,
|
||||||
@ -119,10 +118,10 @@ func NewGrpcHandler(validate *validator.Validate, client discoveryregistry.SvcDi
|
|||||||
func (g GrpcHandler) GetSeq(context context.Context, data *Req) ([]byte, error) {
|
func (g GrpcHandler) GetSeq(context context.Context, data *Req) ([]byte, error) {
|
||||||
req := sdkws.GetMaxSeqReq{}
|
req := sdkws.GetMaxSeqReq{}
|
||||||
if err := proto.Unmarshal(data.Data, &req); err != nil {
|
if err := proto.Unmarshal(data.Data, &req); err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "GetSeq: error unmarshaling request")
|
||||||
}
|
}
|
||||||
if err := g.validate.Struct(&req); err != nil {
|
if err := g.validate.Struct(&req); err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "GetSeq: validation failed")
|
||||||
}
|
}
|
||||||
resp, err := g.msgRpcClient.GetMaxSeq(context, &req)
|
resp, err := g.msgRpcClient.GetMaxSeq(context, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -130,28 +129,37 @@ func (g GrpcHandler) GetSeq(context context.Context, data *Req) ([]byte, error)
|
|||||||
}
|
}
|
||||||
c, err := proto.Marshal(resp)
|
c, err := proto.Marshal(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "GetSeq: error marshaling response")
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g GrpcHandler) SendMessage(context context.Context, data *Req) ([]byte, error) {
|
// SendMessage handles the sending of messages through gRPC. It unmarshals the request data,
|
||||||
msgData := sdkws.MsgData{}
|
// validates the message, and then sends it using the message RPC client.
|
||||||
|
func (g GrpcHandler) SendMessage(ctx context.Context, data *Req) ([]byte, error) {
|
||||||
|
// Unmarshal the message data from the request.
|
||||||
|
var msgData sdkws.MsgData
|
||||||
if err := proto.Unmarshal(data.Data, &msgData); err != nil {
|
if err := proto.Unmarshal(data.Data, &msgData); err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "error unmarshalling message data")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate the message data structure.
|
||||||
if err := g.validate.Struct(&msgData); err != nil {
|
if err := g.validate.Struct(&msgData); err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "message data validation failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
req := msg.SendMsgReq{MsgData: &msgData}
|
req := msg.SendMsgReq{MsgData: &msgData}
|
||||||
resp, err := g.msgRpcClient.SendMsg(context, &req)
|
|
||||||
|
resp, err := g.msgRpcClient.SendMsg(ctx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := proto.Marshal(resp)
|
c, err := proto.Marshal(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "error marshaling response")
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +170,7 @@ func (g GrpcHandler) SendSignalMessage(context context.Context, data *Req) ([]by
|
|||||||
}
|
}
|
||||||
c, err := proto.Marshal(resp)
|
c, err := proto.Marshal(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "error marshaling response")
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
@ -170,10 +178,10 @@ func (g GrpcHandler) SendSignalMessage(context context.Context, data *Req) ([]by
|
|||||||
func (g GrpcHandler) PullMessageBySeqList(context context.Context, data *Req) ([]byte, error) {
|
func (g GrpcHandler) PullMessageBySeqList(context context.Context, data *Req) ([]byte, error) {
|
||||||
req := sdkws.PullMessageBySeqsReq{}
|
req := sdkws.PullMessageBySeqsReq{}
|
||||||
if err := proto.Unmarshal(data.Data, &req); err != nil {
|
if err := proto.Unmarshal(data.Data, &req); err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "error unmarshaling request")
|
||||||
}
|
}
|
||||||
if err := g.validate.Struct(data); err != nil {
|
if err := g.validate.Struct(data); err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "validation failed")
|
||||||
}
|
}
|
||||||
resp, err := g.msgRpcClient.PullMessageBySeqList(context, &req)
|
resp, err := g.msgRpcClient.PullMessageBySeqList(context, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -181,7 +189,7 @@ func (g GrpcHandler) PullMessageBySeqList(context context.Context, data *Req) ([
|
|||||||
}
|
}
|
||||||
c, err := proto.Marshal(resp)
|
c, err := proto.Marshal(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "error marshaling response")
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
@ -189,7 +197,7 @@ func (g GrpcHandler) PullMessageBySeqList(context context.Context, data *Req) ([
|
|||||||
func (g GrpcHandler) UserLogout(context context.Context, data *Req) ([]byte, error) {
|
func (g GrpcHandler) UserLogout(context context.Context, data *Req) ([]byte, error) {
|
||||||
req := push.DelUserPushTokenReq{}
|
req := push.DelUserPushTokenReq{}
|
||||||
if err := proto.Unmarshal(data.Data, &req); err != nil {
|
if err := proto.Unmarshal(data.Data, &req); err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "error unmarshaling request")
|
||||||
}
|
}
|
||||||
resp, err := g.pushClient.DelUserPushToken(context, &req)
|
resp, err := g.pushClient.DelUserPushToken(context, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -197,7 +205,7 @@ func (g GrpcHandler) UserLogout(context context.Context, data *Req) ([]byte, err
|
|||||||
}
|
}
|
||||||
c, err := proto.Marshal(resp)
|
c, err := proto.Marshal(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "error marshaling response")
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
@ -205,10 +213,10 @@ func (g GrpcHandler) UserLogout(context context.Context, data *Req) ([]byte, err
|
|||||||
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 {
|
||||||
return nil, false, err
|
return nil, false, errs.Wrap(err, "error unmarshaling request")
|
||||||
}
|
}
|
||||||
if err := g.validate.Struct(data); err != nil {
|
if err := g.validate.Struct(data); err != nil {
|
||||||
return nil, false, err
|
return nil, false, errs.Wrap(err, "validation failed")
|
||||||
}
|
}
|
||||||
return nil, req.IsBackground, nil
|
return nil, req.IsBackground, nil
|
||||||
}
|
}
|
||||||
|
@ -25,24 +25,21 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/apiresp"
|
|
||||||
|
|
||||||
"github.com/go-playground/validator/v10"
|
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/msggateway"
|
"github.com/OpenIMSDK/protocol/msggateway"
|
||||||
|
"github.com/OpenIMSDK/tools/apiresp"
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LongConnServer interface {
|
type LongConnServer interface {
|
||||||
@ -52,7 +49,7 @@ type LongConnServer interface {
|
|||||||
GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool)
|
GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool)
|
||||||
Validate(s any) error
|
Validate(s any) error
|
||||||
SetCacheHandler(cache cache.MsgModel)
|
SetCacheHandler(cache cache.MsgModel)
|
||||||
SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry)
|
SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry, config *config.GlobalConfig)
|
||||||
KickUserConn(client *Client) error
|
KickUserConn(client *Client) error
|
||||||
UnRegister(c *Client)
|
UnRegister(c *Client)
|
||||||
SetKickHandlerInfo(i *kickHandler)
|
SetKickHandlerInfo(i *kickHandler)
|
||||||
@ -61,13 +58,15 @@ type LongConnServer interface {
|
|||||||
MessageHandler
|
MessageHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferPool = sync.Pool{
|
// bufferPool is unused
|
||||||
New: func() any {
|
// var bufferPool = sync.Pool{
|
||||||
return make([]byte, 1024)
|
// New: func() any {
|
||||||
},
|
// return make([]byte, 1024)
|
||||||
}
|
// },
|
||||||
|
// }
|
||||||
|
|
||||||
type WsServer struct {
|
type WsServer struct {
|
||||||
|
globalConfig *config.GlobalConfig
|
||||||
port int
|
port int
|
||||||
wsMaxConnNum int64
|
wsMaxConnNum int64
|
||||||
registerChan chan *Client
|
registerChan chan *Client
|
||||||
@ -87,15 +86,16 @@ type WsServer struct {
|
|||||||
Encoder
|
Encoder
|
||||||
MessageHandler
|
MessageHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
type kickHandler struct {
|
type kickHandler struct {
|
||||||
clientOK bool
|
clientOK bool
|
||||||
oldClients []*Client
|
oldClients []*Client
|
||||||
newClient *Client
|
newClient *Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WsServer) SetDiscoveryRegistry(disCov discoveryregistry.SvcDiscoveryRegistry) {
|
func (ws *WsServer) SetDiscoveryRegistry(disCov discoveryregistry.SvcDiscoveryRegistry, config *config.GlobalConfig) {
|
||||||
ws.MessageHandler = NewGrpcHandler(ws.validate, disCov)
|
ws.MessageHandler = NewGrpcHandler(ws.validate, disCov, config)
|
||||||
u := rpcclient.NewUserRpcClient(disCov)
|
u := rpcclient.NewUserRpcClient(disCov, config)
|
||||||
ws.userClient = &u
|
ws.userClient = &u
|
||||||
ws.disCov = disCov
|
ws.disCov = disCov
|
||||||
}
|
}
|
||||||
@ -107,12 +107,12 @@ func (ws *WsServer) SetUserOnlineStatus(ctx context.Context, client *Client, sta
|
|||||||
}
|
}
|
||||||
switch status {
|
switch status {
|
||||||
case constant.Online:
|
case constant.Online:
|
||||||
err := CallbackUserOnline(ctx, client.UserID, client.PlatformID, client.IsBackground, client.ctx.GetConnID())
|
err := CallbackUserOnline(ctx, ws.globalConfig, client.UserID, client.PlatformID, client.IsBackground, client.ctx.GetConnID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "CallbackUserOnline err", err)
|
log.ZWarn(ctx, "CallbackUserOnline err", err)
|
||||||
}
|
}
|
||||||
case constant.Offline:
|
case constant.Offline:
|
||||||
err := CallbackUserOffline(ctx, client.UserID, client.PlatformID, client.ctx.GetConnID())
|
err := CallbackUserOffline(ctx, ws.globalConfig, client.UserID, client.PlatformID, client.ctx.GetConnID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "CallbackUserOffline err", err)
|
log.ZWarn(ctx, "CallbackUserOffline err", err)
|
||||||
}
|
}
|
||||||
@ -128,7 +128,9 @@ func (ws *WsServer) UnRegister(c *Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WsServer) Validate(s any) error {
|
func (ws *WsServer) Validate(s any) error {
|
||||||
//?question?
|
if s == nil {
|
||||||
|
return errs.Wrap(errors.New("input cannot be nil"))
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,13 +142,14 @@ func (ws *WsServer) GetUserPlatformCons(userID string, platform int) ([]*Client,
|
|||||||
return ws.clients.Get(userID, platform)
|
return ws.clients.Get(userID, platform)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWsServer(opts ...Option) (*WsServer, error) {
|
func NewWsServer(globalConfig *config.GlobalConfig, opts ...Option) (*WsServer, error) {
|
||||||
var config configs
|
var config configs
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&config)
|
o(&config)
|
||||||
}
|
}
|
||||||
v := validator.New()
|
v := validator.New()
|
||||||
return &WsServer{
|
return &WsServer{
|
||||||
|
globalConfig: globalConfig,
|
||||||
port: config.port,
|
port: config.port,
|
||||||
wsMaxConnNum: config.maxConnNum,
|
wsMaxConnNum: config.maxConnNum,
|
||||||
writeBufferSize: config.writeBufferSize,
|
writeBufferSize: config.writeBufferSize,
|
||||||
@ -220,7 +223,7 @@ func (ws *WsServer) Run(done chan error) error {
|
|||||||
var concurrentRequest = 3
|
var concurrentRequest = 3
|
||||||
|
|
||||||
func (ws *WsServer) sendUserOnlineInfoToOtherNode(ctx context.Context, client *Client) error {
|
func (ws *WsServer) sendUserOnlineInfoToOtherNode(ctx context.Context, client *Client) error {
|
||||||
conns, err := ws.disCov.GetConns(ctx, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := ws.disCov.GetConns(ctx, ws.globalConfig.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -275,7 +278,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)
|
||||||
// 已经有同平台的连接存在
|
// There is already a connection to the platform
|
||||||
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))
|
||||||
ws.onlineUserConnNum.Add(1)
|
ws.onlineUserConnNum.Add(1)
|
||||||
} else {
|
} else {
|
||||||
@ -285,7 +288,7 @@ func (ws *WsServer) registerClient(client *Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
if config.Config.Envs.Discovery == "zookeeper" {
|
if ws.globalConfig.Envs.Discovery == "zookeeper" {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
@ -328,7 +331,7 @@ func (ws *WsServer) KickUserConn(client *Client) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) {
|
func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) {
|
||||||
switch config.Config.MultiLoginPolicy {
|
switch ws.globalConfig.MultiLoginPolicy {
|
||||||
case constant.DefalutNotKick:
|
case constant.DefalutNotKick:
|
||||||
case constant.PCAndOther:
|
case constant.PCAndOther:
|
||||||
if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC {
|
if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC {
|
||||||
@ -440,7 +443,7 @@ func (ws *WsServer) ParseWSArgs(r *http.Request) (args *WSArgs, err error) {
|
|||||||
return nil, errs.ErrConnArgsErr.Wrap("platformID is not int")
|
return nil, errs.ErrConnArgsErr.Wrap("platformID is not int")
|
||||||
}
|
}
|
||||||
v.PlatformID = platformID
|
v.PlatformID = platformID
|
||||||
if err = authverify.WsVerifyToken(v.Token, v.UserID, platformID); err != nil {
|
if err = authverify.WsVerifyToken(v.Token, v.UserID, ws.globalConfig.Secret, platformID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if query.Get(Compression) == GzipCompressionProtocol {
|
if query.Get(Compression) == GzipCompressionProtocol {
|
||||||
|
@ -19,15 +19,15 @@ import "time"
|
|||||||
type (
|
type (
|
||||||
Option func(opt *configs)
|
Option func(opt *configs)
|
||||||
configs struct {
|
configs struct {
|
||||||
// 长连接监听端口
|
// Long connection listening port
|
||||||
port int
|
port int
|
||||||
// 长连接允许最大链接数
|
// Maximum number of connections allowed for long connection
|
||||||
maxConnNum int64
|
maxConnNum int64
|
||||||
// 连接握手超时时间
|
// Connection handshake timeout
|
||||||
handshakeTimeout time.Duration
|
handshakeTimeout time.Duration
|
||||||
// 允许消息最大长度
|
// Maximum length allowed for messages
|
||||||
messageMaxMsgLength int
|
messageMaxMsgLength int
|
||||||
// websocket write buffer, default: 4096, 4kb.
|
// Websocket write buffer, default: 4096, 4kb.
|
||||||
writeBufferSize int
|
writeBufferSize int
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -58,12 +58,12 @@ func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
|
|||||||
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 {
|
||||||
log.ZDebug(context.Background(), "Set existed", "user_id", key, "client", *v)
|
log.ZDebug(context.Background(), "Set existed", "user_id", key, "client_user_id", v.UserID)
|
||||||
oldClients := allClients.([]*Client)
|
oldClients := allClients.([]*Client)
|
||||||
oldClients = append(oldClients, v)
|
oldClients = append(oldClients, v)
|
||||||
u.m.Store(key, oldClients)
|
u.m.Store(key, oldClients)
|
||||||
} else {
|
} else {
|
||||||
log.ZDebug(context.Background(), "Set not existed", "user_id", key, "client", *v)
|
log.ZDebug(context.Background(), "Set not existed", "user_id", key, "client_user_id", v.UserID)
|
||||||
var clients []*Client
|
var clients []*Client
|
||||||
clients = append(clients, v)
|
clients = append(clients, v)
|
||||||
u.m.Store(key, clients)
|
u.m.Store(key, clients)
|
||||||
|
@ -18,24 +18,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
|
||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/mw"
|
"github.com/OpenIMSDK/tools/mw"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
@ -43,22 +32,34 @@ import (
|
|||||||
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MsgTransfer struct {
|
type MsgTransfer struct {
|
||||||
historyCH *OnlineHistoryRedisConsumerHandler // 这个消费者聚合消息, 订阅的topic:ws2ms_chat, 修改通知发往msg_to_modify topic, 消息存入redis后Incr Redis, 再发消息到ms2pschat topic推送, 发消息到msg_to_mongo topic持久化
|
// This consumer aggregated messages, subscribed to the topic:ws2ms_chat,
|
||||||
historyMongoCH *OnlineHistoryMongoConsumerHandler // mongoDB批量插入, 成功后删除redis中消息,以及处理删除通知消息删除的 订阅的topic: msg_to_mongo
|
// the modification notification is sent to msg_to_modify topic, the message is stored in redis, Incr Redis,
|
||||||
ctx context.Context
|
// and then the message is sent to ms2pschat topic for push, and the message is sent to msg_to_mongo topic for persistence
|
||||||
cancel context.CancelFunc
|
historyCH *OnlineHistoryRedisConsumerHandler
|
||||||
|
historyMongoCH *OnlineHistoryMongoConsumerHandler
|
||||||
|
// mongoDB batch insert, delete messages in redis after success,
|
||||||
|
// and handle the deletion notification message deleted subscriptions topic: msg_to_mongo
|
||||||
|
ctx context.Context
|
||||||
|
cancel context.CancelFunc
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartTransfer(prometheusPort int) error {
|
func StartTransfer(config *config.GlobalConfig, prometheusPort int) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -66,36 +67,42 @@ func StartTransfer(prometheusPort int) error {
|
|||||||
if err = mongo.CreateMsgIndex(); err != nil {
|
if err = mongo.CreateMsgIndex(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
client, err := kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
client, err := kdisc.NewDiscoveryRegister(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := client.CreateRpcRootNodes(config.Config.GetServiceNames()); err != nil {
|
if err := client.CreateRpcRootNodes(config.GetServiceNames()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
||||||
msgModel := cache.NewMsgCacheModel(rdb)
|
msgModel := cache.NewMsgCacheModel(rdb, config)
|
||||||
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
|
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase(config.Mongo.Database))
|
||||||
msgDatabase, err := controller.NewCommonMsgDatabase(msgDocModel, msgModel)
|
msgDatabase, err := controller.NewCommonMsgDatabase(msgDocModel, msgModel, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
conversationRpcClient := rpcclient.NewConversationRpcClient(client, config)
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
msgTransfer, err := NewMsgTransfer(msgDatabase, &conversationRpcClient, &groupRpcClient)
|
msgTransfer, err := NewMsgTransfer(config, msgDatabase, &conversationRpcClient, &groupRpcClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return msgTransfer.Start(prometheusPort)
|
return msgTransfer.Start(prometheusPort, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMsgTransfer(msgDatabase controller.CommonMsgDatabase, conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) (*MsgTransfer, error) {
|
func NewMsgTransfer(
|
||||||
historyCH, err := NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient)
|
config *config.GlobalConfig,
|
||||||
|
msgDatabase controller.CommonMsgDatabase,
|
||||||
|
conversationRpcClient *rpcclient.ConversationRpcClient,
|
||||||
|
groupRpcClient *rpcclient.GroupRpcClient,
|
||||||
|
) (*MsgTransfer, error) {
|
||||||
|
historyCH, err := NewOnlineHistoryRedisConsumerHandler(config, msgDatabase, conversationRpcClient, groupRpcClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
historyMongoCH, err := NewOnlineHistoryMongoConsumerHandler(msgDatabase)
|
historyMongoCH, err := NewOnlineHistoryMongoConsumerHandler(config, msgDatabase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -103,10 +110,11 @@ func NewMsgTransfer(msgDatabase controller.CommonMsgDatabase, conversationRpcCli
|
|||||||
return &MsgTransfer{
|
return &MsgTransfer{
|
||||||
historyCH: historyCH,
|
historyCH: historyCH,
|
||||||
historyMongoCH: historyMongoCH,
|
historyMongoCH: historyMongoCH,
|
||||||
|
config: config,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgTransfer) Start(prometheusPort int) error {
|
func (m *MsgTransfer) Start(prometheusPort int, config *config.GlobalConfig) error {
|
||||||
fmt.Println("start msg transfer", "prometheusPort:", prometheusPort)
|
fmt.Println("start msg transfer", "prometheusPort:", prometheusPort)
|
||||||
if prometheusPort <= 0 {
|
if prometheusPort <= 0 {
|
||||||
return errs.Wrap(errors.New("prometheusPort not correct"))
|
return errs.Wrap(errors.New("prometheusPort not correct"))
|
||||||
@ -118,19 +126,16 @@ func (m *MsgTransfer) Start(prometheusPort int) error {
|
|||||||
netErr error
|
netErr error
|
||||||
)
|
)
|
||||||
|
|
||||||
onError := func(ctx context.Context, err error, errInfo string) {
|
go m.historyCH.historyConsumerGroup.RegisterHandleAndConsumer(m.ctx, m.historyCH)
|
||||||
log.ZWarn(ctx, errInfo, err)
|
go m.historyMongoCH.historyConsumerGroup.RegisterHandleAndConsumer(m.ctx, m.historyMongoCH)
|
||||||
}
|
|
||||||
go m.historyCH.historyConsumerGroup.RegisterHandleAndConsumer(m.ctx, m.historyCH, onError)
|
|
||||||
go m.historyMongoCH.historyConsumerGroup.RegisterHandleAndConsumer(m.ctx, m.historyMongoCH, onError)
|
|
||||||
|
|
||||||
if config.Config.Prometheus.Enable {
|
if config.Prometheus.Enable {
|
||||||
go func() {
|
go func() {
|
||||||
proreg := prometheus.NewRegistry()
|
proreg := prometheus.NewRegistry()
|
||||||
proreg.MustRegister(
|
proreg.MustRegister(
|
||||||
collectors.NewGoCollector(),
|
collectors.NewGoCollector(),
|
||||||
)
|
)
|
||||||
proreg.MustRegister(prommetrics.GetGrpcCusMetrics("Transfer")...)
|
proreg.MustRegister(prommetrics.GetGrpcCusMetrics("Transfer", config)...)
|
||||||
http.Handle("/metrics", promhttp.HandlerFor(proreg, promhttp.HandlerOpts{Registry: proreg}))
|
http.Handle("/metrics", promhttp.HandlerFor(proreg, promhttp.HandlerOpts{Registry: proreg}))
|
||||||
err := http.ListenAndServe(fmt.Sprintf(":%d", prometheusPort), nil)
|
err := http.ListenAndServe(fmt.Sprintf(":%d", prometheusPort), nil)
|
||||||
if err != nil && err != http.ErrServerClosed {
|
if err != nil && err != http.ErrServerClosed {
|
||||||
@ -144,12 +149,12 @@ func (m *MsgTransfer) Start(prometheusPort int) error {
|
|||||||
signal.Notify(sigs, syscall.SIGTERM)
|
signal.Notify(sigs, syscall.SIGTERM)
|
||||||
select {
|
select {
|
||||||
case <-sigs:
|
case <-sigs:
|
||||||
util.SIGUSR1Exit()
|
util.SIGTERMExit()
|
||||||
// graceful close kafka client.
|
// graceful close kafka client.
|
||||||
m.cancel()
|
m.cancel()
|
||||||
m.historyCH.historyConsumerGroup.Close()
|
m.historyCH.historyConsumerGroup.Close()
|
||||||
m.historyMongoCH.historyConsumerGroup.Close()
|
m.historyMongoCH.historyConsumerGroup.Close()
|
||||||
|
return nil
|
||||||
case <-netDone:
|
case <-netDone:
|
||||||
m.cancel()
|
m.cancel()
|
||||||
m.historyCH.historyConsumerGroup.Close()
|
m.historyCH.historyConsumerGroup.Close()
|
||||||
@ -157,6 +162,4 @@ func (m *MsgTransfer) Start(prometheusPort int) error {
|
|||||||
close(netDone)
|
close(netDone)
|
||||||
return netErr
|
return netErr
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -22,24 +22,20 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
|
|
||||||
"github.com/IBM/sarama"
|
"github.com/IBM/sarama"
|
||||||
"github.com/go-redis/redis"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/go-redis/redis"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -74,10 +70,10 @@ type OnlineHistoryRedisConsumerHandler struct {
|
|||||||
chArrays [ChannelNum]chan Cmd2Value
|
chArrays [ChannelNum]chan Cmd2Value
|
||||||
msgDistributionCh chan Cmd2Value
|
msgDistributionCh chan Cmd2Value
|
||||||
|
|
||||||
singleMsgSuccessCount uint64
|
// singleMsgSuccessCount uint64
|
||||||
singleMsgFailedCount uint64
|
// singleMsgFailedCount uint64
|
||||||
singleMsgSuccessCountMutex sync.Mutex
|
// singleMsgSuccessCountMutex sync.Mutex
|
||||||
singleMsgFailedCountMutex sync.Mutex
|
// singleMsgFailedCountMutex sync.Mutex
|
||||||
|
|
||||||
msgDatabase controller.CommonMsgDatabase
|
msgDatabase controller.CommonMsgDatabase
|
||||||
conversationRpcClient *rpcclient.ConversationRpcClient
|
conversationRpcClient *rpcclient.ConversationRpcClient
|
||||||
@ -85,6 +81,7 @@ type OnlineHistoryRedisConsumerHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewOnlineHistoryRedisConsumerHandler(
|
func NewOnlineHistoryRedisConsumerHandler(
|
||||||
|
config *config.GlobalConfig,
|
||||||
database controller.CommonMsgDatabase,
|
database controller.CommonMsgDatabase,
|
||||||
conversationRpcClient *rpcclient.ConversationRpcClient,
|
conversationRpcClient *rpcclient.ConversationRpcClient,
|
||||||
groupRpcClient *rpcclient.GroupRpcClient,
|
groupRpcClient *rpcclient.GroupRpcClient,
|
||||||
@ -100,79 +97,86 @@ func NewOnlineHistoryRedisConsumerHandler(
|
|||||||
och.conversationRpcClient = conversationRpcClient
|
och.conversationRpcClient = conversationRpcClient
|
||||||
och.groupRpcClient = groupRpcClient
|
och.groupRpcClient = groupRpcClient
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
var tlsConfig *kafka.TLSConfig
|
||||||
|
if config.Kafka.TLS != nil {
|
||||||
|
tlsConfig = &kafka.TLSConfig{
|
||||||
|
CACrt: config.Kafka.TLS.CACrt,
|
||||||
|
ClientCrt: config.Kafka.TLS.ClientCrt,
|
||||||
|
ClientKey: config.Kafka.TLS.ClientKey,
|
||||||
|
ClientKeyPwd: config.Kafka.TLS.ClientKeyPwd,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
och.historyConsumerGroup, err = kafka.NewMConsumerGroup(&kafka.MConsumerGroupConfig{
|
och.historyConsumerGroup, err = kafka.NewMConsumerGroup(&kafka.MConsumerGroupConfig{
|
||||||
KafkaVersion: sarama.V2_0_0_0,
|
KafkaVersion: sarama.V2_0_0_0,
|
||||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
|
OffsetsInitial: sarama.OffsetNewest,
|
||||||
}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
|
IsReturnErr: false,
|
||||||
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToRedis)
|
UserName: config.Kafka.Username,
|
||||||
|
Password: config.Kafka.Password,
|
||||||
|
}, []string{config.Kafka.LatestMsgToRedis.Topic},
|
||||||
|
config.Kafka.Addr,
|
||||||
|
config.Kafka.ConsumerGroupID.MsgToRedis,
|
||||||
|
tlsConfig,
|
||||||
|
)
|
||||||
// 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)
|
||||||
return &och, err
|
return &och, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (och *OnlineHistoryRedisConsumerHandler) Run(channelID int) {
|
func (och *OnlineHistoryRedisConsumerHandler) Run(channelID int) {
|
||||||
for {
|
for cmd := range och.chArrays[channelID] {
|
||||||
select {
|
switch cmd.Cmd {
|
||||||
case cmd := <-och.chArrays[channelID]:
|
case SourceMessages:
|
||||||
switch cmd.Cmd {
|
msgChannelValue := cmd.Value.(MsgChannelValue)
|
||||||
case SourceMessages:
|
ctxMsgList := msgChannelValue.ctxMsgList
|
||||||
msgChannelValue := cmd.Value.(MsgChannelValue)
|
ctx := msgChannelValue.ctx
|
||||||
ctxMsgList := msgChannelValue.ctxMsgList
|
log.ZDebug(
|
||||||
ctx := msgChannelValue.ctx
|
ctx,
|
||||||
log.ZDebug(
|
"msg arrived channel",
|
||||||
ctx,
|
"channel id",
|
||||||
"msg arrived channel",
|
channelID,
|
||||||
"channel id",
|
"msgList length",
|
||||||
channelID,
|
len(ctxMsgList),
|
||||||
"msgList length",
|
"uniqueKey",
|
||||||
len(ctxMsgList),
|
msgChannelValue.uniqueKey,
|
||||||
"uniqueKey",
|
)
|
||||||
msgChannelValue.uniqueKey,
|
storageMsgList, notStorageMsgList, storageNotificationList, notStorageNotificationList, modifyMsgList := och.getPushStorageMsgList(
|
||||||
)
|
ctxMsgList,
|
||||||
storageMsgList, notStorageMsgList, storageNotificationList, notStorageNotificationList, modifyMsgList := och.getPushStorageMsgList(
|
)
|
||||||
ctxMsgList,
|
log.ZDebug(
|
||||||
)
|
ctx,
|
||||||
log.ZDebug(
|
"msg lens",
|
||||||
ctx,
|
"storageMsgList",
|
||||||
"msg lens",
|
len(storageMsgList),
|
||||||
"storageMsgList",
|
"notStorageMsgList",
|
||||||
len(storageMsgList),
|
len(notStorageMsgList),
|
||||||
"notStorageMsgList",
|
"storageNotificationList",
|
||||||
len(notStorageMsgList),
|
len(storageNotificationList),
|
||||||
"storageNotificationList",
|
"notStorageNotificationList",
|
||||||
len(storageNotificationList),
|
len(notStorageNotificationList),
|
||||||
"notStorageNotificationList",
|
"modifyMsgList",
|
||||||
len(notStorageNotificationList),
|
len(modifyMsgList),
|
||||||
"modifyMsgList",
|
)
|
||||||
len(modifyMsgList),
|
conversationIDMsg := msgprocessor.GetChatConversationIDByMsg(ctxMsgList[0].message)
|
||||||
)
|
conversationIDNotification := msgprocessor.GetNotificationConversationIDByMsg(ctxMsgList[0].message)
|
||||||
conversationIDMsg := msgprocessor.GetChatConversationIDByMsg(ctxMsgList[0].message)
|
och.handleMsg(ctx, msgChannelValue.uniqueKey, conversationIDMsg, storageMsgList, notStorageMsgList)
|
||||||
conversationIDNotification := msgprocessor.GetNotificationConversationIDByMsg(ctxMsgList[0].message)
|
och.handleNotification(
|
||||||
och.handleMsg(ctx, msgChannelValue.uniqueKey, conversationIDMsg, storageMsgList, notStorageMsgList)
|
ctx,
|
||||||
och.handleNotification(
|
msgChannelValue.uniqueKey,
|
||||||
ctx,
|
conversationIDNotification,
|
||||||
msgChannelValue.uniqueKey,
|
storageNotificationList,
|
||||||
conversationIDNotification,
|
notStorageNotificationList,
|
||||||
storageNotificationList,
|
)
|
||||||
notStorageNotificationList,
|
if err := och.msgDatabase.MsgToModifyMQ(ctx, msgChannelValue.uniqueKey, conversationIDNotification, modifyMsgList); err != nil {
|
||||||
)
|
log.ZError(ctx, "msg to modify mq error", err, "uniqueKey", msgChannelValue.uniqueKey, "modifyMsgList", modifyMsgList)
|
||||||
if err := och.msgDatabase.MsgToModifyMQ(ctx, msgChannelValue.uniqueKey, conversationIDNotification, modifyMsgList); err != nil {
|
|
||||||
log.ZError(
|
|
||||||
ctx,
|
|
||||||
"msg to modify mq error",
|
|
||||||
err,
|
|
||||||
"uniqueKey",
|
|
||||||
msgChannelValue.uniqueKey,
|
|
||||||
"modifyMsgList",
|
|
||||||
modifyMsgList,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取消息/通知 存储的消息列表, 不存储并且推送的消息列表,.
|
// Get messages/notifications stored message list, not stored and pushed message list.
|
||||||
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) {
|
||||||
@ -193,7 +197,7 @@ func (och *OnlineHistoryRedisConsumerHandler) getPushStorageMsgList(
|
|||||||
// clone msg from notificationMsg
|
// clone msg from notificationMsg
|
||||||
if options.IsSendMsg() {
|
if options.IsSendMsg() {
|
||||||
msg := proto.Clone(v.message).(*sdkws.MsgData)
|
msg := proto.Clone(v.message).(*sdkws.MsgData)
|
||||||
// 消息
|
// message
|
||||||
if v.message.Options != nil {
|
if v.message.Options != nil {
|
||||||
msg.Options = msgprocessor.NewMsgOptions()
|
msg.Options = msgprocessor.NewMsgOptions()
|
||||||
}
|
}
|
||||||
@ -268,7 +272,8 @@ func (och *OnlineHistoryRedisConsumerHandler) toPushTopic(
|
|||||||
msgs []*sdkws.MsgData,
|
msgs []*sdkws.MsgData,
|
||||||
) {
|
) {
|
||||||
for _, v := range msgs {
|
for _, v := range msgs {
|
||||||
och.msgDatabase.MsgToPushMQ(ctx, key, conversationID, v)
|
och.msgDatabase.MsgToPushMQ(ctx, key, conversationID, v) // nolint: errcheck
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,6 +446,7 @@ func (och *OnlineHistoryRedisConsumerHandler) ConsumeClaim(
|
|||||||
wg = sync.WaitGroup{}
|
wg = sync.WaitGroup{}
|
||||||
running = new(atomic.Bool)
|
running = new(atomic.Bool)
|
||||||
)
|
)
|
||||||
|
running.Store(true)
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -18,15 +18,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/IBM/sarama"
|
"github.com/IBM/sarama"
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
|
|
||||||
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
kfk "github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
|
kfk "github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OnlineHistoryMongoConsumerHandler struct {
|
type OnlineHistoryMongoConsumerHandler struct {
|
||||||
@ -34,12 +32,28 @@ type OnlineHistoryMongoConsumerHandler struct {
|
|||||||
msgDatabase controller.CommonMsgDatabase
|
msgDatabase controller.CommonMsgDatabase
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOnlineHistoryMongoConsumerHandler(database controller.CommonMsgDatabase) (*OnlineHistoryMongoConsumerHandler, error) {
|
func NewOnlineHistoryMongoConsumerHandler(config *config.GlobalConfig, database controller.CommonMsgDatabase) (*OnlineHistoryMongoConsumerHandler, error) {
|
||||||
|
var tlsConfig *kfk.TLSConfig
|
||||||
|
if config.Kafka.TLS != nil {
|
||||||
|
tlsConfig = &kfk.TLSConfig{
|
||||||
|
CACrt: config.Kafka.TLS.CACrt,
|
||||||
|
ClientCrt: config.Kafka.TLS.ClientCrt,
|
||||||
|
ClientKey: config.Kafka.TLS.ClientKey,
|
||||||
|
ClientKeyPwd: config.Kafka.TLS.ClientKeyPwd,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
historyConsumerGroup, err := kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
historyConsumerGroup, err := kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
||||||
KafkaVersion: sarama.V2_0_0_0,
|
KafkaVersion: sarama.V2_0_0_0,
|
||||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
|
OffsetsInitial: sarama.OffsetNewest,
|
||||||
}, []string{config.Config.Kafka.MsgToMongo.Topic},
|
IsReturnErr: false,
|
||||||
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMongo)
|
UserName: config.Kafka.Username,
|
||||||
|
Password: config.Kafka.Password,
|
||||||
|
}, []string{config.Kafka.MsgToMongo.Topic},
|
||||||
|
config.Kafka.Addr,
|
||||||
|
config.Kafka.ConsumerGroupID.MsgToMongo,
|
||||||
|
tlsConfig,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -21,23 +21,19 @@ import (
|
|||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
"github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func url() string {
|
|
||||||
return config.Config.Callback.CallbackUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
func callbackOfflinePush(
|
func callbackOfflinePush(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
config *config.GlobalConfig,
|
||||||
userIDs []string,
|
userIDs []string,
|
||||||
msg *sdkws.MsgData,
|
msg *sdkws.MsgData,
|
||||||
offlinePushUserIDs *[]string,
|
offlinePushUserIDs *[]string,
|
||||||
) error {
|
) error {
|
||||||
if !config.Config.Callback.CallbackOfflinePush.Enable || msg.ContentType == constant.Typing {
|
if !config.Callback.CallbackOfflinePush.Enable || msg.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &callbackstruct.CallbackBeforePushReq{
|
req := &callbackstruct.CallbackBeforePushReq{
|
||||||
@ -59,10 +55,12 @@ func callbackOfflinePush(
|
|||||||
AtUserIDs: msg.AtUserIDList,
|
AtUserIDs: msg.AtUserIDList,
|
||||||
Content: GetContent(msg),
|
Content: GetContent(msg),
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := &callbackstruct.CallbackBeforePushResp{}
|
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, url(), req, resp, config.Config.Callback.CallbackOfflinePush); err != nil {
|
if err := http.CallBackPostReturn(ctx, config.Callback.CallbackUrl, req, resp, config.Callback.CallbackOfflinePush); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(resp.UserIDs) != 0 {
|
if len(resp.UserIDs) != 0 {
|
||||||
*offlinePushUserIDs = resp.UserIDs
|
*offlinePushUserIDs = resp.UserIDs
|
||||||
}
|
}
|
||||||
@ -72,8 +70,8 @@ func callbackOfflinePush(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
func callbackOnlinePush(ctx context.Context, config *config.GlobalConfig, userIDs []string, msg *sdkws.MsgData) error {
|
||||||
if !config.Config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDs...) || msg.ContentType == constant.Typing {
|
if !config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDs...) || msg.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := callbackstruct.CallbackBeforePushReq{
|
req := callbackstruct.CallbackBeforePushReq{
|
||||||
@ -95,7 +93,7 @@ func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgDat
|
|||||||
Content: GetContent(msg),
|
Content: GetContent(msg),
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackBeforePushResp{}
|
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, url(), req, resp, config.Config.Callback.CallbackOnlinePush); err != nil {
|
if err := http.CallBackPostReturn(ctx, config.Callback.CallbackUrl, req, resp, config.Callback.CallbackOnlinePush); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -103,11 +101,12 @@ func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgDat
|
|||||||
|
|
||||||
func callbackBeforeSuperGroupOnlinePush(
|
func callbackBeforeSuperGroupOnlinePush(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
config *config.GlobalConfig,
|
||||||
groupID string,
|
groupID string,
|
||||||
msg *sdkws.MsgData,
|
msg *sdkws.MsgData,
|
||||||
pushToUserIDs *[]string,
|
pushToUserIDs *[]string,
|
||||||
) error {
|
) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable || msg.ContentType == constant.Typing {
|
if !config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable || msg.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
|
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
|
||||||
@ -127,7 +126,7 @@ func callbackBeforeSuperGroupOnlinePush(
|
|||||||
Seq: msg.Seq,
|
Seq: msg.Seq,
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackBeforeSuperGroupOnlinePushResp{}
|
resp := &callbackstruct.CallbackBeforeSuperGroupOnlinePushResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackBeforeSuperGroupOnlinePush); err != nil {
|
if err := http.CallBackPostReturn(ctx, config.Callback.CallbackUrl, req, resp, config.Callback.CallbackBeforeSuperGroupOnlinePush); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,16 +17,17 @@ package push
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Consumer struct {
|
type Consumer struct {
|
||||||
pushCh ConsumerHandler
|
pushCh ConsumerHandler
|
||||||
successCount uint64
|
// successCount is unused
|
||||||
|
// successCount uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConsumer(pusher *Pusher) (*Consumer, error) {
|
func NewConsumer(config *config.GlobalConfig, pusher *Pusher) (*Consumer, error) {
|
||||||
c, err := NewConsumerHandler(pusher)
|
c, err := NewConsumerHandler(config, pusher)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -36,9 +37,5 @@ func NewConsumer(pusher *Pusher) (*Consumer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Consumer) Start() {
|
func (c *Consumer) Start() {
|
||||||
onError := func(ctx context.Context, err error, errInfo string) {
|
go c.pushCh.pushConsumerGroup.RegisterHandleAndConsumer(context.Background(), &c.pushCh)
|
||||||
log.ZWarn(ctx, errInfo, err)
|
|
||||||
}
|
|
||||||
go c.pushCh.pushConsumerGroup.RegisterHandleAndConsumer(context.Background(), &c.pushCh, onError)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,12 @@ import (
|
|||||||
|
|
||||||
firebase "firebase.google.com/go"
|
firebase "firebase.google.com/go"
|
||||||
"firebase.google.com/go/messaging"
|
"firebase.google.com/go/messaging"
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
"google.golang.org/api/option"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
"google.golang.org/api/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
const SinglePushCountLimit = 400
|
const SinglePushCountLimit = 400
|
||||||
@ -39,20 +37,22 @@ type Fcm struct {
|
|||||||
cache cache.MsgModel
|
cache cache.MsgModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(cache cache.MsgModel) *Fcm {
|
// NewClient initializes a new FCM client using the Firebase Admin SDK.
|
||||||
|
// It requires the FCM service account credentials file located within the project's configuration directory.
|
||||||
|
func NewClient(globalConfig *config.GlobalConfig, cache cache.MsgModel) *Fcm {
|
||||||
projectRoot := config.GetProjectRoot()
|
projectRoot := config.GetProjectRoot()
|
||||||
credentialsFilePath := filepath.Join(projectRoot, "config", config.Config.Push.Fcm.ServiceAccount)
|
credentialsFilePath := filepath.Join(projectRoot, "config", globalConfig.Push.Fcm.ServiceAccount)
|
||||||
opt := option.WithCredentialsFile(credentialsFilePath)
|
opt := option.WithCredentialsFile(credentialsFilePath)
|
||||||
fcmApp, err := firebase.NewApp(context.Background(), nil, opt)
|
fcmApp, err := firebase.NewApp(context.Background(), nil, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
fcmMsgClient, err := fcmApp.Messaging(ctx)
|
fcmMsgClient, err := fcmApp.Messaging(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Fcm{fcmMsgCli: fcmMsgClient, cache: cache}
|
return &Fcm{fcmMsgCli: fcmMsgClient, cache: cache}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +125,6 @@ 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)
|
|
||||||
} else {
|
} else {
|
||||||
Success = Success + response.SuccessCount
|
Success = Success + response.SuccessCount
|
||||||
Fail = Fail + response.FailureCount
|
Fail = Fail + response.FailureCount
|
||||||
|
@ -133,13 +133,13 @@ type Payload struct {
|
|||||||
IsSignal bool `json:"isSignal"`
|
IsSignal bool `json:"isSignal"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPushReq(title, content string) PushReq {
|
func newPushReq(config *config.GlobalConfig, title, content string) PushReq {
|
||||||
pushReq := PushReq{PushMessage: &PushMessage{Notification: &Notification{
|
pushReq := PushReq{PushMessage: &PushMessage{Notification: &Notification{
|
||||||
Title: title,
|
Title: title,
|
||||||
Body: content,
|
Body: content,
|
||||||
ClickType: "startapp",
|
ClickType: "startapp",
|
||||||
ChannelID: config.Config.Push.GeTui.ChannelID,
|
ChannelID: config.Push.GeTui.ChannelID,
|
||||||
ChannelName: config.Config.Push.GeTui.ChannelName,
|
ChannelName: config.Push.GeTui.ChannelName,
|
||||||
}}}
|
}}}
|
||||||
return pushReq
|
return pushReq
|
||||||
}
|
}
|
||||||
|
@ -23,19 +23,15 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils/splitter"
|
"github.com/OpenIMSDK/tools/utils/splitter"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
http2 "github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
http2 "github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -59,10 +55,15 @@ type Client struct {
|
|||||||
cache cache.MsgModel
|
cache cache.MsgModel
|
||||||
tokenExpireTime int64
|
tokenExpireTime int64
|
||||||
taskIDTTL int64
|
taskIDTTL int64
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(cache cache.MsgModel) *Client {
|
func NewClient(config *config.GlobalConfig, cache cache.MsgModel) *Client {
|
||||||
return &Client{cache: cache, tokenExpireTime: tokenExpireTime, taskIDTTL: taskIDTTL}
|
return &Client{cache: cache,
|
||||||
|
tokenExpireTime: tokenExpireTime,
|
||||||
|
taskIDTTL: taskIDTTL,
|
||||||
|
config: config,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) Push(ctx context.Context, userIDs []string, title, content string, opts *offlinepush.Opts) error {
|
func (g *Client) Push(ctx context.Context, userIDs []string, title, content string, opts *offlinepush.Opts) error {
|
||||||
@ -78,7 +79,7 @@ func (g *Client) Push(ctx context.Context, userIDs []string, title, content stri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pushReq := newPushReq(title, content)
|
pushReq := newPushReq(g.config, title, content)
|
||||||
pushReq.setPushChannel(title, content)
|
pushReq.setPushChannel(title, content)
|
||||||
if len(userIDs) > 1 {
|
if len(userIDs) > 1 {
|
||||||
maxNum := 999
|
maxNum := 999
|
||||||
@ -89,9 +90,9 @@ func (g *Client) Push(ctx context.Context, userIDs []string, title, content stri
|
|||||||
for i, v := range s.GetSplitResult() {
|
for i, v := range s.GetSplitResult() {
|
||||||
go func(index int, userIDs []string) {
|
go func(index int, userIDs []string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err2 := g.batchPush(ctx, token, userIDs, pushReq); err2 != nil {
|
if err := g.batchPush(ctx, token, userIDs, pushReq); err != nil {
|
||||||
log.ZError(ctx, "batchPush failed", err2, "index", index, "token", token, "req", pushReq)
|
log.ZError(ctx, "batchPush failed", err, "index", index, "token", token, "req", pushReq)
|
||||||
err = err2
|
err = err
|
||||||
}
|
}
|
||||||
}(i, v.Item)
|
}(i, v.Item)
|
||||||
}
|
}
|
||||||
@ -114,13 +115,13 @@ func (g *Client) Push(ctx context.Context, userIDs []string, title, content stri
|
|||||||
func (g *Client) Auth(ctx context.Context, timeStamp int64) (token string, expireTime int64, err error) {
|
func (g *Client) Auth(ctx context.Context, timeStamp int64) (token string, expireTime int64, err error) {
|
||||||
h := sha256.New()
|
h := sha256.New()
|
||||||
h.Write(
|
h.Write(
|
||||||
[]byte(config.Config.Push.GeTui.AppKey + strconv.Itoa(int(timeStamp)) + config.Config.Push.GeTui.MasterSecret),
|
[]byte(g.config.Push.GeTui.AppKey + strconv.Itoa(int(timeStamp)) + g.config.Push.GeTui.MasterSecret),
|
||||||
)
|
)
|
||||||
sign := hex.EncodeToString(h.Sum(nil))
|
sign := hex.EncodeToString(h.Sum(nil))
|
||||||
reqAuth := AuthReq{
|
reqAuth := AuthReq{
|
||||||
Sign: sign,
|
Sign: sign,
|
||||||
Timestamp: strconv.Itoa(int(timeStamp)),
|
Timestamp: strconv.Itoa(int(timeStamp)),
|
||||||
AppKey: config.Config.Push.GeTui.AppKey,
|
AppKey: g.config.Push.GeTui.AppKey,
|
||||||
}
|
}
|
||||||
respAuth := AuthResp{}
|
respAuth := AuthResp{}
|
||||||
err = g.request(ctx, authURL, reqAuth, "", &respAuth)
|
err = g.request(ctx, authURL, reqAuth, "", &respAuth)
|
||||||
@ -137,7 +138,7 @@ func (g *Client) GetTaskID(ctx context.Context, token string, pushReq PushReq) (
|
|||||||
pushReq.Settings = &Settings{TTL: &ttl}
|
pushReq.Settings = &Settings{TTL: &ttl}
|
||||||
err := g.request(ctx, taskURL, pushReq, token, &respTask)
|
err := g.request(ctx, taskURL, pushReq, token, &respTask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", utils.Wrap(err, "")
|
return "", errs.Wrap(err)
|
||||||
}
|
}
|
||||||
return respTask.TaskID, nil
|
return respTask.TaskID, nil
|
||||||
}
|
}
|
||||||
@ -163,7 +164,7 @@ func (g *Client) request(ctx context.Context, url string, input any, token strin
|
|||||||
header := map[string]string{"token": token}
|
header := map[string]string{"token": token}
|
||||||
resp := &Resp{}
|
resp := &Resp{}
|
||||||
resp.Data = output
|
resp.Data = output
|
||||||
return g.postReturn(ctx, config.Config.Push.GeTui.PushUrl+url, header, input, resp, 3)
|
return g.postReturn(ctx, g.config.Push.GeTui.PushUrl+url, header, input, resp, 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) postReturn(
|
func (g *Client) postReturn(
|
||||||
|
@ -46,7 +46,6 @@ type Extras struct {
|
|||||||
func (n *Notification) SetAlert(alert string) {
|
func (n *Notification) SetAlert(alert string) {
|
||||||
n.Alert = alert
|
n.Alert = alert
|
||||||
n.Android.Alert = alert
|
n.Android.Alert = alert
|
||||||
n.SetAndroidIntent()
|
|
||||||
n.IOS.Alert = alert
|
n.IOS.Alert = alert
|
||||||
n.IOS.Sound = "default"
|
n.IOS.Sound = "default"
|
||||||
n.IOS.Badge = "+1"
|
n.IOS.Badge = "+1"
|
||||||
@ -57,8 +56,8 @@ func (n *Notification) SetExtras(extras Extras) {
|
|||||||
n.Android.Extras = extras
|
n.Android.Extras = extras
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notification) SetAndroidIntent() {
|
func (n *Notification) SetAndroidIntent(config *config.GlobalConfig) {
|
||||||
n.Android.Intent.URL = config.Config.Push.Jpns.PushIntent
|
n.Android.Intent.URL = config.Push.Jpns.PushIntent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notification) IOSEnableMutableContent() {
|
func (n *Notification) IOSEnableMutableContent() {
|
||||||
|
@ -25,10 +25,12 @@ import (
|
|||||||
http2 "github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
http2 "github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type JPush struct{}
|
type JPush struct {
|
||||||
|
config *config.GlobalConfig
|
||||||
|
}
|
||||||
|
|
||||||
func NewClient() *JPush {
|
func NewClient(config *config.GlobalConfig) *JPush {
|
||||||
return &JPush{}
|
return &JPush{config: config}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *JPush) Auth(apiKey, secretKey string, timeStamp int64) (token string, err error) {
|
func (j *JPush) Auth(apiKey, secretKey string, timeStamp int64) (token string, err error) {
|
||||||
@ -59,10 +61,12 @@ func (j *JPush) Push(ctx context.Context, userIDs []string, title, content strin
|
|||||||
no.IOSEnableMutableContent()
|
no.IOSEnableMutableContent()
|
||||||
no.SetExtras(extras)
|
no.SetExtras(extras)
|
||||||
no.SetAlert(title)
|
no.SetAlert(title)
|
||||||
|
no.SetAndroidIntent(j.config)
|
||||||
|
|
||||||
var msg body.Message
|
var msg body.Message
|
||||||
msg.SetMsgContent(content)
|
msg.SetMsgContent(content)
|
||||||
var opt body.Options
|
var opt body.Options
|
||||||
opt.SetApnsProduction(config.Config.IOSPush.Production)
|
opt.SetApnsProduction(j.config.IOSPush.Production)
|
||||||
var pushObj body.PushObj
|
var pushObj body.PushObj
|
||||||
pushObj.SetPlatform(&pf)
|
pushObj.SetPlatform(&pf)
|
||||||
pushObj.SetAudience(&au)
|
pushObj.SetAudience(&au)
|
||||||
@ -76,9 +80,9 @@ func (j *JPush) Push(ctx context.Context, userIDs []string, title, content strin
|
|||||||
func (j *JPush) request(ctx context.Context, po body.PushObj, resp any, timeout int) error {
|
func (j *JPush) request(ctx context.Context, po body.PushObj, resp any, timeout int) error {
|
||||||
return http2.PostReturn(
|
return http2.PostReturn(
|
||||||
ctx,
|
ctx,
|
||||||
config.Config.Push.Jpns.PushUrl,
|
j.config.Push.Jpns.PushUrl,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"Authorization": j.getAuthorization(config.Config.Push.Jpns.AppKey, config.Config.Push.Jpns.MasterSecret),
|
"Authorization": j.getAuthorization(j.config.Push.Jpns.AppKey, j.config.Push.Jpns.MasterSecret),
|
||||||
},
|
},
|
||||||
po,
|
po,
|
||||||
resp,
|
resp,
|
||||||
|
@ -18,16 +18,14 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/IBM/sarama"
|
"github.com/IBM/sarama"
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
pbchat "github.com/OpenIMSDK/protocol/msg"
|
pbchat "github.com/OpenIMSDK/protocol/msg"
|
||||||
pbpush "github.com/OpenIMSDK/protocol/push"
|
pbpush "github.com/OpenIMSDK/protocol/push"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
kfk "github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
|
kfk "github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConsumerHandler struct {
|
type ConsumerHandler struct {
|
||||||
@ -35,15 +33,29 @@ type ConsumerHandler struct {
|
|||||||
pusher *Pusher
|
pusher *Pusher
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConsumerHandler(pusher *Pusher) (*ConsumerHandler, error) {
|
func NewConsumerHandler(config *config.GlobalConfig, pusher *Pusher) (*ConsumerHandler, error) {
|
||||||
var consumerHandler ConsumerHandler
|
var consumerHandler ConsumerHandler
|
||||||
consumerHandler.pusher = pusher
|
consumerHandler.pusher = pusher
|
||||||
var err error
|
var err error
|
||||||
|
var tlsConfig *kfk.TLSConfig
|
||||||
|
if config.Kafka.TLS != nil {
|
||||||
|
tlsConfig = &kfk.TLSConfig{
|
||||||
|
CACrt: config.Kafka.TLS.CACrt,
|
||||||
|
ClientCrt: config.Kafka.TLS.ClientCrt,
|
||||||
|
ClientKey: config.Kafka.TLS.ClientKey,
|
||||||
|
ClientKeyPwd: config.Kafka.TLS.ClientKeyPwd,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
consumerHandler.pushConsumerGroup, err = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
consumerHandler.pushConsumerGroup, err = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
||||||
KafkaVersion: sarama.V2_0_0_0,
|
KafkaVersion: sarama.V2_0_0_0,
|
||||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
|
OffsetsInitial: sarama.OffsetNewest,
|
||||||
}, []string{config.Config.Kafka.MsgToPush.Topic}, config.Config.Kafka.Addr,
|
IsReturnErr: false,
|
||||||
config.Config.Kafka.ConsumerGroupID.MsgToPush)
|
UserName: config.Kafka.Username,
|
||||||
|
Password: config.Kafka.Password,
|
||||||
|
}, []string{config.Kafka.MsgToPush.Topic}, config.Kafka.Addr,
|
||||||
|
config.Kafka.ConsumerGroupID.MsgToPush,
|
||||||
|
tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -17,37 +17,37 @@ package push
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
pbpush "github.com/OpenIMSDK/protocol/push"
|
pbpush "github.com/OpenIMSDK/protocol/push"
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type pushServer struct {
|
type pushServer struct {
|
||||||
pusher *Pusher
|
pusher *Pusher
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cacheModel := cache.NewMsgCacheModel(rdb)
|
cacheModel := cache.NewMsgCacheModel(rdb, config)
|
||||||
offlinePusher := NewOfflinePusher(cacheModel)
|
offlinePusher := NewOfflinePusher(config, cacheModel)
|
||||||
database := controller.NewPushDatabase(cacheModel)
|
database := controller.NewPushDatabase(cacheModel)
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
conversationRpcClient := rpcclient.NewConversationRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
pusher := NewPusher(
|
pusher := NewPusher(
|
||||||
|
config,
|
||||||
client,
|
client,
|
||||||
offlinePusher,
|
offlinePusher,
|
||||||
database,
|
database,
|
||||||
@ -60,9 +60,10 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
|
|
||||||
pbpush.RegisterPushMsgServiceServer(server, &pushServer{
|
pbpush.RegisterPushMsgServiceServer(server, &pushServer{
|
||||||
pusher: pusher,
|
pusher: pusher,
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
|
|
||||||
consumer, err := NewConsumer(pusher)
|
consumer, err := NewConsumer(config, pusher)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/conversation"
|
"github.com/OpenIMSDK/protocol/conversation"
|
||||||
"github.com/OpenIMSDK/protocol/msggateway"
|
"github.com/OpenIMSDK/protocol/msggateway"
|
||||||
@ -32,7 +28,6 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/dummy"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/dummy"
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/fcm"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/fcm"
|
||||||
@ -45,9 +40,12 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Pusher struct {
|
type Pusher struct {
|
||||||
|
config *config.GlobalConfig
|
||||||
database controller.PushDatabase
|
database controller.PushDatabase
|
||||||
discov discoveryregistry.SvcDiscoveryRegistry
|
discov discoveryregistry.SvcDiscoveryRegistry
|
||||||
offlinePusher offlinepush.OfflinePusher
|
offlinePusher offlinepush.OfflinePusher
|
||||||
@ -60,11 +58,12 @@ type Pusher struct {
|
|||||||
|
|
||||||
var errNoOfflinePusher = errors.New("no offlinePusher is configured")
|
var errNoOfflinePusher = errors.New("no offlinePusher is configured")
|
||||||
|
|
||||||
func NewPusher(discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offlinepush.OfflinePusher, database controller.PushDatabase,
|
func NewPusher(config *config.GlobalConfig, 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,
|
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient,
|
||||||
) *Pusher {
|
) *Pusher {
|
||||||
return &Pusher{
|
return &Pusher{
|
||||||
|
config: config,
|
||||||
discov: discov,
|
discov: discov,
|
||||||
database: database,
|
database: database,
|
||||||
offlinePusher: offlinePusher,
|
offlinePusher: offlinePusher,
|
||||||
@ -76,15 +75,15 @@ func NewPusher(discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOfflinePusher(cache cache.MsgModel) offlinepush.OfflinePusher {
|
func NewOfflinePusher(config *config.GlobalConfig, cache cache.MsgModel) offlinepush.OfflinePusher {
|
||||||
var offlinePusher offlinepush.OfflinePusher
|
var offlinePusher offlinepush.OfflinePusher
|
||||||
switch config.Config.Push.Enable {
|
switch config.Push.Enable {
|
||||||
case "getui":
|
case "getui":
|
||||||
offlinePusher = getui.NewClient(cache)
|
offlinePusher = getui.NewClient(config, cache)
|
||||||
case "fcm":
|
case "fcm":
|
||||||
offlinePusher = fcm.NewClient(cache)
|
offlinePusher = fcm.NewClient(config, cache)
|
||||||
case "jpush":
|
case "jpush":
|
||||||
offlinePusher = jpush.NewClient()
|
offlinePusher = jpush.NewClient(config)
|
||||||
default:
|
default:
|
||||||
offlinePusher = dummy.NewClient()
|
offlinePusher = dummy.NewClient()
|
||||||
}
|
}
|
||||||
@ -102,7 +101,7 @@ func (p *Pusher) DeleteMemberAndSetConversationSeq(ctx context.Context, groupID
|
|||||||
|
|
||||||
func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
||||||
log.ZDebug(ctx, "Get msg from msg_transfer And push msg", "userIDs", userIDs, "msg", msg.String())
|
log.ZDebug(ctx, "Get msg from msg_transfer And push msg", "userIDs", userIDs, "msg", msg.String())
|
||||||
if err := callbackOnlinePush(ctx, userIDs, msg); err != nil {
|
if err := callbackOnlinePush(ctx, p.config, userIDs, msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// push
|
// push
|
||||||
@ -130,7 +129,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
|
|||||||
})
|
})
|
||||||
|
|
||||||
if len(offlinePushUserIDList) > 0 {
|
if len(offlinePushUserIDList) > 0 {
|
||||||
if err = callbackOfflinePush(ctx, offlinePushUserIDList, msg, &[]string{}); err != nil {
|
if err = callbackOfflinePush(ctx, p.config, offlinePushUserIDList, msg, &[]string{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = p.offlinePushMsg(ctx, msg.SendID, msg, offlinePushUserIDList)
|
err = p.offlinePushMsg(ctx, msg.SendID, msg, offlinePushUserIDList)
|
||||||
@ -163,7 +162,7 @@ func (p *Pusher) k8sOfflinePush2SuperGroup(ctx context.Context, groupID string,
|
|||||||
}
|
}
|
||||||
if len(needOfflinePushUserIDs) > 0 {
|
if len(needOfflinePushUserIDs) > 0 {
|
||||||
var offlinePushUserIDs []string
|
var offlinePushUserIDs []string
|
||||||
err := callbackOfflinePush(ctx, needOfflinePushUserIDs, msg, &offlinePushUserIDs)
|
err := callbackOfflinePush(ctx, p.config, needOfflinePushUserIDs, msg, &offlinePushUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -194,7 +193,7 @@ func (p *Pusher) k8sOfflinePush2SuperGroup(ctx context.Context, groupID string,
|
|||||||
func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws.MsgData) (err error) {
|
func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws.MsgData) (err error) {
|
||||||
log.ZDebug(ctx, "Get super group msg from msg_transfer and push msg", "msg", msg.String(), "groupID", groupID)
|
log.ZDebug(ctx, "Get super group msg from msg_transfer and push msg", "msg", msg.String(), "groupID", groupID)
|
||||||
var pushToUserIDs []string
|
var pushToUserIDs []string
|
||||||
if err = callbackBeforeSuperGroupOnlinePush(ctx, groupID, msg, &pushToUserIDs); err != nil {
|
if err = callbackBeforeSuperGroupOnlinePush(ctx, p.config, groupID, msg, &pushToUserIDs); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,17 +228,18 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
|
|||||||
}(groupID, kickedUsers)
|
}(groupID, kickedUsers)
|
||||||
pushToUserIDs = append(pushToUserIDs, kickedUsers...)
|
pushToUserIDs = append(pushToUserIDs, kickedUsers...)
|
||||||
case constant.GroupDismissedNotification:
|
case constant.GroupDismissedNotification:
|
||||||
if msgprocessor.IsNotification(msgprocessor.GetConversationIDByMsg(msg)) { // 消息先到,通知后到
|
// Messages arrive first, notifications arrive later
|
||||||
|
if msgprocessor.IsNotification(msgprocessor.GetConversationIDByMsg(msg)) {
|
||||||
var tips sdkws.GroupDismissedTips
|
var tips sdkws.GroupDismissedTips
|
||||||
if p.UnmarshalNotificationElem(msg.Content, &tips) != nil {
|
if p.UnmarshalNotificationElem(msg.Content, &tips) != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "GroupDismissedNotificationInfo****", "groupID", groupID, "num", len(pushToUserIDs), "list", pushToUserIDs)
|
log.ZInfo(ctx, "GroupDismissedNotificationInfo****", "groupID", groupID, "num", len(pushToUserIDs), "list", pushToUserIDs)
|
||||||
if len(config.Config.Manager.UserID) > 0 {
|
if len(p.config.Manager.UserID) > 0 {
|
||||||
ctx = mcontext.WithOpUserIDContext(ctx, config.Config.Manager.UserID[0])
|
ctx = mcontext.WithOpUserIDContext(ctx, p.config.Manager.UserID[0])
|
||||||
}
|
}
|
||||||
if len(config.Config.Manager.UserID) == 0 && len(config.Config.IMAdmin.UserID) > 0 {
|
if len(p.config.Manager.UserID) == 0 && len(p.config.IMAdmin.UserID) > 0 {
|
||||||
ctx = mcontext.WithOpUserIDContext(ctx, config.Config.IMAdmin.UserID[0])
|
ctx = mcontext.WithOpUserIDContext(ctx, p.config.IMAdmin.UserID[0])
|
||||||
}
|
}
|
||||||
defer func(groupID string) {
|
defer func(groupID string) {
|
||||||
if err = p.groupRpcClient.DismissGroup(ctx, groupID); err != nil {
|
if err = p.groupRpcClient.DismissGroup(ctx, groupID); err != nil {
|
||||||
@ -257,10 +257,10 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
|
|||||||
|
|
||||||
log.ZDebug(ctx, "get conn and online push success", "result", wsResults, "msg", msg)
|
log.ZDebug(ctx, "get conn and online push success", "result", wsResults, "msg", msg)
|
||||||
isOfflinePush := utils.GetSwitchFromOptions(msg.Options, constant.IsOfflinePush)
|
isOfflinePush := utils.GetSwitchFromOptions(msg.Options, constant.IsOfflinePush)
|
||||||
if isOfflinePush && config.Config.Envs.Discovery == "k8s" {
|
if isOfflinePush && p.config.Envs.Discovery == "k8s" {
|
||||||
return p.k8sOfflinePush2SuperGroup(ctx, groupID, msg, wsResults)
|
return p.k8sOfflinePush2SuperGroup(ctx, groupID, msg, wsResults)
|
||||||
}
|
}
|
||||||
if isOfflinePush && config.Config.Envs.Discovery == "zookeeper" {
|
if isOfflinePush && p.config.Envs.Discovery == "zookeeper" {
|
||||||
var (
|
var (
|
||||||
onlineSuccessUserIDs = []string{msg.SendID}
|
onlineSuccessUserIDs = []string{msg.SendID}
|
||||||
webAndPcBackgroundUserIDs []string
|
webAndPcBackgroundUserIDs []string
|
||||||
@ -298,7 +298,7 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
|
|||||||
// 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, p.config, needOfflinePushUserIDs, msg, &offlinePushUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -357,7 +357,7 @@ func (p *Pusher) k8sOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUs
|
|||||||
var (
|
var (
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
wg = errgroup.Group{}
|
wg = errgroup.Group{}
|
||||||
maxWorkers = config.Config.Push.MaxConcurrentWorkers
|
maxWorkers = p.config.Push.MaxConcurrentWorkers
|
||||||
)
|
)
|
||||||
if maxWorkers < 3 {
|
if maxWorkers < 3 {
|
||||||
maxWorkers = 3
|
maxWorkers = 3
|
||||||
@ -386,10 +386,10 @@ func (p *Pusher) k8sOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUs
|
|||||||
return wsResults, nil
|
return wsResults, nil
|
||||||
}
|
}
|
||||||
func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUserIDs []string) (wsResults []*msggateway.SingleMsgToUserResults, err error) {
|
func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUserIDs []string) (wsResults []*msggateway.SingleMsgToUserResults, err error) {
|
||||||
if config.Config.Envs.Discovery == "k8s" {
|
if p.config.Envs.Discovery == "k8s" {
|
||||||
return p.k8sOnlinePush(ctx, msg, pushToUserIDs)
|
return p.k8sOnlinePush(ctx, msg, pushToUserIDs)
|
||||||
}
|
}
|
||||||
conns, err := p.discov.GetConns(ctx, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := p.discov.GetConns(ctx, p.config.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
log.ZDebug(ctx, "get gateway conn", "conn length", len(conns))
|
log.ZDebug(ctx, "get gateway conn", "conn length", len(conns))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -399,7 +399,7 @@ func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData,
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
wg = errgroup.Group{}
|
wg = errgroup.Group{}
|
||||||
input = &msggateway.OnlineBatchPushOneMsgReq{MsgData: msg, PushToUserIDs: pushToUserIDs}
|
input = &msggateway.OnlineBatchPushOneMsgReq{MsgData: msg, PushToUserIDs: pushToUserIDs}
|
||||||
maxWorkers = config.Config.Push.MaxConcurrentWorkers
|
maxWorkers = p.config.Push.MaxConcurrentWorkers
|
||||||
)
|
)
|
||||||
|
|
||||||
if maxWorkers < 3 {
|
if maxWorkers < 3 {
|
||||||
|
@ -17,10 +17,6 @@ package auth
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
pbauth "github.com/OpenIMSDK/protocol/auth"
|
pbauth "github.com/OpenIMSDK/protocol/auth"
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/msggateway"
|
"github.com/OpenIMSDK/protocol/msggateway"
|
||||||
@ -29,42 +25,45 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/tokenverify"
|
"github.com/OpenIMSDK/tools/tokenverify"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type authServer struct {
|
type authServer struct {
|
||||||
authDatabase controller.AuthDatabase
|
authDatabase controller.AuthDatabase
|
||||||
userRpcClient *rpcclient.UserRpcClient
|
userRpcClient *rpcclient.UserRpcClient
|
||||||
RegisterCenter discoveryregistry.SvcDiscoveryRegistry
|
RegisterCenter discoveryregistry.SvcDiscoveryRegistry
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
pbauth.RegisterAuthServer(server, &authServer{
|
pbauth.RegisterAuthServer(server, &authServer{
|
||||||
userRpcClient: &userRpcClient,
|
userRpcClient: &userRpcClient,
|
||||||
RegisterCenter: client,
|
RegisterCenter: client,
|
||||||
authDatabase: controller.NewAuthDatabase(
|
authDatabase: controller.NewAuthDatabase(
|
||||||
cache.NewMsgCacheModel(rdb),
|
cache.NewMsgCacheModel(rdb, config),
|
||||||
config.Config.Secret,
|
config.Secret,
|
||||||
config.Config.TokenPolicy.Expire,
|
config.TokenPolicy.Expire,
|
||||||
|
config,
|
||||||
),
|
),
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) UserToken(ctx context.Context, req *pbauth.UserTokenReq) (*pbauth.UserTokenResp, error) {
|
func (s *authServer) UserToken(ctx context.Context, req *pbauth.UserTokenReq) (*pbauth.UserTokenResp, error) {
|
||||||
resp := pbauth.UserTokenResp{}
|
resp := pbauth.UserTokenResp{}
|
||||||
if req.Secret != config.Config.Secret {
|
if req.Secret != s.config.Secret {
|
||||||
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
||||||
}
|
}
|
||||||
if _, err := s.userRpcClient.GetUserInfo(ctx, req.UserID); err != nil {
|
if _, err := s.userRpcClient.GetUserInfo(ctx, req.UserID); err != nil {
|
||||||
@ -76,17 +75,17 @@ func (s *authServer) UserToken(ctx context.Context, req *pbauth.UserTokenReq) (*
|
|||||||
}
|
}
|
||||||
prommetrics.UserLoginCounter.Inc()
|
prommetrics.UserLoginCounter.Inc()
|
||||||
resp.Token = token
|
resp.Token = token
|
||||||
resp.ExpireTimeSeconds = config.Config.TokenPolicy.Expire * 24 * 60 * 60
|
resp.ExpireTimeSeconds = s.config.TokenPolicy.Expire * 24 * 60 * 60
|
||||||
return &resp, nil
|
return &resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenReq) (*pbauth.GetUserTokenResp, error) {
|
func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenReq) (*pbauth.GetUserTokenResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp := pbauth.GetUserTokenResp{}
|
resp := pbauth.GetUserTokenResp{}
|
||||||
|
|
||||||
if authverify.IsManagerUserID(req.UserID) {
|
if authverify.IsManagerUserID(req.UserID, s.config) {
|
||||||
return nil, errs.ErrNoPermission.Wrap("don't get Admin token")
|
return nil, errs.ErrNoPermission.Wrap("don't get Admin token")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,14 +97,14 @@ func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenR
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp.Token = token
|
resp.Token = token
|
||||||
resp.ExpireTimeSeconds = config.Config.TokenPolicy.Expire * 24 * 60 * 60
|
resp.ExpireTimeSeconds = s.config.TokenPolicy.Expire * 24 * 60 * 60
|
||||||
return &resp, nil
|
return &resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) parseToken(ctx context.Context, tokensString string) (claims *tokenverify.Claims, err error) {
|
func (s *authServer) parseToken(ctx context.Context, tokensString string) (claims *tokenverify.Claims, err error) {
|
||||||
claims, err = tokenverify.GetClaimFromToken(tokensString, authverify.Secret())
|
claims, err = tokenverify.GetClaimFromToken(tokensString, authverify.Secret(s.config.Secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, utils.Wrap(err, "")
|
return nil, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
m, err := s.authDatabase.GetTokensWithoutError(ctx, claims.UserID, claims.PlatformID)
|
m, err := s.authDatabase.GetTokensWithoutError(ctx, claims.UserID, claims.PlatformID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -121,7 +120,7 @@ func (s *authServer) parseToken(ctx context.Context, tokensString string) (claim
|
|||||||
case constant.KickedToken:
|
case constant.KickedToken:
|
||||||
return nil, errs.ErrTokenKicked.Wrap()
|
return nil, errs.ErrTokenKicked.Wrap()
|
||||||
default:
|
default:
|
||||||
return nil, utils.Wrap(errs.ErrTokenUnknown, "")
|
return nil, errs.Wrap(errs.ErrTokenUnknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, errs.ErrTokenNotExist.Wrap()
|
return nil, errs.ErrTokenNotExist.Wrap()
|
||||||
@ -143,7 +142,7 @@ func (s *authServer) ParseToken(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) ForceLogout(ctx context.Context, req *pbauth.ForceLogoutReq) (*pbauth.ForceLogoutResp, error) {
|
func (s *authServer) ForceLogout(ctx context.Context, req *pbauth.ForceLogoutReq) (*pbauth.ForceLogoutResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.forceKickOff(ctx, req.UserID, req.PlatformID, mcontext.GetOperationID(ctx)); err != nil {
|
if err := s.forceKickOff(ctx, req.UserID, req.PlatformID, mcontext.GetOperationID(ctx)); err != nil {
|
||||||
@ -153,7 +152,7 @@ func (s *authServer) ForceLogout(ctx context.Context, req *pbauth.ForceLogoutReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID int32, operationID string) error {
|
func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID int32, operationID string) error {
|
||||||
conns, err := s.RegisterCenter.GetConns(ctx, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := s.RegisterCenter.GetConns(ctx, s.config.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -19,28 +19,24 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
pbconversation "github.com/OpenIMSDK/protocol/conversation"
|
pbconversation "github.com/OpenIMSDK/protocol/conversation"
|
||||||
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type conversationServer struct {
|
type conversationServer struct {
|
||||||
@ -49,6 +45,7 @@ type conversationServer struct {
|
|||||||
groupRpcClient *rpcclient.GroupRpcClient
|
groupRpcClient *rpcclient.GroupRpcClient
|
||||||
conversationDatabase controller.ConversationDatabase
|
conversationDatabase controller.ConversationDatabase
|
||||||
conversationNotificationSender *notification.ConversationNotificationSender
|
conversationNotificationSender *notification.ConversationNotificationSender
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(
|
func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(
|
||||||
@ -59,28 +56,29 @@ func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase())
|
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
pbconversation.RegisterConversationServer(server, &conversationServer{
|
pbconversation.RegisterConversationServer(server, &conversationServer{
|
||||||
msgRpcClient: &msgRpcClient,
|
msgRpcClient: &msgRpcClient,
|
||||||
user: &userRpcClient,
|
user: &userRpcClient,
|
||||||
conversationNotificationSender: notification.NewConversationNotificationSender(&msgRpcClient),
|
conversationNotificationSender: notification.NewConversationNotificationSender(config, &msgRpcClient),
|
||||||
groupRpcClient: &groupRpcClient,
|
groupRpcClient: &groupRpcClient,
|
||||||
conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewMongo(mongo.GetClient())),
|
conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewMongo(mongo.GetClient())),
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -310,7 +308,7 @@ func (c *conversationServer) SetConversations(ctx context.Context,
|
|||||||
unequal++
|
unequal++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := c.conversationDatabase.SetUsersConversationFiledTx(ctx, req.UserIDs, &conversation, m); err != nil {
|
if err := c.conversationDatabase.SetUsersConversationFieldTx(ctx, req.UserIDs, &conversation, m); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if unequal > 0 {
|
if unequal > 0 {
|
||||||
@ -321,7 +319,7 @@ func (c *conversationServer) SetConversations(ctx context.Context,
|
|||||||
return &pbconversation.SetConversationsResp{}, nil
|
return &pbconversation.SetConversationsResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取超级大群开启免打扰的用户ID.
|
// Get user IDs with "Do Not Disturb" enabled in super large groups.
|
||||||
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 {
|
||||||
@ -378,7 +376,7 @@ func (c *conversationServer) CreateGroupChatConversations(ctx context.Context, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *conversationServer) SetConversationMaxSeq(ctx context.Context, req *pbconversation.SetConversationMaxSeqReq) (*pbconversation.SetConversationMaxSeqResp, error) {
|
func (c *conversationServer) SetConversationMaxSeq(ctx context.Context, req *pbconversation.SetConversationMaxSeqReq) (*pbconversation.SetConversationMaxSeqResp, error) {
|
||||||
if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, req.OwnerUserID, req.ConversationID,
|
if err := c.conversationDatabase.UpdateUsersConversationField(ctx, req.OwnerUserID, req.ConversationID,
|
||||||
map[string]any{"max_seq": req.MaxSeq}); err != nil {
|
map[string]any{"max_seq": req.MaxSeq}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
|
|
||||||
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
)
|
)
|
||||||
@ -67,7 +65,7 @@ func (s *friendServer) RemoveBlack(ctx context.Context, req *pbfriend.RemoveBlac
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) AddBlack(ctx context.Context, req *pbfriend.AddBlackReq) (*pbfriend.AddBlackResp, error) {
|
func (s *friendServer) AddBlack(ctx context.Context, req *pbfriend.AddBlackReq) (*pbfriend.AddBlackResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err := s.userRpcClient.GetUsersInfo(ctx, []string{req.OwnerUserID, req.BlackUserID})
|
_, err := s.userRpcClient.GetUsersInfo(ctx, []string{req.OwnerUserID, req.BlackUserID})
|
||||||
|
@ -19,14 +19,13 @@ import (
|
|||||||
|
|
||||||
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CallbackBeforeAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) error {
|
func CallbackBeforeAddFriend(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.ApplyToAddFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeAddFriend.Enable {
|
if !globalConfig.Callback.CallbackBeforeAddFriend.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeAddFriendReq{
|
cbReq := &cbapi.CallbackBeforeAddFriendReq{
|
||||||
@ -37,14 +36,14 @@ func CallbackBeforeAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriend
|
|||||||
Ex: req.Ex,
|
Ex: req.Ex,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeAddFriendResp{}
|
resp := &cbapi.CallbackBeforeAddFriendResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackBeforeSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) error {
|
func CallbackBeforeSetFriendRemark(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.SetFriendRemarkReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSetFriendRemark.Enable {
|
if !globalConfig.Callback.CallbackBeforeSetFriendRemark.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeSetFriendRemarkReq{
|
cbReq := &cbapi.CallbackBeforeSetFriendRemarkReq{
|
||||||
@ -54,15 +53,15 @@ func CallbackBeforeSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendR
|
|||||||
Remark: req.Remark,
|
Remark: req.Remark,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeSetFriendRemarkResp{}
|
resp := &cbapi.CallbackBeforeSetFriendRemarkResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
utils.NotNilReplace(&req.Remark, &resp.Remark)
|
utils.NotNilReplace(&req.Remark, &resp.Remark)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) error {
|
func CallbackAfterSetFriendRemark(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.SetFriendRemarkReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSetFriendRemark.Enable {
|
if !globalConfig.Callback.CallbackAfterSetFriendRemark.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterSetFriendRemarkReq{
|
cbReq := &cbapi.CallbackAfterSetFriendRemarkReq{
|
||||||
@ -72,13 +71,13 @@ func CallbackAfterSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRe
|
|||||||
Remark: req.Remark,
|
Remark: req.Remark,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterSetFriendRemarkResp{}
|
resp := &cbapi.CallbackAfterSetFriendRemarkResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeAddBlack(ctx context.Context, req *pbfriend.AddBlackReq) error {
|
func CallbackBeforeAddBlack(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.AddBlackReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeAddBlack.Enable {
|
if !globalConfig.Callback.CallbackBeforeAddBlack.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeAddBlackReq{
|
cbReq := &cbapi.CallbackBeforeAddBlackReq{
|
||||||
@ -87,13 +86,13 @@ func CallbackBeforeAddBlack(ctx context.Context, req *pbfriend.AddBlackReq) erro
|
|||||||
BlackUserID: req.BlackUserID,
|
BlackUserID: req.BlackUserID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeAddBlackResp{}
|
resp := &cbapi.CallbackBeforeAddBlackResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddBlack); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddBlack); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) error {
|
func CallbackAfterAddFriend(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.ApplyToAddFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterAddFriend.Enable {
|
if !globalConfig.Callback.CallbackAfterAddFriend.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterAddFriendReq{
|
cbReq := &cbapi.CallbackAfterAddFriendReq{
|
||||||
@ -103,14 +102,14 @@ func CallbackAfterAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendR
|
|||||||
ReqMsg: req.ReqMsg,
|
ReqMsg: req.ReqMsg,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterAddFriendResp{}
|
resp := &cbapi.CallbackAfterAddFriendResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterAddFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterAddFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeAddFriendAgree(ctx context.Context, req *pbfriend.RespondFriendApplyReq) error {
|
func CallbackBeforeAddFriendAgree(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.RespondFriendApplyReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeAddFriendAgree.Enable {
|
if !globalConfig.Callback.CallbackBeforeAddFriendAgree.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeAddFriendAgreeReq{
|
cbReq := &cbapi.CallbackBeforeAddFriendAgreeReq{
|
||||||
@ -121,13 +120,13 @@ func CallbackBeforeAddFriendAgree(ctx context.Context, req *pbfriend.RespondFrie
|
|||||||
HandleResult: req.HandleResult,
|
HandleResult: req.HandleResult,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeAddFriendAgreeResp{}
|
resp := &cbapi.CallbackBeforeAddFriendAgreeResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriendAgree); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddFriendAgree); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterDeleteFriend(ctx context.Context, req *pbfriend.DeleteFriendReq) error {
|
func CallbackAfterDeleteFriend(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.DeleteFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterDeleteFriend.Enable {
|
if !globalConfig.Callback.CallbackAfterDeleteFriend.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterDeleteFriendReq{
|
cbReq := &cbapi.CallbackAfterDeleteFriendReq{
|
||||||
@ -136,13 +135,13 @@ func CallbackAfterDeleteFriend(ctx context.Context, req *pbfriend.DeleteFriendRe
|
|||||||
FriendUserID: req.FriendUserID,
|
FriendUserID: req.FriendUserID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterDeleteFriendResp{}
|
resp := &cbapi.CallbackAfterDeleteFriendResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterDeleteFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterDeleteFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) error {
|
func CallbackBeforeImportFriends(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.ImportFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeImportFriends.Enable {
|
if !globalConfig.Callback.CallbackBeforeImportFriends.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeImportFriendsReq{
|
cbReq := &cbapi.CallbackBeforeImportFriendsReq{
|
||||||
@ -151,7 +150,7 @@ func CallbackBeforeImportFriends(ctx context.Context, req *pbfriend.ImportFriend
|
|||||||
FriendUserIDs: req.FriendUserIDs,
|
FriendUserIDs: req.FriendUserIDs,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeImportFriendsResp{}
|
resp := &cbapi.CallbackBeforeImportFriendsResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeImportFriends); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeImportFriends); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(resp.FriendUserIDs) != 0 {
|
if len(resp.FriendUserIDs) != 0 {
|
||||||
@ -159,8 +158,8 @@ func CallbackBeforeImportFriends(ctx context.Context, req *pbfriend.ImportFriend
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) error {
|
func CallbackAfterImportFriends(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.ImportFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterImportFriends.Enable {
|
if !globalConfig.Callback.CallbackAfterImportFriends.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterImportFriendsReq{
|
cbReq := &cbapi.CallbackAfterImportFriendsReq{
|
||||||
@ -169,14 +168,14 @@ func CallbackAfterImportFriends(ctx context.Context, req *pbfriend.ImportFriendR
|
|||||||
FriendUserIDs: req.FriendUserIDs,
|
FriendUserIDs: req.FriendUserIDs,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterImportFriendsResp{}
|
resp := &cbapi.CallbackAfterImportFriendsResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterImportFriends); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterImportFriends); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterRemoveBlack(ctx context.Context, req *pbfriend.RemoveBlackReq) error {
|
func CallbackAfterRemoveBlack(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.RemoveBlackReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterRemoveBlack.Enable {
|
if !globalConfig.Callback.CallbackAfterRemoveBlack.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterRemoveBlackReq{
|
cbReq := &cbapi.CallbackAfterRemoveBlackReq{
|
||||||
@ -185,7 +184,7 @@ func CallbackAfterRemoveBlack(ctx context.Context, req *pbfriend.RemoveBlackReq)
|
|||||||
BlackUserID: req.BlackUserID,
|
BlackUserID: req.BlackUserID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterRemoveBlackResp{}
|
resp := &cbapi.CallbackAfterRemoveBlackResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterRemoveBlack); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterRemoveBlack); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -17,31 +17,25 @@ package friend
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
||||||
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type friendServer struct {
|
type friendServer struct {
|
||||||
@ -51,42 +45,44 @@ type friendServer struct {
|
|||||||
notificationSender *notification.FriendNotificationSender
|
notificationSender *notification.FriendNotificationSender
|
||||||
conversationRpcClient rpcclient.ConversationRpcClient
|
conversationRpcClient rpcclient.ConversationRpcClient
|
||||||
RegisterCenter registry.SvcDiscoveryRegistry
|
RegisterCenter registry.SvcDiscoveryRegistry
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
// Initialize MongoDB
|
// Initialize MongoDB
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize Redis
|
// Initialize Redis
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
friendMongoDB, err := mgo.NewFriendMongo(mongo.GetDatabase())
|
friendMongoDB, err := mgo.NewFriendMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
friendRequestMongoDB, err := mgo.NewFriendRequestMongo(mongo.GetDatabase())
|
friendRequestMongoDB, err := mgo.NewFriendRequestMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
blackMongoDB, err := mgo.NewBlackMongo(mongo.GetDatabase())
|
blackMongoDB, err := mgo.NewBlackMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize RPC clients
|
// Initialize RPC clients
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
|
|
||||||
// Initialize notification sender
|
// Initialize notification sender
|
||||||
notificationSender := notification.NewFriendNotificationSender(
|
notificationSender := notification.NewFriendNotificationSender(
|
||||||
|
config,
|
||||||
&msgRpcClient,
|
&msgRpcClient,
|
||||||
notification.WithRpcFunc(userRpcClient.GetUsersInfo),
|
notification.WithRpcFunc(userRpcClient.GetUsersInfo),
|
||||||
)
|
)
|
||||||
@ -105,7 +101,8 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
|||||||
userRpcClient: &userRpcClient,
|
userRpcClient: &userRpcClient,
|
||||||
notificationSender: notificationSender,
|
notificationSender: notificationSender,
|
||||||
RegisterCenter: client,
|
RegisterCenter: client,
|
||||||
conversationRpcClient: rpcclient.NewConversationRpcClient(client),
|
conversationRpcClient: rpcclient.NewConversationRpcClient(client, config),
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -113,15 +110,14 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
|||||||
|
|
||||||
// ok.
|
// ok.
|
||||||
func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) (resp *pbfriend.ApplyToAddFriendResp, err error) {
|
func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) (resp *pbfriend.ApplyToAddFriendResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
|
||||||
resp = &pbfriend.ApplyToAddFriendResp{}
|
resp = &pbfriend.ApplyToAddFriendResp{}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.FromUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.FromUserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if req.ToUserID == req.FromUserID {
|
if req.ToUserID == req.FromUserID {
|
||||||
return nil, errs.ErrCanNotAddYourself.Wrap()
|
return nil, errs.ErrCanNotAddYourself.Wrap("req.ToUserID", req.ToUserID)
|
||||||
}
|
}
|
||||||
if err = CallbackBeforeAddFriend(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err = CallbackBeforeAddFriend(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if _, err := s.userRpcClient.GetUsersInfoMap(ctx, []string{req.ToUserID, req.FromUserID}); err != nil {
|
if _, err := s.userRpcClient.GetUsersInfoMap(ctx, []string{req.ToUserID, req.FromUserID}); err != nil {
|
||||||
@ -138,7 +134,7 @@ func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.Apply
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.notificationSender.FriendApplicationAddNotification(ctx, req)
|
s.notificationSender.FriendApplicationAddNotification(ctx, req)
|
||||||
if err = CallbackAfterAddFriend(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err = CallbackAfterAddFriend(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -147,7 +143,7 @@ func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.Apply
|
|||||||
// ok.
|
// ok.
|
||||||
func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) (resp *pbfriend.ImportFriendResp, err error) {
|
func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) (resp *pbfriend.ImportFriendResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if _, err := s.userRpcClient.GetUsersInfo(ctx, append([]string{req.OwnerUserID}, req.FriendUserIDs...)); err != nil {
|
if _, err := s.userRpcClient.GetUsersInfo(ctx, append([]string{req.OwnerUserID}, req.FriendUserIDs...)); err != nil {
|
||||||
@ -159,7 +155,7 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFr
|
|||||||
if utils.Duplicate(req.FriendUserIDs) {
|
if utils.Duplicate(req.FriendUserIDs) {
|
||||||
return nil, errs.ErrArgs.Wrap("friend userID repeated")
|
return nil, errs.ErrArgs.Wrap("friend userID repeated")
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeImportFriends(ctx, req); err != nil {
|
if err := CallbackBeforeImportFriends(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +169,7 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFr
|
|||||||
HandleResult: constant.FriendResponseAgree,
|
HandleResult: constant.FriendResponseAgree,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if err := CallbackAfterImportFriends(ctx, req); err != nil {
|
if err := CallbackAfterImportFriends(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &pbfriend.ImportFriendResp{}, nil
|
return &pbfriend.ImportFriendResp{}, nil
|
||||||
@ -183,7 +179,7 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFr
|
|||||||
func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.RespondFriendApplyReq) (resp *pbfriend.RespondFriendApplyResp, err error) {
|
func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.RespondFriendApplyReq) (resp *pbfriend.RespondFriendApplyResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||||
resp = &pbfriend.RespondFriendApplyResp{}
|
resp = &pbfriend.RespondFriendApplyResp{}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.ToUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.ToUserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +190,7 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.Res
|
|||||||
HandleResult: req.HandleResult,
|
HandleResult: req.HandleResult,
|
||||||
}
|
}
|
||||||
if req.HandleResult == constant.FriendResponseAgree {
|
if req.HandleResult == constant.FriendResponseAgree {
|
||||||
if err := CallbackBeforeAddFriendAgree(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err := CallbackBeforeAddFriendAgree(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err := s.friendDatabase.AgreeFriendRequest(ctx, &friendRequest)
|
err := s.friendDatabase.AgreeFriendRequest(ctx, &friendRequest)
|
||||||
@ -230,7 +226,7 @@ func (s *friendServer) DeleteFriend(ctx context.Context, req *pbfriend.DeleteFri
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.notificationSender.FriendDeletedNotification(ctx, req)
|
s.notificationSender.FriendDeletedNotification(ctx, req)
|
||||||
if err := CallbackAfterDeleteFriend(ctx, req); err != nil {
|
if err := CallbackAfterDeleteFriend(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -240,7 +236,7 @@ func (s *friendServer) DeleteFriend(ctx context.Context, req *pbfriend.DeleteFri
|
|||||||
func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) (resp *pbfriend.SetFriendRemarkResp, err error) {
|
func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) (resp *pbfriend.SetFriendRemarkResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||||
|
|
||||||
if err = CallbackBeforeSetFriendRemark(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err = CallbackBeforeSetFriendRemark(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp = &pbfriend.SetFriendRemarkResp{}
|
resp = &pbfriend.SetFriendRemarkResp{}
|
||||||
@ -254,7 +250,7 @@ func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFri
|
|||||||
if err := s.friendDatabase.UpdateRemark(ctx, req.OwnerUserID, req.FriendUserID, req.Remark); err != nil {
|
if err := s.friendDatabase.UpdateRemark(ctx, req.OwnerUserID, req.FriendUserID, req.Remark); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := CallbackAfterSetFriendRemark(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err := CallbackAfterSetFriendRemark(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.notificationSender.FriendRemarkSetNotification(ctx, req.OwnerUserID, req.FriendUserID)
|
s.notificationSender.FriendRemarkSetNotification(ctx, req.OwnerUserID, req.FriendUserID)
|
||||||
@ -278,6 +274,7 @@ func (s *friendServer) GetDesignatedFriends(ctx context.Context, req *pbfriend.G
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the list of friend requests sent out proactively.
|
||||||
func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context,
|
func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context,
|
||||||
req *pbfriend.GetDesignatedFriendsApplyReq) (resp *pbfriend.GetDesignatedFriendsApplyResp, err error) {
|
req *pbfriend.GetDesignatedFriendsApplyReq) (resp *pbfriend.GetDesignatedFriendsApplyResp, err error) {
|
||||||
friendRequests, err := s.friendDatabase.FindBothFriendRequests(ctx, req.FromUserID, req.ToUserID)
|
friendRequests, err := s.friendDatabase.FindBothFriendRequests(ctx, req.FromUserID, req.ToUserID)
|
||||||
@ -292,7 +289,7 @@ func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context,
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok 获取接收到的好友申请(即别人主动申请的).
|
// Get received friend requests (i.e., those initiated by others).
|
||||||
func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyToReq) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) {
|
func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyToReq) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||||
@ -311,7 +308,6 @@ func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *pbf
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok 获取主动发出去的好友申请列表.
|
|
||||||
func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyFromReq) (resp *pbfriend.GetPaginationFriendsApplyFromResp, err error) {
|
func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyFromReq) (resp *pbfriend.GetPaginationFriendsApplyFromResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||||
resp = &pbfriend.GetPaginationFriendsApplyFromResp{}
|
resp = &pbfriend.GetPaginationFriendsApplyFromResp{}
|
||||||
|
@ -18,7 +18,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
pbgroup "github.com/OpenIMSDK/protocol/group"
|
pbgroup "github.com/OpenIMSDK/protocol/group"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,16 +18,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/group"
|
"github.com/OpenIMSDK/protocol/group"
|
||||||
|
pbgroup "github.com/OpenIMSDK/protocol/group"
|
||||||
"github.com/OpenIMSDK/protocol/wrapperspb"
|
"github.com/OpenIMSDK/protocol/wrapperspb"
|
||||||
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
pbgroup "github.com/OpenIMSDK/protocol/group"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
"github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
@ -35,8 +32,8 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (err error) {
|
func CallbackBeforeCreateGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.CreateGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeCreateGroup.Enable {
|
if !globalConfig.Callback.CallbackBeforeCreateGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &callbackstruct.CallbackBeforeCreateGroupReq{
|
cbReq := &callbackstruct.CallbackBeforeCreateGroupReq{
|
||||||
@ -61,7 +58,7 @@ func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackBeforeCreateGroupResp{}
|
resp := &callbackstruct.CallbackBeforeCreateGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeCreateGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeCreateGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
utils.NotNilReplace(&req.GroupInfo.GroupID, resp.GroupID)
|
utils.NotNilReplace(&req.GroupInfo.GroupID, resp.GroupID)
|
||||||
@ -79,8 +76,8 @@ func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterCreateGroup(ctx context.Context, req *group.CreateGroupReq) (err error) {
|
func CallbackAfterCreateGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.CreateGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackAfterCreateGroup.Enable {
|
if !globalConfig.Callback.CallbackAfterCreateGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &callbackstruct.CallbackAfterCreateGroupReq{
|
cbReq := &callbackstruct.CallbackAfterCreateGroupReq{
|
||||||
@ -104,7 +101,7 @@ func CallbackAfterCreateGroup(ctx context.Context, req *group.CreateGroupReq) (e
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackAfterCreateGroupResp{}
|
resp := &callbackstruct.CallbackAfterCreateGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterCreateGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterCreateGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -112,10 +109,11 @@ func CallbackAfterCreateGroup(ctx context.Context, req *group.CreateGroupReq) (e
|
|||||||
|
|
||||||
func CallbackBeforeMemberJoinGroup(
|
func CallbackBeforeMemberJoinGroup(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
globalConfig *config.GlobalConfig,
|
||||||
groupMember *relation.GroupMemberModel,
|
groupMember *relation.GroupMemberModel,
|
||||||
groupEx string,
|
groupEx string,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeMemberJoinGroup.Enable {
|
if !globalConfig.Callback.CallbackBeforeMemberJoinGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &callbackstruct.CallbackBeforeMemberJoinGroupReq{
|
callbackReq := &callbackstruct.CallbackBeforeMemberJoinGroupReq{
|
||||||
@ -128,10 +126,10 @@ func CallbackBeforeMemberJoinGroup(
|
|||||||
resp := &callbackstruct.CallbackBeforeMemberJoinGroupResp{}
|
resp := &callbackstruct.CallbackBeforeMemberJoinGroupResp{}
|
||||||
err = http.CallBackPostReturn(
|
err = http.CallBackPostReturn(
|
||||||
ctx,
|
ctx,
|
||||||
config.Config.Callback.CallbackUrl,
|
globalConfig.Callback.CallbackUrl,
|
||||||
callbackReq,
|
callbackReq,
|
||||||
resp,
|
resp,
|
||||||
config.Config.Callback.CallbackBeforeMemberJoinGroup,
|
globalConfig.Callback.CallbackBeforeMemberJoinGroup,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -146,8 +144,8 @@ func CallbackBeforeMemberJoinGroup(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMemberInfo) (err error) {
|
func CallbackBeforeSetGroupMemberInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *group.SetGroupMemberInfo) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeSetGroupMemberInfo.Enable {
|
if !globalConfig.Callback.CallbackBeforeSetGroupMemberInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := callbackstruct.CallbackBeforeSetGroupMemberInfoReq{
|
callbackReq := callbackstruct.CallbackBeforeSetGroupMemberInfoReq{
|
||||||
@ -170,10 +168,10 @@ func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMe
|
|||||||
resp := &callbackstruct.CallbackBeforeSetGroupMemberInfoResp{}
|
resp := &callbackstruct.CallbackBeforeSetGroupMemberInfoResp{}
|
||||||
err = http.CallBackPostReturn(
|
err = http.CallBackPostReturn(
|
||||||
ctx,
|
ctx,
|
||||||
config.Config.Callback.CallbackUrl,
|
globalConfig.Callback.CallbackUrl,
|
||||||
callbackReq,
|
callbackReq,
|
||||||
resp,
|
resp,
|
||||||
config.Config.Callback.CallbackBeforeSetGroupMemberInfo,
|
globalConfig.Callback.CallbackBeforeSetGroupMemberInfo,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -192,8 +190,8 @@ func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMe
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMemberInfo) (err error) {
|
func CallbackAfterSetGroupMemberInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *group.SetGroupMemberInfo) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeSetGroupMemberInfo.Enable {
|
if !globalConfig.Callback.CallbackBeforeSetGroupMemberInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := callbackstruct.CallbackAfterSetGroupMemberInfoReq{
|
callbackReq := callbackstruct.CallbackAfterSetGroupMemberInfoReq{
|
||||||
@ -214,14 +212,14 @@ func CallbackAfterSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMem
|
|||||||
callbackReq.Ex = &req.Ex.Value
|
callbackReq.Ex = &req.Ex.Value
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackAfterSetGroupMemberInfoResp{}
|
resp := &callbackstruct.CallbackAfterSetGroupMemberInfoResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterSetGroupMemberInfo); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackAfterSetGroupMemberInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackQuitGroup(ctx context.Context, req *group.QuitGroupReq) (err error) {
|
func CallbackQuitGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.QuitGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackQuitGroup.Enable {
|
if !globalConfig.Callback.CallbackQuitGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &callbackstruct.CallbackQuitGroupReq{
|
cbReq := &callbackstruct.CallbackQuitGroupReq{
|
||||||
@ -230,14 +228,14 @@ func CallbackQuitGroup(ctx context.Context, req *group.QuitGroupReq) (err error)
|
|||||||
UserID: req.UserID,
|
UserID: req.UserID,
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackQuitGroupResp{}
|
resp := &callbackstruct.CallbackQuitGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackQuitGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackQuitGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackKillGroupMember(ctx context.Context, req *pbgroup.KickGroupMemberReq) (err error) {
|
func CallbackKillGroupMember(ctx context.Context, globalConfig *config.GlobalConfig, req *pbgroup.KickGroupMemberReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackKillGroupMember.Enable {
|
if !globalConfig.Callback.CallbackKillGroupMember.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &callbackstruct.CallbackKillGroupMemberReq{
|
cbReq := &callbackstruct.CallbackKillGroupMemberReq{
|
||||||
@ -246,41 +244,41 @@ func CallbackKillGroupMember(ctx context.Context, req *pbgroup.KickGroupMemberRe
|
|||||||
KickedUserIDs: req.KickedUserIDs,
|
KickedUserIDs: req.KickedUserIDs,
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackKillGroupMemberResp{}
|
resp := &callbackstruct.CallbackKillGroupMemberResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackQuitGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackQuitGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackDismissGroup(ctx context.Context, req *callbackstruct.CallbackDisMissGroupReq) (err error) {
|
func CallbackDismissGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *callbackstruct.CallbackDisMissGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackDismissGroup.Enable {
|
if !globalConfig.Callback.CallbackDismissGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req.CallbackCommand = callbackstruct.CallbackDisMissGroupCommand
|
req.CallbackCommand = callbackstruct.CallbackDisMissGroupCommand
|
||||||
resp := &callbackstruct.CallbackDisMissGroupResp{}
|
resp := &callbackstruct.CallbackDisMissGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackQuitGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackQuitGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackApplyJoinGroupBefore(ctx context.Context, req *callbackstruct.CallbackJoinGroupReq) (err error) {
|
func CallbackApplyJoinGroupBefore(ctx context.Context, globalConfig *config.GlobalConfig, req *callbackstruct.CallbackJoinGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeJoinGroup.Enable {
|
if !globalConfig.Callback.CallbackBeforeJoinGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
req.CallbackCommand = callbackstruct.CallbackBeforeJoinGroupCommand
|
req.CallbackCommand = callbackstruct.CallbackBeforeJoinGroupCommand
|
||||||
|
|
||||||
resp := &callbackstruct.CallbackJoinGroupResp{}
|
resp := &callbackstruct.CallbackJoinGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackBeforeJoinGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackBeforeJoinGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterTransferGroupOwner(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (err error) {
|
func CallbackAfterTransferGroupOwner(ctx context.Context, globalConfig *config.GlobalConfig, req *pbgroup.TransferGroupOwnerReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackAfterTransferGroupOwner.Enable {
|
if !globalConfig.Callback.CallbackAfterTransferGroupOwner.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,13 +290,13 @@ func CallbackAfterTransferGroupOwner(ctx context.Context, req *pbgroup.TransferG
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := &callbackstruct.CallbackTransferGroupOwnerResp{}
|
resp := &callbackstruct.CallbackTransferGroupOwnerResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterTransferGroupOwner); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterTransferGroupOwner); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeInviteUserToGroup(ctx context.Context, req *group.InviteUserToGroupReq) (err error) {
|
func CallbackBeforeInviteUserToGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.InviteUserToGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeInviteUserToGroup.Enable {
|
if !globalConfig.Callback.CallbackBeforeInviteUserToGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,10 +311,10 @@ func CallbackBeforeInviteUserToGroup(ctx context.Context, req *group.InviteUserT
|
|||||||
resp := &callbackstruct.CallbackBeforeInviteUserToGroupResp{}
|
resp := &callbackstruct.CallbackBeforeInviteUserToGroupResp{}
|
||||||
err = http.CallBackPostReturn(
|
err = http.CallBackPostReturn(
|
||||||
ctx,
|
ctx,
|
||||||
config.Config.Callback.CallbackUrl,
|
globalConfig.Callback.CallbackUrl,
|
||||||
callbackReq,
|
callbackReq,
|
||||||
resp,
|
resp,
|
||||||
config.Config.Callback.CallbackBeforeInviteUserToGroup,
|
globalConfig.Callback.CallbackBeforeInviteUserToGroup,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -330,8 +328,8 @@ func CallbackBeforeInviteUserToGroup(ctx context.Context, req *group.InviteUserT
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterJoinGroup(ctx context.Context, req *group.JoinGroupReq) error {
|
func CallbackAfterJoinGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.JoinGroupReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterJoinGroup.Enable {
|
if !globalConfig.Callback.CallbackAfterJoinGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &callbackstruct.CallbackAfterJoinGroupReq{
|
callbackReq := &callbackstruct.CallbackAfterJoinGroupReq{
|
||||||
@ -343,14 +341,14 @@ func CallbackAfterJoinGroup(ctx context.Context, req *group.JoinGroupReq) error
|
|||||||
InviterUserID: req.InviterUserID,
|
InviterUserID: req.InviterUserID,
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackAfterJoinGroupResp{}
|
resp := &callbackstruct.CallbackAfterJoinGroupResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterJoinGroup); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackAfterJoinGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackBeforeSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq) error {
|
func CallbackBeforeSetGroupInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *group.SetGroupInfoReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSetGroupInfo.Enable {
|
if !globalConfig.Callback.CallbackBeforeSetGroupInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &callbackstruct.CallbackBeforeSetGroupInfoReq{
|
callbackReq := &callbackstruct.CallbackBeforeSetGroupInfoReq{
|
||||||
@ -377,7 +375,7 @@ func CallbackBeforeSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq)
|
|||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackBeforeSetGroupInfoResp{}
|
resp := &callbackstruct.CallbackBeforeSetGroupInfoResp{}
|
||||||
|
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackBeforeSetGroupInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackBeforeSetGroupInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,8 +397,8 @@ func CallbackBeforeSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq)
|
|||||||
utils.NotNilReplace(&req.GroupInfoForSet.Introduction, &resp.Introduction)
|
utils.NotNilReplace(&req.GroupInfoForSet.Introduction, &resp.Introduction)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq) error {
|
func CallbackAfterSetGroupInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *group.SetGroupInfoReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSetGroupInfo.Enable {
|
if !globalConfig.Callback.CallbackAfterSetGroupInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &callbackstruct.CallbackAfterSetGroupInfoReq{
|
callbackReq := &callbackstruct.CallbackAfterSetGroupInfoReq{
|
||||||
@ -424,7 +422,7 @@ func CallbackAfterSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq)
|
|||||||
callbackReq.ApplyMemberFriend = &req.GroupInfoForSet.ApplyMemberFriend.Value
|
callbackReq.ApplyMemberFriend = &req.GroupInfoForSet.ApplyMemberFriend.Value
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackAfterSetGroupInfoResp{}
|
resp := &callbackstruct.CallbackAfterSetGroupInfoResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterSetGroupInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackAfterSetGroupInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -16,7 +16,6 @@ package group
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,10 +18,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
|
||||||
|
|
||||||
pbgroup "github.com/OpenIMSDK/protocol/group"
|
pbgroup "github.com/OpenIMSDK/protocol/group"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSet) map[string]any {
|
func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSet) map[string]any {
|
||||||
|
@ -23,71 +23,63 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
|
||||||
|
|
||||||
pbconversation "github.com/OpenIMSDK/protocol/conversation"
|
|
||||||
"github.com/OpenIMSDK/protocol/wrapperspb"
|
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/grouphash"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/mw/specialerror"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
pbconversation "github.com/OpenIMSDK/protocol/conversation"
|
||||||
pbgroup "github.com/OpenIMSDK/protocol/group"
|
pbgroup "github.com/OpenIMSDK/protocol/group"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
"github.com/OpenIMSDK/protocol/wrapperspb"
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
|
"github.com/OpenIMSDK/tools/mw/specialerror"
|
||||||
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/grouphash"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase())
|
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase())
|
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase())
|
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
conversationRpcClient := rpcclient.NewConversationRpcClient(client, config)
|
||||||
var gs groupServer
|
var gs groupServer
|
||||||
database := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, tx.NewMongo(mongo.GetClient()), grouphash.NewGroupHashFromGroupServer(&gs))
|
database := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, tx.NewMongo(mongo.GetClient()), grouphash.NewGroupHashFromGroupServer(&gs))
|
||||||
gs.db = database
|
gs.db = database
|
||||||
gs.User = userRpcClient
|
gs.User = userRpcClient
|
||||||
gs.Notification = notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
gs.Notification = notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, config, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
||||||
users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -96,6 +88,7 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
})
|
})
|
||||||
gs.conversationRpcClient = conversationRpcClient
|
gs.conversationRpcClient = conversationRpcClient
|
||||||
gs.msgRpcClient = msgRpcClient
|
gs.msgRpcClient = msgRpcClient
|
||||||
|
gs.config = config
|
||||||
pbgroup.RegisterGroupServer(server, &gs)
|
pbgroup.RegisterGroupServer(server, &gs)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -106,6 +99,7 @@ type groupServer struct {
|
|||||||
Notification *notification.GroupNotificationSender
|
Notification *notification.GroupNotificationSender
|
||||||
conversationRpcClient rpcclient.ConversationRpcClient
|
conversationRpcClient rpcclient.ConversationRpcClient
|
||||||
msgRpcClient rpcclient.MessageRpcClient
|
msgRpcClient rpcclient.MessageRpcClient
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) GetJoinedGroupIDs(ctx context.Context, req *pbgroup.GetJoinedGroupIDsReq) (*pbgroup.GetJoinedGroupIDsResp, error) {
|
func (s *groupServer) GetJoinedGroupIDs(ctx context.Context, req *pbgroup.GetJoinedGroupIDsReq) (*pbgroup.GetJoinedGroupIDsResp, error) {
|
||||||
@ -114,7 +108,6 @@ func (s *groupServer) GetJoinedGroupIDs(ctx context.Context, req *pbgroup.GetJoi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgroup.NotificationUserInfoUpdateReq) (*pbgroup.NotificationUserInfoUpdateResp, error) {
|
func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgroup.NotificationUserInfoUpdateReq) (*pbgroup.NotificationUserInfoUpdateResp, error) {
|
||||||
defer log.ZDebug(ctx, "NotificationUserInfoUpdate return")
|
|
||||||
members, err := s.db.FindGroupMemberUser(ctx, nil, req.UserID)
|
members, err := s.db.FindGroupMemberUser(ctx, nil, req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -126,21 +119,20 @@ func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgro
|
|||||||
}
|
}
|
||||||
groupIDs = append(groupIDs, member.GroupID)
|
groupIDs = append(groupIDs, member.GroupID)
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "NotificationUserInfoUpdate", "joinGroupNum", len(members), "updateNum", len(groupIDs), "updateGroupIDs", groupIDs)
|
|
||||||
for _, groupID := range groupIDs {
|
for _, groupID := range groupIDs {
|
||||||
if err := s.Notification.GroupMemberInfoSetNotification(ctx, groupID, req.UserID); err != nil {
|
if err = s.Notification.GroupMemberInfoSetNotification(ctx, groupID, req.UserID); err != nil {
|
||||||
log.ZError(ctx, "NotificationUserInfoUpdate setGroupMemberInfo notification failed", err, "groupID", groupID)
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := s.db.DeleteGroupMemberHash(ctx, groupIDs); err != nil {
|
if err = s.db.DeleteGroupMemberHash(ctx, groupIDs); err != nil {
|
||||||
log.ZError(ctx, "NotificationUserInfoUpdate DeleteGroupMemberHash", err, "groupID", groupIDs)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pbgroup.NotificationUserInfoUpdateResp{}, nil
|
return &pbgroup.NotificationUserInfoUpdateResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error {
|
func (s *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error {
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
groupMember, err := s.db.TakeGroupMember(ctx, groupID, mcontext.GetOpUserID(ctx))
|
groupMember, err := s.db.TakeGroupMember(ctx, groupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -205,7 +197,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
if req.OwnerUserID == "" {
|
if req.OwnerUserID == "" {
|
||||||
return nil, errs.ErrArgs.Wrap("no group owner")
|
return nil, errs.ErrArgs.Wrap("no group owner")
|
||||||
}
|
}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userIDs := append(append(req.MemberUserIDs, req.AdminUserIDs...), req.OwnerUserID)
|
userIDs := append(append(req.MemberUserIDs, req.AdminUserIDs...), req.OwnerUserID)
|
||||||
@ -224,7 +216,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
return nil, errs.ErrUserIDNotFound.Wrap("user not found")
|
return nil, errs.ErrUserIDNotFound.Wrap("user not found")
|
||||||
}
|
}
|
||||||
// Callback Before create Group
|
// Callback Before create Group
|
||||||
if err := CallbackBeforeCreateGroup(ctx, req); err != nil {
|
if err := CallbackBeforeCreateGroup(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var groupMembers []*relationtb.GroupMemberModel
|
var groupMembers []*relationtb.GroupMemberModel
|
||||||
@ -243,7 +235,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
JoinTime: time.Now(),
|
JoinTime: time.Now(),
|
||||||
MuteEndTime: time.UnixMilli(0),
|
MuteEndTime: time.UnixMilli(0),
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeMemberJoinGroup(ctx, groupMember, group.Ex); err != nil {
|
if err := CallbackBeforeMemberJoinGroup(ctx, s.config, groupMember, group.Ex); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupMembers = append(groupMembers, groupMember)
|
groupMembers = append(groupMembers, groupMember)
|
||||||
@ -311,7 +303,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
AdminUserIDs: req.AdminUserIDs,
|
AdminUserIDs: req.AdminUserIDs,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackAfterCreateGroup(ctx, reqCallBackAfter); err != nil {
|
if err := CallbackAfterCreateGroup(ctx, s.config, reqCallBackAfter); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +312,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
|
|
||||||
func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbgroup.GetJoinedGroupListReq) (*pbgroup.GetJoinedGroupListResp, error) {
|
func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbgroup.GetJoinedGroupListReq) (*pbgroup.GetJoinedGroupListResp, error) {
|
||||||
resp := &pbgroup.GetJoinedGroupListResp{}
|
resp := &pbgroup.GetJoinedGroupListResp{}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.FromUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.FromUserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
total, members, err := s.db.PageGetJoinGroup(ctx, req.FromUserID, req.Pagination)
|
total, members, err := s.db.PageGetJoinGroup(ctx, req.FromUserID, req.Pagination)
|
||||||
@ -390,7 +382,7 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
|||||||
}
|
}
|
||||||
var groupMember *relationtb.GroupMemberModel
|
var groupMember *relationtb.GroupMemberModel
|
||||||
var opUserID string
|
var opUserID string
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
opUserID = mcontext.GetOpUserID(ctx)
|
opUserID = mcontext.GetOpUserID(ctx)
|
||||||
var err error
|
var err error
|
||||||
groupMember, err = s.db.TakeGroupMember(ctx, req.GroupID, opUserID)
|
groupMember, err = s.db.TakeGroupMember(ctx, req.GroupID, opUserID)
|
||||||
@ -402,11 +394,11 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackBeforeInviteUserToGroup(ctx, req); err != nil {
|
if err := CallbackBeforeInviteUserToGroup(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if group.NeedVerification == constant.AllNeedVerification {
|
if group.NeedVerification == constant.AllNeedVerification {
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
if !(groupMember.RoleLevel == constant.GroupOwner || groupMember.RoleLevel == constant.GroupAdmin) {
|
if !(groupMember.RoleLevel == constant.GroupOwner || groupMember.RoleLevel == constant.GroupAdmin) {
|
||||||
var requests []*relationtb.GroupRequestModel
|
var requests []*relationtb.GroupRequestModel
|
||||||
for _, userID := range req.InvitedUserIDs {
|
for _, userID := range req.InvitedUserIDs {
|
||||||
@ -446,7 +438,7 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
|||||||
JoinTime: time.Now(),
|
JoinTime: time.Now(),
|
||||||
MuteEndTime: time.UnixMilli(0),
|
MuteEndTime: time.UnixMilli(0),
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeMemberJoinGroup(ctx, member, group.Ex); err != nil {
|
if err := CallbackBeforeMemberJoinGroup(ctx, s.config, member, group.Ex); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
groupMembers = append(groupMembers, member)
|
groupMembers = append(groupMembers, member)
|
||||||
@ -546,7 +538,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbgroup.KickGrou
|
|||||||
for i, member := range members {
|
for i, member := range members {
|
||||||
memberMap[member.UserID] = members[i]
|
memberMap[member.UserID] = members[i]
|
||||||
}
|
}
|
||||||
isAppManagerUid := authverify.IsAppManagerUid(ctx)
|
isAppManagerUid := authverify.IsAppManagerUid(ctx, s.config)
|
||||||
opMember := memberMap[opUserID]
|
opMember := memberMap[opUserID]
|
||||||
for _, userID := range req.KickedUserIDs {
|
for _, userID := range req.KickedUserIDs {
|
||||||
member, ok := memberMap[userID]
|
member, ok := memberMap[userID]
|
||||||
@ -618,7 +610,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbgroup.KickGrou
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackKillGroupMember(ctx, req); err != nil {
|
if err := CallbackKillGroupMember(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -744,7 +736,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup
|
|||||||
if !utils.Contain(req.HandleResult, constant.GroupResponseAgree, constant.GroupResponseRefuse) {
|
if !utils.Contain(req.HandleResult, constant.GroupResponseAgree, constant.GroupResponseRefuse) {
|
||||||
return nil, errs.ErrArgs.Wrap("HandleResult unknown")
|
return nil, errs.ErrArgs.Wrap("HandleResult unknown")
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
groupMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
groupMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -765,8 +757,8 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup
|
|||||||
return nil, errs.ErrGroupRequestHandled.Wrap("group request already processed")
|
return nil, errs.ErrGroupRequestHandled.Wrap("group request already processed")
|
||||||
}
|
}
|
||||||
var inGroup bool
|
var inGroup bool
|
||||||
if _, err := s.db.TakeGroupMember(ctx, req.GroupID, req.FromUserID); err == nil {
|
if _, takeErr := s.db.TakeGroupMember(ctx, req.GroupID, req.FromUserID); takeErr == nil {
|
||||||
inGroup = true // 已经在群里了
|
inGroup = true // Already in group
|
||||||
} else if !s.IsNotFound(err) {
|
} else if !s.IsNotFound(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -788,7 +780,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup
|
|||||||
OperatorUserID: mcontext.GetOpUserID(ctx),
|
OperatorUserID: mcontext.GetOpUserID(ctx),
|
||||||
Ex: groupRequest.Ex,
|
Ex: groupRequest.Ex,
|
||||||
}
|
}
|
||||||
if err = CallbackBeforeMemberJoinGroup(ctx, member, group.Ex); err != nil {
|
if err = CallbackBeforeMemberJoinGroup(ctx, s.config, member, group.Ex); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -836,7 +828,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
|
|||||||
Ex: req.Ex,
|
Ex: req.Ex,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CallbackApplyJoinGroupBefore(ctx, reqCall); err != nil {
|
if err = CallbackApplyJoinGroupBefore(ctx, s.config, reqCall); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = s.db.TakeGroupMember(ctx, req.GroupID, req.InviterUserID)
|
_, err = s.db.TakeGroupMember(ctx, req.GroupID, req.InviterUserID)
|
||||||
@ -857,7 +849,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
|
|||||||
JoinTime: time.Now(),
|
JoinTime: time.Now(),
|
||||||
MuteEndTime: time.UnixMilli(0),
|
MuteEndTime: time.UnixMilli(0),
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeMemberJoinGroup(ctx, groupMember, group.Ex); err != nil {
|
if err := CallbackBeforeMemberJoinGroup(ctx, s.config, groupMember, group.Ex); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.db.CreateGroup(ctx, nil, []*relationtb.GroupMemberModel{groupMember}); err != nil {
|
if err := s.db.CreateGroup(ctx, nil, []*relationtb.GroupMemberModel{groupMember}); err != nil {
|
||||||
@ -868,7 +860,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.MemberEnterNotification(ctx, req.GroupID, req.InviterUserID)
|
s.Notification.MemberEnterNotification(ctx, req.GroupID, req.InviterUserID)
|
||||||
if err = CallbackAfterJoinGroup(ctx, req); err != nil {
|
if err = CallbackAfterJoinGroup(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -882,7 +874,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
|
|||||||
HandledTime: time.Unix(0, 0),
|
HandledTime: time.Unix(0, 0),
|
||||||
Ex: req.Ex,
|
Ex: req.Ex,
|
||||||
}
|
}
|
||||||
if err := s.db.CreateGroupRequest(ctx, []*relationtb.GroupRequestModel{&groupRequest}); err != nil {
|
if err = s.db.CreateGroupRequest(ctx, []*relationtb.GroupRequestModel{&groupRequest}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.JoinGroupApplicationNotification(ctx, req)
|
s.Notification.JoinGroupApplicationNotification(ctx, req)
|
||||||
@ -894,7 +886,7 @@ func (s *groupServer) QuitGroup(ctx context.Context, req *pbgroup.QuitGroupReq)
|
|||||||
if req.UserID == "" {
|
if req.UserID == "" {
|
||||||
req.UserID = mcontext.GetOpUserID(ctx)
|
req.UserID = mcontext.GetOpUserID(ctx)
|
||||||
} else {
|
} else {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -918,7 +910,7 @@ func (s *groupServer) QuitGroup(ctx context.Context, req *pbgroup.QuitGroupReq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// callback
|
// callback
|
||||||
if err := CallbackQuitGroup(ctx, req); err != nil {
|
if err := CallbackQuitGroup(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -935,7 +927,7 @@ func (s *groupServer) deleteMemberAndSetConversationSeq(ctx context.Context, gro
|
|||||||
|
|
||||||
func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInfoReq) (*pbgroup.SetGroupInfoResp, error) {
|
func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInfoReq) (*pbgroup.SetGroupInfoResp, error) {
|
||||||
var opMember *relationtb.GroupMemberModel
|
var opMember *relationtb.GroupMemberModel
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
var err error
|
var err error
|
||||||
opMember, err = s.db.TakeGroupMember(ctx, req.GroupInfoForSet.GroupID, mcontext.GetOpUserID(ctx))
|
opMember, err = s.db.TakeGroupMember(ctx, req.GroupInfoForSet.GroupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -948,7 +940,7 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeSetGroupInfo(ctx, req); err != nil {
|
if err := CallbackBeforeSetGroupInfo(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
group, err := s.db.TakeGroup(ctx, req.GroupInfoForSet.GroupID)
|
group, err := s.db.TakeGroup(ctx, req.GroupInfoForSet.GroupID)
|
||||||
@ -956,7 +948,7 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if group.Status == constant.GroupStatusDismissed {
|
if group.Status == constant.GroupStatusDismissed {
|
||||||
return nil, utils.Wrap(errs.ErrDismissedAlready, "")
|
return nil, errs.Wrap(errs.ErrDismissedAlready)
|
||||||
}
|
}
|
||||||
resp := &pbgroup.SetGroupInfoResp{}
|
resp := &pbgroup.SetGroupInfoResp{}
|
||||||
count, err := s.db.FindGroupMemberNum(ctx, group.GroupID)
|
count, err := s.db.FindGroupMemberNum(ctx, group.GroupID)
|
||||||
@ -1017,7 +1009,7 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf
|
|||||||
if num > 0 {
|
if num > 0 {
|
||||||
_ = s.Notification.GroupInfoSetNotification(ctx, tips)
|
_ = s.Notification.GroupInfoSetNotification(ctx, tips)
|
||||||
}
|
}
|
||||||
if err := CallbackAfterSetGroupInfo(ctx, req); err != nil {
|
if err := CallbackAfterSetGroupInfo(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -1054,7 +1046,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
|
|||||||
if newOwner == nil {
|
if newOwner == nil {
|
||||||
return nil, errs.ErrArgs.Wrap("NewOwnerUser not in group " + req.NewOwnerUserID)
|
return nil, errs.ErrArgs.Wrap("NewOwnerUser not in group " + req.NewOwnerUserID)
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
if !(mcontext.GetOpUserID(ctx) == oldOwner.UserID && oldOwner.RoleLevel == constant.GroupOwner) {
|
if !(mcontext.GetOpUserID(ctx) == oldOwner.UserID && oldOwner.RoleLevel == constant.GroupOwner) {
|
||||||
return nil, errs.ErrNoPermission.Wrap("no permission transfer group owner")
|
return nil, errs.ErrNoPermission.Wrap("no permission transfer group owner")
|
||||||
}
|
}
|
||||||
@ -1063,7 +1055,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackAfterTransferGroupOwner(ctx, req); err != nil {
|
if err := CallbackAfterTransferGroupOwner(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.GroupOwnerTransferredNotification(ctx, req)
|
s.Notification.GroupOwnerTransferredNotification(ctx, req)
|
||||||
@ -1195,7 +1187,7 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbgroup.DismissGrou
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
if owner.UserID != mcontext.GetOpUserID(ctx) {
|
if owner.UserID != mcontext.GetOpUserID(ctx) {
|
||||||
return nil, errs.ErrNoPermission.Wrap("not group owner")
|
return nil, errs.ErrNoPermission.Wrap("not group owner")
|
||||||
}
|
}
|
||||||
@ -1207,7 +1199,7 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbgroup.DismissGrou
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if req.DeleteMember == false && group.Status == constant.GroupStatusDismissed {
|
if !req.DeleteMember && group.Status == constant.GroupStatusDismissed {
|
||||||
return nil, errs.ErrDismissedAlready.Wrap("group status is dismissed")
|
return nil, errs.ErrDismissedAlready.Wrap("group status is dismissed")
|
||||||
}
|
}
|
||||||
if err := s.db.DismissGroup(ctx, req.GroupID, req.DeleteMember); err != nil {
|
if err := s.db.DismissGroup(ctx, req.GroupID, req.DeleteMember); err != nil {
|
||||||
@ -1237,7 +1229,7 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbgroup.DismissGrou
|
|||||||
MembersID: membersID,
|
MembersID: membersID,
|
||||||
GroupType: string(group.GroupType),
|
GroupType: string(group.GroupType),
|
||||||
}
|
}
|
||||||
if err := CallbackDismissGroup(ctx, reqCall); err != nil {
|
if err := CallbackDismissGroup(ctx, s.config, reqCall); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1253,7 +1245,7 @@ func (s *groupServer) MuteGroupMember(ctx context.Context, req *pbgroup.MuteGrou
|
|||||||
if err := s.PopulateGroupMember(ctx, member); err != nil {
|
if err := s.PopulateGroupMember(ctx, member); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1287,7 +1279,7 @@ func (s *groupServer) CancelMuteGroupMember(ctx context.Context, req *pbgroup.Ca
|
|||||||
if err := s.PopulateGroupMember(ctx, member); err != nil {
|
if err := s.PopulateGroupMember(ctx, member); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1346,7 +1338,7 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr
|
|||||||
if opUserID == "" {
|
if opUserID == "" {
|
||||||
return nil, errs.ErrNoPermission.Wrap("no op user id")
|
return nil, errs.ErrNoPermission.Wrap("no op user id")
|
||||||
}
|
}
|
||||||
isAppManagerUid := authverify.IsAppManagerUid(ctx)
|
isAppManagerUid := authverify.IsAppManagerUid(ctx, s.config)
|
||||||
for i := range req.Members {
|
for i := range req.Members {
|
||||||
req.Members[i].FaceURL = nil
|
req.Members[i].FaceURL = nil
|
||||||
}
|
}
|
||||||
@ -1429,7 +1421,7 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := 0; i < len(req.Members); i++ {
|
for i := 0; i < len(req.Members); i++ {
|
||||||
if err := CallbackBeforeSetGroupMemberInfo(ctx, req.Members[i]); err != nil {
|
if err := CallbackBeforeSetGroupMemberInfo(ctx, s.config, req.Members[i]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1456,7 +1448,7 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := 0; i < len(req.Members); i++ {
|
for i := 0; i < len(req.Members); i++ {
|
||||||
if err := CallbackAfterSetGroupMemberInfo(ctx, req.Members[i]); err != nil {
|
if err := CallbackAfterSetGroupMemberInfo(ctx, s.config, req.Members[i]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,17 +17,14 @@ package msg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
utils2 "github.com/OpenIMSDK/tools/utils"
|
|
||||||
|
|
||||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
utils2 "github.com/OpenIMSDK/tools/utils"
|
||||||
|
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (resp *msg.GetConversationsHasReadAndMaxSeqResp, err error) {
|
func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (resp *msg.GetConversationsHasReadAndMaxSeqResp, err error) {
|
||||||
@ -132,7 +129,7 @@ func (m *msgServer) MarkMsgsAsRead(
|
|||||||
Seqs: req.Seqs,
|
Seqs: req.Seqs,
|
||||||
ContentType: conversation.ConversationType,
|
ContentType: conversation.ConversationType,
|
||||||
}
|
}
|
||||||
if err = CallbackSingleMsgRead(ctx, req_callback); err != nil {
|
if err = CallbackSingleMsgRead(ctx, m.config, req_callback); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +206,7 @@ func (m *msgServer) MarkConversationAsRead(
|
|||||||
UnreadMsgNum: req.HasReadSeq,
|
UnreadMsgNum: req.HasReadSeq,
|
||||||
ContentType: int64(conversation.ConversationType),
|
ContentType: int64(conversation.ConversationType),
|
||||||
}
|
}
|
||||||
if err := CallbackGroupMsgRead(ctx, reqCall); err != nil {
|
if err := CallbackGroupMsgRead(ctx, m.config, reqCall); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,25 +17,18 @@ package msg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
pbchat "github.com/OpenIMSDK/protocol/msg"
|
pbchat "github.com/OpenIMSDK/protocol/msg"
|
||||||
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func cbURL() string {
|
|
||||||
return config.Config.Callback.CallbackUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
func toCommonCallback(ctx context.Context, msg *pbchat.SendMsgReq, command string) cbapi.CommonCallbackReq {
|
func toCommonCallback(ctx context.Context, msg *pbchat.SendMsgReq, command string) cbapi.CommonCallbackReq {
|
||||||
return cbapi.CommonCallbackReq{
|
return cbapi.CommonCallbackReq{
|
||||||
SendID: msg.MsgData.SendID,
|
SendID: msg.MsgData.SendID,
|
||||||
@ -69,8 +62,8 @@ func GetContent(msg *sdkws.MsgData) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackBeforeSendSingleMsg(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
if !globalConfig.Callback.CallbackBeforeSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackBeforeSendSingleMsgReq{
|
req := &cbapi.CallbackBeforeSendSingleMsgReq{
|
||||||
@ -78,14 +71,14 @@ func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) er
|
|||||||
RecvID: msg.MsgData.RecvID,
|
RecvID: msg.MsgData.RecvID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeSendSingleMsgResp{}
|
resp := &cbapi.CallbackBeforeSendSingleMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackBeforeSendSingleMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackBeforeSendSingleMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackAfterSendSingleMsg(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
if !globalConfig.Callback.CallbackAfterSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackAfterSendSingleMsgReq{
|
req := &cbapi.CallbackAfterSendSingleMsgReq{
|
||||||
@ -93,14 +86,14 @@ func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) err
|
|||||||
RecvID: msg.MsgData.RecvID,
|
RecvID: msg.MsgData.RecvID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterSendSingleMsgResp{}
|
resp := &cbapi.CallbackAfterSendSingleMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendSingleMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackAfterSendSingleMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackBeforeSendGroupMsg(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
if !globalConfig.Callback.CallbackBeforeSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackBeforeSendGroupMsgReq{
|
req := &cbapi.CallbackBeforeSendGroupMsgReq{
|
||||||
@ -108,14 +101,14 @@ func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) err
|
|||||||
GroupID: msg.MsgData.GroupID,
|
GroupID: msg.MsgData.GroupID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeSendGroupMsgResp{}
|
resp := &cbapi.CallbackBeforeSendGroupMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackBeforeSendGroupMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackBeforeSendGroupMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackAfterSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackAfterSendGroupMsg(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
if !globalConfig.Callback.CallbackAfterSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackAfterSendGroupMsgReq{
|
req := &cbapi.CallbackAfterSendGroupMsgReq{
|
||||||
@ -123,21 +116,21 @@ func callbackAfterSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) erro
|
|||||||
GroupID: msg.MsgData.GroupID,
|
GroupID: msg.MsgData.GroupID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterSendGroupMsgResp{}
|
resp := &cbapi.CallbackAfterSendGroupMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendGroupMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackAfterSendGroupMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackMsgModify(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackMsgModify(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackMsgModify.Enable || msg.MsgData.ContentType != constant.Text {
|
if !globalConfig.Callback.CallbackMsgModify.Enable || msg.MsgData.ContentType != constant.Text {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackMsgModifyCommandReq{
|
req := &cbapi.CallbackMsgModifyCommandReq{
|
||||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackMsgModifyCommand),
|
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackMsgModifyCommand),
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackMsgModifyCommandResp{}
|
resp := &cbapi.CallbackMsgModifyCommandResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackMsgModify); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackMsgModify); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if resp.Content != nil {
|
if resp.Content != nil {
|
||||||
@ -162,34 +155,34 @@ func callbackMsgModify(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
|||||||
log.ZDebug(ctx, "callbackMsgModify", "msg", msg.MsgData)
|
log.ZDebug(ctx, "callbackMsgModify", "msg", msg.MsgData)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackGroupMsgRead(ctx context.Context, req *cbapi.CallbackGroupMsgReadReq) error {
|
func CallbackGroupMsgRead(ctx context.Context, globalConfig *config.GlobalConfig, req *cbapi.CallbackGroupMsgReadReq) error {
|
||||||
if !config.Config.Callback.CallbackGroupMsgRead.Enable || req.ContentType != constant.Text {
|
if !globalConfig.Callback.CallbackGroupMsgRead.Enable || req.ContentType != constant.Text {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req.CallbackCommand = cbapi.CallbackGroupMsgReadCommand
|
req.CallbackCommand = cbapi.CallbackGroupMsgReadCommand
|
||||||
|
|
||||||
resp := &cbapi.CallbackGroupMsgReadResp{}
|
resp := &cbapi.CallbackGroupMsgReadResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackMsgModify); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackMsgModify); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackSingleMsgRead(ctx context.Context, req *cbapi.CallbackSingleMsgReadReq) error {
|
func CallbackSingleMsgRead(ctx context.Context, globalConfig *config.GlobalConfig, req *cbapi.CallbackSingleMsgReadReq) error {
|
||||||
if !config.Config.Callback.CallbackSingleMsgRead.Enable || req.ContentType != constant.Text {
|
if !globalConfig.Callback.CallbackSingleMsgRead.Enable || req.ContentType != constant.Text {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req.CallbackCommand = cbapi.CallbackSingleMsgRead
|
req.CallbackCommand = cbapi.CallbackSingleMsgRead
|
||||||
|
|
||||||
resp := &cbapi.CallbackSingleMsgReadResp{}
|
resp := &cbapi.CallbackSingleMsgReadResp{}
|
||||||
|
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackMsgModify); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackMsgModify); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterRevokeMsg(ctx context.Context, req *pbchat.RevokeMsgReq) error {
|
func CallbackAfterRevokeMsg(ctx context.Context, globalConfig *config.GlobalConfig, req *pbchat.RevokeMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterRevokeMsg.Enable {
|
if !globalConfig.Callback.CallbackAfterRevokeMsg.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &cbapi.CallbackAfterRevokeMsgReq{
|
callbackReq := &cbapi.CallbackAfterRevokeMsgReq{
|
||||||
@ -199,7 +192,7 @@ func CallbackAfterRevokeMsg(ctx context.Context, req *pbchat.RevokeMsgReq) error
|
|||||||
UserID: req.UserID,
|
UserID: req.UserID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterRevokeMsgResp{}
|
resp := &cbapi.CallbackAfterRevokeMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterRevokeMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackAfterRevokeMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -17,14 +17,13 @@ package msg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/conversation"
|
"github.com/OpenIMSDK/protocol/conversation"
|
||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *msgServer) getMinSeqs(maxSeqs map[string]int64) map[string]int64 {
|
func (m *msgServer) getMinSeqs(maxSeqs map[string]int64) map[string]int64 {
|
||||||
@ -46,7 +45,7 @@ func (m *msgServer) ClearConversationsMsg(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *msg.ClearConversationsMsgReq,
|
req *msg.ClearConversationsMsgReq,
|
||||||
) (*msg.ClearConversationsMsgResp, error) {
|
) (*msg.ClearConversationsMsgResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := m.clearConversation(ctx, req.ConversationIDs, req.UserID, req.DeleteSyncOpt); err != nil {
|
if err := m.clearConversation(ctx, req.ConversationIDs, req.UserID, req.DeleteSyncOpt); err != nil {
|
||||||
@ -59,7 +58,7 @@ func (m *msgServer) UserClearAllMsg(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *msg.UserClearAllMsgReq,
|
req *msg.UserClearAllMsgReq,
|
||||||
) (*msg.UserClearAllMsgResp, error) {
|
) (*msg.UserClearAllMsgResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
||||||
@ -74,7 +73,7 @@ func (m *msgServer) UserClearAllMsg(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *msgServer) DeleteMsgs(ctx context.Context, req *msg.DeleteMsgsReq) (*msg.DeleteMsgsResp, error) {
|
func (m *msgServer) DeleteMsgs(ctx context.Context, req *msg.DeleteMsgsReq) (*msg.DeleteMsgsResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
isSyncSelf, isSyncOther := m.validateDeleteSyncOpt(req.DeleteSyncOpt)
|
isSyncSelf, isSyncOther := m.validateDeleteSyncOpt(req.DeleteSyncOpt)
|
||||||
@ -122,7 +121,7 @@ func (m *msgServer) DeleteMsgPhysical(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *msg.DeleteMsgPhysicalReq,
|
req *msg.DeleteMsgPhysicalReq,
|
||||||
) (*msg.DeleteMsgPhysicalResp, error) {
|
) (*msg.DeleteMsgPhysicalResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
remainTime := utils.GetCurrentTimestampBySecond() - req.Timestamp
|
remainTime := utils.GetCurrentTimestampBySecond() - req.Timestamp
|
||||||
|
@ -21,21 +21,20 @@ import (
|
|||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageInterceptorFunc func(ctx context.Context, req *msg.SendMsgReq) (*sdkws.MsgData, error)
|
type MessageInterceptorFunc func(ctx context.Context, globalConfig *config.GlobalConfig, req *msg.SendMsgReq) (*sdkws.MsgData, error)
|
||||||
|
|
||||||
func MessageHasReadEnabled(_ context.Context, req *msg.SendMsgReq) (*sdkws.MsgData, error) {
|
func MessageHasReadEnabled(_ context.Context, globalConfig *config.GlobalConfig, req *msg.SendMsgReq) (*sdkws.MsgData, error) {
|
||||||
switch {
|
switch {
|
||||||
case req.MsgData.ContentType == constant.HasReadReceipt && req.MsgData.SessionType == constant.SingleChatType:
|
case req.MsgData.ContentType == constant.HasReadReceipt && req.MsgData.SessionType == constant.SingleChatType:
|
||||||
if !config.Config.SingleMessageHasReadReceiptEnable {
|
if !globalConfig.SingleMessageHasReadReceiptEnable {
|
||||||
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
||||||
}
|
}
|
||||||
return req.MsgData, nil
|
return req.MsgData, nil
|
||||||
case req.MsgData.ContentType == constant.HasReadReceipt && req.MsgData.SessionType == constant.SuperGroupChatType:
|
case req.MsgData.ContentType == constant.HasReadReceipt && req.MsgData.SessionType == constant.SuperGroupChatType:
|
||||||
if !config.Config.GroupMessageHasReadReceiptEnable {
|
if !globalConfig.GroupMessageHasReadReceiptEnable {
|
||||||
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
||||||
}
|
}
|
||||||
return req.MsgData, nil
|
return req.MsgData, nil
|
||||||
|
@ -19,8 +19,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
@ -28,8 +26,7 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,7 +41,7 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
if req.Seq < 0 {
|
if req.Seq < 0 {
|
||||||
return nil, errs.ErrArgs.Wrap("seq is invalid")
|
return nil, errs.ErrArgs.Wrap("seq is invalid")
|
||||||
}
|
}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
user, err := m.User.GetUserInfo(ctx, req.UserID)
|
user, err := m.User.GetUserInfo(ctx, req.UserID)
|
||||||
@ -65,10 +62,10 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
data, _ := json.Marshal(msgs[0])
|
data, _ := json.Marshal(msgs[0])
|
||||||
log.ZInfo(ctx, "GetMsgBySeqs", "conversationID", req.ConversationID, "seq", req.Seq, "msg", string(data))
|
log.ZInfo(ctx, "GetMsgBySeqs", "conversationID", req.ConversationID, "seq", req.Seq, "msg", string(data))
|
||||||
var role int32
|
var role int32
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, m.config) {
|
||||||
switch msgs[0].SessionType {
|
switch msgs[0].SessionType {
|
||||||
case constant.SingleChatType:
|
case constant.SingleChatType:
|
||||||
if err := authverify.CheckAccessV3(ctx, msgs[0].SendID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, msgs[0].SendID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
role = user.AppMangerLevel
|
role = user.AppMangerLevel
|
||||||
@ -112,11 +109,11 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
}
|
}
|
||||||
revokerUserID := mcontext.GetOpUserID(ctx)
|
revokerUserID := mcontext.GetOpUserID(ctx)
|
||||||
var flag bool
|
var flag bool
|
||||||
if len(config.Config.Manager.UserID) > 0 {
|
if len(m.config.Manager.UserID) > 0 {
|
||||||
flag = utils.Contain(revokerUserID, config.Config.Manager.UserID...)
|
flag = utils.Contain(revokerUserID, m.config.Manager.UserID...)
|
||||||
}
|
}
|
||||||
if len(config.Config.Manager.UserID) == 0 && len(config.Config.IMAdmin.UserID) > 0 {
|
if len(m.config.Manager.UserID) == 0 && len(m.config.IMAdmin.UserID) > 0 {
|
||||||
flag = utils.Contain(revokerUserID, config.Config.IMAdmin.UserID...)
|
flag = utils.Contain(revokerUserID, m.config.IMAdmin.UserID...)
|
||||||
}
|
}
|
||||||
tips := sdkws.RevokeMsgTips{
|
tips := sdkws.RevokeMsgTips{
|
||||||
RevokerUserID: revokerUserID,
|
RevokerUserID: revokerUserID,
|
||||||
@ -136,7 +133,7 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
if err := m.notificationSender.NotificationWithSesstionType(ctx, req.UserID, recvID, constant.MsgRevokeNotification, msgs[0].SessionType, &tips); err != nil {
|
if err := m.notificationSender.NotificationWithSesstionType(ctx, req.UserID, recvID, constant.MsgRevokeNotification, msgs[0].SessionType, &tips); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err = CallbackAfterRevokeMsg(ctx, req); err != nil {
|
if err = CallbackAfterRevokeMsg(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &msg.RevokeMsgResp{}, nil
|
return &msg.RevokeMsgResp{}, nil
|
||||||
|
@ -17,9 +17,6 @@ package msg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
pbconversation "github.com/OpenIMSDK/protocol/conversation"
|
pbconversation "github.com/OpenIMSDK/protocol/conversation"
|
||||||
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
||||||
@ -29,12 +26,14 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *msgServer) SendMsg(ctx context.Context, req *pbmsg.SendMsgReq) (resp *pbmsg.SendMsgResp, error error) {
|
func (m *msgServer) SendMsg(ctx context.Context, req *pbmsg.SendMsgReq) (resp *pbmsg.SendMsgResp, error error) {
|
||||||
resp = &pbmsg.SendMsgResp{}
|
resp = &pbmsg.SendMsgResp{}
|
||||||
if req.MsgData != nil {
|
if req.MsgData != nil {
|
||||||
flag := isMessageHasReadEnabled(req.MsgData)
|
flag := isMessageHasReadEnabled(req.MsgData, m.config)
|
||||||
if !flag {
|
if !flag {
|
||||||
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
||||||
}
|
}
|
||||||
@ -62,11 +61,11 @@ func (m *msgServer) sendMsgSuperGroupChat(
|
|||||||
prommetrics.GroupChatMsgProcessFailedCounter.Inc()
|
prommetrics.GroupChatMsgProcessFailedCounter.Inc()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err = callbackBeforeSendGroupMsg(ctx, req); err != nil {
|
if err = callbackBeforeSendGroupMsg(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := callbackMsgModify(ctx, req); err != nil {
|
if err := callbackMsgModify(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForGroup(req.MsgData.GroupID), req.MsgData)
|
err = m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForGroup(req.MsgData.GroupID), req.MsgData)
|
||||||
@ -76,7 +75,7 @@ func (m *msgServer) sendMsgSuperGroupChat(
|
|||||||
if req.MsgData.ContentType == constant.AtText {
|
if req.MsgData.ContentType == constant.AtText {
|
||||||
go m.setConversationAtInfo(ctx, req.MsgData)
|
go m.setConversationAtInfo(ctx, req.MsgData)
|
||||||
}
|
}
|
||||||
if err = callbackAfterSendGroupMsg(ctx, req); err != nil {
|
if err = callbackAfterSendGroupMsg(ctx, m.config, req); err != nil {
|
||||||
log.ZWarn(ctx, "CallbackAfterSendGroupMsg", err)
|
log.ZWarn(ctx, "CallbackAfterSendGroupMsg", err)
|
||||||
}
|
}
|
||||||
prommetrics.GroupChatMsgProcessSuccessCounter.Inc()
|
prommetrics.GroupChatMsgProcessSuccessCounter.Inc()
|
||||||
@ -108,7 +107,7 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
|
|||||||
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}
|
||||||
err := m.Conversation.SetConversations(ctx, atUserID, conversation)
|
err = m.Conversation.SetConversations(ctx, atUserID, conversation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "SetConversations", err, "userID", atUserID, "conversation", conversation)
|
log.ZWarn(ctx, "SetConversations", err, "userID", atUserID, "conversation", conversation)
|
||||||
}
|
}
|
||||||
@ -165,18 +164,18 @@ func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbmsg.SendMsgReq
|
|||||||
prommetrics.SingleChatMsgProcessFailedCounter.Inc()
|
prommetrics.SingleChatMsgProcessFailedCounter.Inc()
|
||||||
return nil, nil
|
return nil, nil
|
||||||
} else {
|
} else {
|
||||||
if err = callbackBeforeSendSingleMsg(ctx, req); err != nil {
|
if err = callbackBeforeSendSingleMsg(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := callbackMsgModify(ctx, req); err != nil {
|
if err := callbackMsgModify(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForSingle(req.MsgData.SendID, req.MsgData.RecvID), req.MsgData); err != nil {
|
if err := m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForSingle(req.MsgData.SendID, req.MsgData.RecvID), req.MsgData); err != nil {
|
||||||
prommetrics.SingleChatMsgProcessFailedCounter.Inc()
|
prommetrics.SingleChatMsgProcessFailedCounter.Inc()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = callbackAfterSendSingleMsg(ctx, req)
|
err = callbackAfterSendSingleMsg(ctx, m.config, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "CallbackAfterSendSingleMsg", err, "req", req)
|
log.ZWarn(ctx, "CallbackAfterSendSingleMsg", err, "req", req)
|
||||||
}
|
}
|
||||||
|
@ -15,20 +15,17 @@
|
|||||||
package msg
|
package msg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/conversation"
|
"github.com/OpenIMSDK/protocol/conversation"
|
||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -44,6 +41,7 @@ type (
|
|||||||
ConversationLocalCache *localcache.ConversationLocalCache
|
ConversationLocalCache *localcache.ConversationLocalCache
|
||||||
Handlers MessageInterceptorChain
|
Handlers MessageInterceptorChain
|
||||||
notificationSender *rpcclient.NotificationSender
|
notificationSender *rpcclient.NotificationSender
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -51,36 +49,36 @@ func (m *msgServer) addInterceptorHandler(interceptorFunc ...MessageInterceptorF
|
|||||||
m.Handlers = append(m.Handlers, interceptorFunc...)
|
m.Handlers = append(m.Handlers, interceptorFunc...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *msgServer) execInterceptorHandler(ctx context.Context, req *msg.SendMsgReq) error {
|
//func (m *msgServer) execInterceptorHandler(ctx context.Context, config *config.GlobalConfig, req *msg.SendMsgReq) error {
|
||||||
for _, handler := range m.Handlers {
|
// for _, handler := range m.Handlers {
|
||||||
msgData, err := handler(ctx, req)
|
// msgData, err := handler(ctx, config, req)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
req.MsgData = msgData
|
// req.MsgData = msgData
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := mongo.CreateMsgIndex(); err != nil {
|
if err := mongo.CreateMsgIndex(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cacheModel := cache.NewMsgCacheModel(rdb)
|
cacheModel := cache.NewMsgCacheModel(rdb, config)
|
||||||
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
|
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase(config.Mongo.Database))
|
||||||
conversationClient := rpcclient.NewConversationRpcClient(client)
|
conversationClient := rpcclient.NewConversationRpcClient(client, config)
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
friendRpcClient := rpcclient.NewFriendRpcClient(client)
|
friendRpcClient := rpcclient.NewFriendRpcClient(client, config)
|
||||||
msgDatabase, err := controller.NewCommonMsgDatabase(msgDocModel, cacheModel)
|
msgDatabase, err := controller.NewCommonMsgDatabase(msgDocModel, cacheModel, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -93,8 +91,9 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
GroupLocalCache: localcache.NewGroupLocalCache(&groupRpcClient),
|
GroupLocalCache: localcache.NewGroupLocalCache(&groupRpcClient),
|
||||||
ConversationLocalCache: localcache.NewConversationLocalCache(&conversationClient),
|
ConversationLocalCache: localcache.NewConversationLocalCache(&conversationClient),
|
||||||
friend: &friendRpcClient,
|
friend: &friendRpcClient,
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
s.notificationSender = rpcclient.NewNotificationSender(rpcclient.WithLocalSendMsg(s.SendMsg))
|
s.notificationSender = rpcclient.NewNotificationSender(config, rpcclient.WithLocalSendMsg(s.SendMsg))
|
||||||
s.addInterceptorHandler(MessageHasReadEnabled)
|
s.addInterceptorHandler(MessageHasReadEnabled)
|
||||||
msg.RegisterMsgServer(server, s)
|
msg.RegisterMsgServer(server, s)
|
||||||
return nil
|
return nil
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,15 +17,13 @@ package msg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *msgServer) PullMessageBySeqs(
|
func (m *msgServer) PullMessageBySeqs(
|
||||||
@ -90,7 +88,7 @@ func (m *msgServer) PullMessageBySeqs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sdkws.GetMaxSeqResp, error) {
|
func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sdkws.GetMaxSeqResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
||||||
|
@ -18,22 +18,21 @@ import (
|
|||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func isMessageHasReadEnabled(msgData *sdkws.MsgData) bool {
|
func isMessageHasReadEnabled(msgData *sdkws.MsgData, config *config.GlobalConfig) bool {
|
||||||
switch {
|
switch {
|
||||||
case msgData.ContentType == constant.HasReadReceipt && msgData.SessionType == constant.SingleChatType:
|
case msgData.ContentType == constant.HasReadReceipt && msgData.SessionType == constant.SingleChatType:
|
||||||
if config.Config.SingleMessageHasReadReceiptEnable {
|
if config.SingleMessageHasReadReceiptEnable {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case msgData.ContentType == constant.HasReadReceipt && msgData.SessionType == constant.SuperGroupChatType:
|
case msgData.ContentType == constant.HasReadReceipt && msgData.SessionType == constant.SuperGroupChatType:
|
||||||
if config.Config.GroupMessageHasReadReceiptEnable {
|
if config.GroupMessageHasReadReceiptEnable {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
|
@ -25,8 +25,6 @@ import (
|
|||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ExcludeContentType = []int{constant.HasReadReceipt}
|
var ExcludeContentType = []int{constant.HasReadReceipt}
|
||||||
@ -51,10 +49,10 @@ type MessageRevoked struct {
|
|||||||
func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgReq) error {
|
func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgReq) error {
|
||||||
switch data.MsgData.SessionType {
|
switch data.MsgData.SessionType {
|
||||||
case constant.SingleChatType:
|
case constant.SingleChatType:
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(data.MsgData.SendID, config.Config.Manager.UserID) {
|
if len(m.config.Manager.UserID) > 0 && utils.IsContain(data.MsgData.SendID, m.config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if utils.IsContain(data.MsgData.SendID, config.Config.IMAdmin.UserID) {
|
if utils.IsContain(data.MsgData.SendID, m.config.IMAdmin.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if data.MsgData.ContentType <= constant.NotificationEnd &&
|
if data.MsgData.ContentType <= constant.NotificationEnd &&
|
||||||
@ -68,7 +66,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
|||||||
if black {
|
if black {
|
||||||
return errs.ErrBlockedByPeer.Wrap()
|
return errs.ErrBlockedByPeer.Wrap()
|
||||||
}
|
}
|
||||||
if *config.Config.MessageVerify.FriendVerify {
|
if *m.config.MessageVerify.FriendVerify {
|
||||||
friend, err := m.friend.IsFriend(ctx, data.MsgData.SendID, data.MsgData.RecvID)
|
friend, err := m.friend.IsFriend(ctx, data.MsgData.SendID, data.MsgData.RecvID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -91,10 +89,10 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
|||||||
if groupInfo.GroupType == constant.SuperGroup {
|
if groupInfo.GroupType == constant.SuperGroup {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(data.MsgData.SendID, config.Config.Manager.UserID) {
|
if len(m.config.Manager.UserID) > 0 && utils.IsContain(data.MsgData.SendID, m.config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if utils.IsContain(data.MsgData.SendID, config.Config.IMAdmin.UserID) {
|
if utils.IsContain(data.MsgData.SendID, m.config.IMAdmin.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if data.MsgData.ContentType <= constant.NotificationEnd &&
|
if data.MsgData.ContentType <= constant.NotificationEnd &&
|
||||||
@ -159,9 +157,6 @@ func (m *msgServer) encapsulateMsgData(msg *sdkws.MsgData) {
|
|||||||
case constant.Custom:
|
case constant.Custom:
|
||||||
fallthrough
|
fallthrough
|
||||||
case constant.Quote:
|
case constant.Quote:
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsConversationUpdate, true)
|
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsUnreadCount, true)
|
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsSenderSync, true)
|
|
||||||
case constant.Revoke:
|
case constant.Revoke:
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsUnreadCount, false)
|
utils.SetSwitchFromOptions(msg.Options, constant.IsUnreadCount, false)
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsOfflinePush, false)
|
utils.SetSwitchFromOptions(msg.Options, constant.IsOfflinePush, false)
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
utils2 "github.com/OpenIMSDK/tools/utils"
|
utils2 "github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
)
|
)
|
||||||
@ -83,7 +82,7 @@ func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *thirdServer) DeleteLogs(ctx context.Context, req *third.DeleteLogsReq) (*third.DeleteLogsResp, error) {
|
func (t *thirdServer) DeleteLogs(ctx context.Context, req *third.DeleteLogsReq) (*third.DeleteLogsResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, t.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userID := ""
|
userID := ""
|
||||||
@ -124,7 +123,7 @@ func dbToPbLogInfos(logs []*relationtb.LogModel) []*third.LogInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq) (*third.SearchLogsResp, error) {
|
func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq) (*third.SearchLogsResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, t.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
|
@ -23,18 +23,13 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/third"
|
"github.com/OpenIMSDK/protocol/third"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cont"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cont"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
)
|
)
|
||||||
@ -58,7 +53,7 @@ func (t *thirdServer) PartSize(ctx context.Context, req *third.PartSizeReq) (*th
|
|||||||
|
|
||||||
func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *third.InitiateMultipartUploadReq) (*third.InitiateMultipartUploadResp, error) {
|
func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *third.InitiateMultipartUploadReq) (*third.InitiateMultipartUploadResp, error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
defer log.ZDebug(ctx, "return")
|
||||||
if err := checkUploadName(ctx, req.Name); err != nil {
|
if err := t.checkUploadName(ctx, req.Name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
expireTime := time.Now().Add(t.defaultExpire)
|
expireTime := time.Now().Add(t.defaultExpire)
|
||||||
@ -137,7 +132,7 @@ func (t *thirdServer) AuthSign(ctx context.Context, req *third.AuthSignReq) (*th
|
|||||||
|
|
||||||
func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.CompleteMultipartUploadReq) (*third.CompleteMultipartUploadResp, error) {
|
func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.CompleteMultipartUploadReq) (*third.CompleteMultipartUploadResp, error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
defer log.ZDebug(ctx, "return")
|
||||||
if err := checkUploadName(ctx, req.Name); err != nil {
|
if err := t.checkUploadName(ctx, req.Name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result, err := t.s3dataBase.CompleteMultipartUpload(ctx, req.UploadID, req.Parts)
|
result, err := t.s3dataBase.CompleteMultipartUpload(ctx, req.UploadID, req.Parts)
|
||||||
@ -194,13 +189,13 @@ func (t *thirdServer) InitiateFormData(ctx context.Context, req *third.InitiateF
|
|||||||
if req.Size <= 0 {
|
if req.Size <= 0 {
|
||||||
return nil, errs.ErrArgs.Wrap("size must be greater than 0")
|
return nil, errs.ErrArgs.Wrap("size must be greater than 0")
|
||||||
}
|
}
|
||||||
if err := checkUploadName(ctx, req.Name); err != nil {
|
if err := t.checkUploadName(ctx, req.Name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var duration time.Duration
|
var duration time.Duration
|
||||||
opUserID := mcontext.GetOpUserID(ctx)
|
opUserID := mcontext.GetOpUserID(ctx)
|
||||||
var key string
|
var key string
|
||||||
if authverify.IsManagerUserID(opUserID) {
|
if t.IsManagerUserID(opUserID) {
|
||||||
if req.Millisecond <= 0 {
|
if req.Millisecond <= 0 {
|
||||||
duration = time.Minute * 10
|
duration = time.Minute * 10
|
||||||
} else {
|
} else {
|
||||||
@ -214,7 +209,7 @@ func (t *thirdServer) InitiateFormData(ctx context.Context, req *third.InitiateF
|
|||||||
}
|
}
|
||||||
uid, err := uuid.NewRandom()
|
uid, err := uuid.NewRandom()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "uuid NewRandom failed")
|
||||||
}
|
}
|
||||||
if key == "" {
|
if key == "" {
|
||||||
date := time.Now().Format("20060102")
|
date := time.Now().Format("20060102")
|
||||||
@ -229,7 +224,7 @@ func (t *thirdServer) InitiateFormData(ctx context.Context, req *third.InitiateF
|
|||||||
}
|
}
|
||||||
mateData, err := json.Marshal(&mate)
|
mateData, err := json.Marshal(&mate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errs.Wrap(err, "marshal failed")
|
||||||
}
|
}
|
||||||
resp, err := t.s3dataBase.FormData(ctx, key, req.Size, req.ContentType, duration)
|
resp, err := t.s3dataBase.FormData(ctx, key, req.Size, req.ContentType, duration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -260,7 +255,7 @@ func (t *thirdServer) CompleteFormData(ctx context.Context, req *third.CompleteF
|
|||||||
if err := json.Unmarshal(data, &mate); err != nil {
|
if err := json.Unmarshal(data, &mate); err != nil {
|
||||||
return nil, errs.ErrArgs.Wrap("invalid id " + err.Error())
|
return nil, errs.ErrArgs.Wrap("invalid id " + err.Error())
|
||||||
}
|
}
|
||||||
if err := checkUploadName(ctx, mate.Name); err != nil {
|
if err := t.checkUploadName(ctx, mate.Name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
info, err := t.s3dataBase.StatObject(ctx, mate.Key)
|
info, err := t.s3dataBase.StatObject(ctx, mate.Key)
|
||||||
|
@ -17,66 +17,63 @@ package third
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/protocol/third"
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cos"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cos"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/minio"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/minio"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/oss"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/oss"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/third"
|
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
logdb, err := mgo.NewLogMongo(mongo.GetDatabase())
|
logdb, err := mgo.NewLogMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s3db, err := mgo.NewS3Mongo(mongo.GetDatabase())
|
s3db, err := mgo.NewS3Mongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
apiURL := config.Config.Object.ApiURL
|
apiURL := config.Object.ApiURL
|
||||||
if apiURL == "" {
|
if apiURL == "" {
|
||||||
return fmt.Errorf("api url is empty")
|
return errs.Wrap(fmt.Errorf("api is empty"))
|
||||||
}
|
}
|
||||||
if _, err := url.Parse(config.Config.Object.ApiURL); err != nil {
|
if _, err := url.Parse(config.Object.ApiURL); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if apiURL[len(apiURL)-1] != '/' {
|
if apiURL[len(apiURL)-1] != '/' {
|
||||||
apiURL += "/"
|
apiURL += "/"
|
||||||
}
|
}
|
||||||
apiURL += "object/"
|
apiURL += "object/"
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 根据配置文件策略选择 oss 方式
|
// Select the oss method according to the profile policy
|
||||||
enable := config.Config.Object.Enable
|
enable := config.Object.Enable
|
||||||
var o s3.Interface
|
var o s3.Interface
|
||||||
switch config.Config.Object.Enable {
|
switch enable {
|
||||||
case "minio":
|
case "minio":
|
||||||
o, err = minio.NewMinio(cache.NewMinioCache(rdb))
|
o, err = minio.NewMinio(cache.NewMinioCache(rdb), minio.Config(config.Object.Minio))
|
||||||
case "cos":
|
case "cos":
|
||||||
o, err = cos.NewCos()
|
o, err = cos.NewCos(cos.Config(config.Object.Cos))
|
||||||
case "oss":
|
case "oss":
|
||||||
o, err = oss.NewOSS()
|
o, err = oss.NewOSS(oss.Config(config.Object.Oss))
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("invalid object enable: %s", enable)
|
err = fmt.Errorf("invalid object enable: %s", enable)
|
||||||
}
|
}
|
||||||
@ -85,10 +82,11 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
}
|
}
|
||||||
third.RegisterThirdServer(server, &thirdServer{
|
third.RegisterThirdServer(server, &thirdServer{
|
||||||
apiURL: apiURL,
|
apiURL: apiURL,
|
||||||
thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb), logdb),
|
thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb, config), logdb),
|
||||||
userRpcClient: rpcclient.NewUserRpcClient(client),
|
userRpcClient: rpcclient.NewUserRpcClient(client, config),
|
||||||
s3dataBase: controller.NewS3Database(rdb, o, s3db),
|
s3dataBase: controller.NewS3Database(rdb, o, s3db),
|
||||||
defaultExpire: time.Hour * 24 * 7,
|
defaultExpire: time.Hour * 24 * 7,
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -99,6 +97,7 @@ type thirdServer struct {
|
|||||||
s3dataBase controller.S3Database
|
s3dataBase controller.S3Database
|
||||||
userRpcClient rpcclient.UserRpcClient
|
userRpcClient rpcclient.UserRpcClient
|
||||||
defaultExpire time.Duration
|
defaultExpire time.Duration
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *thirdServer) FcmUpdateToken(ctx context.Context, req *third.FcmUpdateTokenReq) (resp *third.FcmUpdateTokenResp, err error) {
|
func (t *thirdServer) FcmUpdateToken(ctx context.Context, req *third.FcmUpdateTokenReq) (resp *third.FcmUpdateTokenResp, err error) {
|
||||||
|
@ -21,11 +21,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/third"
|
"github.com/OpenIMSDK/protocol/third"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
)
|
)
|
||||||
|
|
||||||
func toPbMapArray(m map[string][]string) []*third.KeyValues {
|
func toPbMapArray(m map[string][]string) []*third.KeyValues {
|
||||||
@ -42,7 +41,7 @@ func toPbMapArray(m map[string][]string) []*third.KeyValues {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkUploadName(ctx context.Context, name string) error {
|
func (t *thirdServer) checkUploadName(ctx context.Context, name string) error {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return errs.ErrArgs.Wrap("name is empty")
|
return errs.ErrArgs.Wrap("name is empty")
|
||||||
}
|
}
|
||||||
@ -56,7 +55,7 @@ func checkUploadName(ctx context.Context, name string) error {
|
|||||||
if opUserID == "" {
|
if opUserID == "" {
|
||||||
return errs.ErrNoPermission.Wrap("opUserID is empty")
|
return errs.ErrNoPermission.Wrap("opUserID is empty")
|
||||||
}
|
}
|
||||||
if !authverify.IsManagerUserID(opUserID) {
|
if !authverify.IsManagerUserID(opUserID, t.config) {
|
||||||
if !strings.HasPrefix(name, opUserID+"/") {
|
if !strings.HasPrefix(name, opUserID+"/") {
|
||||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("name must start with `%s/`", opUserID))
|
return errs.ErrNoPermission.Wrap(fmt.Sprintf("name must start with `%s/`", opUserID))
|
||||||
}
|
}
|
||||||
@ -80,3 +79,7 @@ func checkValidObjectName(objectName string) error {
|
|||||||
}
|
}
|
||||||
return checkValidObjectNamePrefix(objectName)
|
return checkValidObjectNamePrefix(objectName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *thirdServer) IsManagerUserID(opUserID string) bool {
|
||||||
|
return authverify.IsManagerUserID(opUserID, t.config)
|
||||||
|
}
|
||||||
|
@ -19,14 +19,13 @@ import (
|
|||||||
|
|
||||||
pbuser "github.com/OpenIMSDK/protocol/user"
|
pbuser "github.com/OpenIMSDK/protocol/user"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CallbackBeforeUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) error {
|
func CallbackBeforeUpdateUserInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UpdateUserInfoReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeUpdateUserInfo.Enable {
|
if !globalConfig.Callback.CallbackBeforeUpdateUserInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeUpdateUserInfoReq{
|
cbReq := &cbapi.CallbackBeforeUpdateUserInfoReq{
|
||||||
@ -36,7 +35,7 @@ func CallbackBeforeUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInf
|
|||||||
Nickname: &req.UserInfo.Nickname,
|
Nickname: &req.UserInfo.Nickname,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeUpdateUserInfoResp{}
|
resp := &cbapi.CallbackBeforeUpdateUserInfoResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
utils.NotNilReplace(&req.UserInfo.FaceURL, resp.FaceURL)
|
utils.NotNilReplace(&req.UserInfo.FaceURL, resp.FaceURL)
|
||||||
@ -44,8 +43,8 @@ func CallbackBeforeUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInf
|
|||||||
utils.NotNilReplace(&req.UserInfo.Nickname, resp.Nickname)
|
utils.NotNilReplace(&req.UserInfo.Nickname, resp.Nickname)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) error {
|
func CallbackAfterUpdateUserInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UpdateUserInfoReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterUpdateUserInfo.Enable {
|
if !globalConfig.Callback.CallbackAfterUpdateUserInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterUpdateUserInfoReq{
|
cbReq := &cbapi.CallbackAfterUpdateUserInfoReq{
|
||||||
@ -55,13 +54,13 @@ func CallbackAfterUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfo
|
|||||||
Nickname: req.UserInfo.Nickname,
|
Nickname: req.UserInfo.Nickname,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterUpdateUserInfoResp{}
|
resp := &cbapi.CallbackAfterUpdateUserInfoResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) error {
|
func CallbackBeforeUpdateUserInfoEx(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UpdateUserInfoExReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeUpdateUserInfoEx.Enable {
|
if !globalConfig.Callback.CallbackBeforeUpdateUserInfoEx.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeUpdateUserInfoExReq{
|
cbReq := &cbapi.CallbackBeforeUpdateUserInfoExReq{
|
||||||
@ -71,7 +70,7 @@ func CallbackBeforeUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserI
|
|||||||
Nickname: req.UserInfo.Nickname,
|
Nickname: req.UserInfo.Nickname,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeUpdateUserInfoExResp{}
|
resp := &cbapi.CallbackBeforeUpdateUserInfoExResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfoEx); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfoEx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
utils.NotNilReplace(req.UserInfo.FaceURL, resp.FaceURL)
|
utils.NotNilReplace(req.UserInfo.FaceURL, resp.FaceURL)
|
||||||
@ -79,8 +78,8 @@ func CallbackBeforeUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserI
|
|||||||
utils.NotNilReplace(req.UserInfo.Nickname, resp.Nickname)
|
utils.NotNilReplace(req.UserInfo.Nickname, resp.Nickname)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) error {
|
func CallbackAfterUpdateUserInfoEx(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UpdateUserInfoExReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterUpdateUserInfoEx.Enable {
|
if !globalConfig.Callback.CallbackAfterUpdateUserInfoEx.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterUpdateUserInfoExReq{
|
cbReq := &cbapi.CallbackAfterUpdateUserInfoExReq{
|
||||||
@ -90,14 +89,14 @@ func CallbackAfterUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserIn
|
|||||||
Nickname: req.UserInfo.Nickname,
|
Nickname: req.UserInfo.Nickname,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterUpdateUserInfoExResp{}
|
resp := &cbapi.CallbackAfterUpdateUserInfoExResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfoEx); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfoEx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackBeforeUserRegister(ctx context.Context, req *pbuser.UserRegisterReq) error {
|
func CallbackBeforeUserRegister(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UserRegisterReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeUserRegister.Enable {
|
if !globalConfig.Callback.CallbackBeforeUserRegister.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeUserRegisterReq{
|
cbReq := &cbapi.CallbackBeforeUserRegisterReq{
|
||||||
@ -107,7 +106,7 @@ func CallbackBeforeUserRegister(ctx context.Context, req *pbuser.UserRegisterReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := &cbapi.CallbackBeforeUserRegisterResp{}
|
resp := &cbapi.CallbackBeforeUserRegisterResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(resp.Users) != 0 {
|
if len(resp.Users) != 0 {
|
||||||
@ -116,8 +115,8 @@ func CallbackBeforeUserRegister(ctx context.Context, req *pbuser.UserRegisterReq
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterUserRegister(ctx context.Context, req *pbuser.UserRegisterReq) error {
|
func CallbackAfterUserRegister(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UserRegisterReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterUserRegister.Enable {
|
if !globalConfig.Callback.CallbackAfterUserRegister.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterUserRegisterReq{
|
cbReq := &cbapi.CallbackAfterUserRegisterReq{
|
||||||
@ -127,7 +126,7 @@ func CallbackAfterUserRegister(ctx context.Context, req *pbuser.UserRegisterReq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := &cbapi.CallbackAfterUserRegisterResp{}
|
resp := &cbapi.CallbackAfterUserRegisterResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterUpdateUserInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterUpdateUserInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -16,39 +16,31 @@ package user
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/pagination"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
pbuser "github.com/OpenIMSDK/protocol/user"
|
||||||
|
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/pagination"
|
||||||
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
|
||||||
|
|
||||||
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||||
|
|
||||||
pbuser "github.com/OpenIMSDK/protocol/user"
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -59,6 +51,7 @@ type userServer struct {
|
|||||||
friendRpcClient *rpcclient.FriendRpcClient
|
friendRpcClient *rpcclient.FriendRpcClient
|
||||||
groupRpcClient *rpcclient.GroupRpcClient
|
groupRpcClient *rpcclient.GroupRpcClient
|
||||||
RegisterCenter registry.SvcDiscoveryRegistry
|
RegisterCenter registry.SvcDiscoveryRegistry
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) GetGroupOnlineUser(ctx context.Context, req *pbuser.GetGroupOnlineUserReq) (*pbuser.GetGroupOnlineUserResp, error) {
|
func (s *userServer) GetGroupOnlineUser(ctx context.Context, req *pbuser.GetGroupOnlineUserReq) (*pbuser.GetGroupOnlineUserResp, error) {
|
||||||
@ -66,39 +59,40 @@ func (s *userServer) GetGroupOnlineUser(ctx context.Context, req *pbuser.GetGrou
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
users := make([]*tablerelation.UserModel, 0)
|
users := make([]*tablerelation.UserModel, 0)
|
||||||
if len(config.Config.IMAdmin.UserID) != len(config.Config.IMAdmin.Nickname) {
|
if len(config.IMAdmin.UserID) != len(config.IMAdmin.Nickname) {
|
||||||
return errors.New("len(config.Config.AppNotificationAdmin.AppManagerUid) != len(config.Config.AppNotificationAdmin.Nickname)")
|
return errs.Wrap(fmt.Errorf("the count of ImAdmin.UserID is not equal to the count of ImAdmin.Nickname"))
|
||||||
}
|
}
|
||||||
for k, v := range config.Config.IMAdmin.UserID {
|
for k, v := range config.IMAdmin.UserID {
|
||||||
users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.Config.IMAdmin.Nickname[k], AppMangerLevel: constant.AppNotificationAdmin})
|
users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.IMAdmin.Nickname[k], AppMangerLevel: constant.AppNotificationAdmin})
|
||||||
}
|
}
|
||||||
userDB, err := mgo.NewUserMongo(mongo.GetDatabase())
|
userDB, err := mgo.NewUserMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt())
|
cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt())
|
||||||
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase())
|
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase(config.Mongo.Database))
|
||||||
database := controller.NewUserDatabase(userDB, cache, tx.NewMongo(mongo.GetClient()), userMongoDB)
|
database := controller.NewUserDatabase(userDB, cache, tx.NewMongo(mongo.GetClient()), userMongoDB)
|
||||||
friendRpcClient := rpcclient.NewFriendRpcClient(client)
|
friendRpcClient := rpcclient.NewFriendRpcClient(client, config)
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
u := &userServer{
|
u := &userServer{
|
||||||
UserDatabase: database,
|
UserDatabase: database,
|
||||||
RegisterCenter: client,
|
RegisterCenter: client,
|
||||||
friendRpcClient: &friendRpcClient,
|
friendRpcClient: &friendRpcClient,
|
||||||
groupRpcClient: &groupRpcClient,
|
groupRpcClient: &groupRpcClient,
|
||||||
friendNotificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)),
|
friendNotificationSender: notification.NewFriendNotificationSender(config, &msgRpcClient, notification.WithDBFunc(database.FindWithError)),
|
||||||
userNotificationSender: notification.NewUserNotificationSender(&msgRpcClient, notification.WithUserFunc(database.FindWithError)),
|
userNotificationSender: notification.NewUserNotificationSender(config, &msgRpcClient, notification.WithUserFunc(database.FindWithError)),
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
pbuser.RegisterUserServer(server, u)
|
pbuser.RegisterUserServer(server, u)
|
||||||
return u.UserDatabase.InitOnce(context.Background(), users)
|
return u.UserDatabase.InitOnce(context.Background(), users)
|
||||||
@ -111,19 +105,16 @@ func (s *userServer) GetDesignateUsers(ctx context.Context, req *pbuser.GetDesig
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp.UsersInfo = convert.UsersDB2Pb(users)
|
resp.UsersInfo = convert.UsersDB2Pb(users)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) (resp *pbuser.UpdateUserInfoResp, err error) {
|
func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) (resp *pbuser.UpdateUserInfoResp, err error) {
|
||||||
resp = &pbuser.UpdateUserInfoResp{}
|
resp = &pbuser.UpdateUserInfoResp{}
|
||||||
err = authverify.CheckAccessV3(ctx, req.UserInfo.UserID)
|
err = authverify.CheckAccessV3(ctx, req.UserInfo.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeUpdateUserInfo(ctx, req); err != nil {
|
if err := CallbackBeforeUpdateUserInfo(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data := convert.UserPb2DBMap(req.UserInfo)
|
data := convert.UserPb2DBMap(req.UserInfo)
|
||||||
@ -136,29 +127,29 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if req.UserInfo.Nickname != "" || req.UserInfo.FaceURL != "" {
|
if req.UserInfo.Nickname != "" || req.UserInfo.FaceURL != "" {
|
||||||
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
if err = s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
||||||
log.ZError(ctx, "NotificationUserInfoUpdate", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, friendID := range friends {
|
for _, friendID := range friends {
|
||||||
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
||||||
}
|
}
|
||||||
if err := CallbackAfterUpdateUserInfo(ctx, req); err != nil {
|
if err = CallbackAfterUpdateUserInfo(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
if err = s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
||||||
log.ZError(ctx, "NotificationUserInfoUpdate", err, "userID", req.UserInfo.UserID)
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) (resp *pbuser.UpdateUserInfoExResp, err error) {
|
func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) (resp *pbuser.UpdateUserInfoExResp, err error) {
|
||||||
resp = &pbuser.UpdateUserInfoExResp{}
|
resp = &pbuser.UpdateUserInfoExResp{}
|
||||||
err = authverify.CheckAccessV3(ctx, req.UserInfo.UserID)
|
err = authverify.CheckAccessV3(ctx, req.UserInfo.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CallbackBeforeUpdateUserInfoEx(ctx, req); err != nil {
|
if err = CallbackBeforeUpdateUserInfoEx(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data := convert.UserPb2DBMapEx(req.UserInfo)
|
data := convert.UserPb2DBMapEx(req.UserInfo)
|
||||||
@ -172,17 +163,17 @@ func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUse
|
|||||||
}
|
}
|
||||||
if req.UserInfo.Nickname != nil || req.UserInfo.FaceURL != nil {
|
if req.UserInfo.Nickname != nil || req.UserInfo.FaceURL != nil {
|
||||||
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
||||||
log.ZError(ctx, "NotificationUserInfoUpdate", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, friendID := range friends {
|
for _, friendID := range friends {
|
||||||
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
||||||
}
|
}
|
||||||
if err := CallbackAfterUpdateUserInfoEx(ctx, req); err != nil {
|
if err := CallbackAfterUpdateUserInfoEx(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
||||||
log.ZError(ctx, "NotificationUserInfoUpdate", err, "userID", req.UserInfo.UserID)
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
@ -205,7 +196,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR
|
|||||||
if utils.Duplicate(req.CheckUserIDs) {
|
if utils.Duplicate(req.CheckUserIDs) {
|
||||||
return nil, errs.ErrArgs.Wrap("userID repeated")
|
return nil, errs.ErrArgs.Wrap("userID repeated")
|
||||||
}
|
}
|
||||||
err = authverify.CheckAdmin(ctx)
|
err = authverify.CheckAdmin(ctx, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -252,8 +243,8 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
|
|||||||
if len(req.Users) == 0 {
|
if len(req.Users) == 0 {
|
||||||
return nil, errs.ErrArgs.Wrap("users is empty")
|
return nil, errs.ErrArgs.Wrap("users is empty")
|
||||||
}
|
}
|
||||||
if req.Secret != config.Config.Secret {
|
if req.Secret != s.config.Secret {
|
||||||
log.ZDebug(ctx, "UserRegister", config.Config.Secret, req.Secret)
|
log.ZDebug(ctx, "UserRegister", s.config.Secret, req.Secret)
|
||||||
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
||||||
}
|
}
|
||||||
if utils.DuplicateAny(req.Users, func(e *sdkws.UserInfo) string { return e.UserID }) {
|
if utils.DuplicateAny(req.Users, func(e *sdkws.UserInfo) string { return e.UserID }) {
|
||||||
@ -276,7 +267,7 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
|
|||||||
if exist {
|
if exist {
|
||||||
return nil, errs.ErrRegisteredAlready.Wrap("userID registered already")
|
return nil, errs.ErrRegisteredAlready.Wrap("userID registered already")
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeUserRegister(ctx, req); err != nil {
|
if err := CallbackBeforeUserRegister(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@ -296,7 +287,7 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackAfterUserRegister(ctx, req); err != nil {
|
if err := CallbackAfterUserRegister(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -391,7 +382,7 @@ func (s *userServer) GetSubscribeUsersStatus(ctx context.Context,
|
|||||||
|
|
||||||
// ProcessUserCommandAdd user general function add.
|
// ProcessUserCommandAdd user general function add.
|
||||||
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
|
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -422,7 +413,7 @@ func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.Proc
|
|||||||
|
|
||||||
// ProcessUserCommandDelete user general function delete.
|
// ProcessUserCommandDelete user general function delete.
|
||||||
func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) {
|
func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) {
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -445,7 +436,7 @@ func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.P
|
|||||||
|
|
||||||
// ProcessUserCommandUpdate user general function update.
|
// ProcessUserCommandUpdate user general function update.
|
||||||
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
|
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -477,7 +468,7 @@ func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.P
|
|||||||
|
|
||||||
func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) {
|
func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) {
|
||||||
|
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -506,7 +497,7 @@ func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.Proc
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
|
func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -535,7 +526,7 @@ func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.AddNotificationAccountReq) (*pbuser.AddNotificationAccountResp, error) {
|
func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.AddNotificationAccountReq) (*pbuser.AddNotificationAccountResp, error) {
|
||||||
if err := authverify.CheckIMAdmin(ctx); err != nil {
|
if err := authverify.CheckIMAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,7 +569,7 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbuser.UpdateNotificationAccountInfoReq) (*pbuser.UpdateNotificationAccountInfoResp, error) {
|
func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbuser.UpdateNotificationAccountInfoReq) (*pbuser.UpdateNotificationAccountInfoResp, error) {
|
||||||
if err := authverify.CheckIMAdmin(ctx); err != nil {
|
if err := authverify.CheckIMAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,7 +596,7 @@ func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbu
|
|||||||
|
|
||||||
func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.SearchNotificationAccountReq) (*pbuser.SearchNotificationAccountResp, error) {
|
func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.SearchNotificationAccountReq) (*pbuser.SearchNotificationAccountResp, error) {
|
||||||
// Check if user is an admin
|
// Check if user is an admin
|
||||||
if err := authverify.CheckIMAdmin(ctx); err != nil {
|
if err := authverify.CheckIMAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,7 +670,7 @@ func (s *userServer) userModelToResp(users []*relation.UserModel, pagination pag
|
|||||||
accounts := make([]*pbuser.NotificationAccountInfo, 0)
|
accounts := make([]*pbuser.NotificationAccountInfo, 0)
|
||||||
var total int64
|
var total int64
|
||||||
for _, v := range users {
|
for _, v := range users {
|
||||||
if v.AppMangerLevel == constant.AppNotificationAdmin && !utils.IsContain(v.UserID, config.Config.IMAdmin.UserID) {
|
if v.AppMangerLevel == constant.AppNotificationAdmin && !utils.IsContain(v.UserID, s.config.IMAdmin.UserID) {
|
||||||
temp := &pbuser.NotificationAccountInfo{
|
temp := &pbuser.NotificationAccountInfo{
|
||||||
UserID: v.UserID,
|
UserID: v.UserID,
|
||||||
FaceURL: v.FaceURL,
|
FaceURL: v.FaceURL,
|
||||||
|
@ -20,11 +20,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -58,9 +56,9 @@ import (
|
|||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
// if len(seqs) > 0 {
|
// if len(seqs) > 0 {
|
||||||
// if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]interface{}{"latest_msg_destruct_time": now}); err
|
// if err := c.conversationDatabase.UpdateUsersConversationField(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]interface{}{"latest_msg_destruct_time": now}); err
|
||||||
// != nil {
|
// != nil {
|
||||||
// log.ZError(ctx, "updateUsersConversationFiled failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
|
// log.ZError(ctx, "updateUsersConversationField failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
// if err := c.msgNotificationSender.UserDeleteMsgsNotification(ctx, conversation.OwnerUserID, conversation.ConversationID, seqs); err != nil {
|
// if err := c.msgNotificationSender.UserDeleteMsgsNotification(ctx, conversation.OwnerUserID, conversation.ConversationID, seqs); err != nil {
|
||||||
@ -139,8 +137,8 @@ func (c *MsgTool) ConversationsDestructMsgs() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(seqs) > 0 {
|
if len(seqs) > 0 {
|
||||||
if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]any{"latest_msg_destruct_time": now}); err != nil {
|
if err := c.conversationDatabase.UpdateUsersConversationField(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]any{"latest_msg_destruct_time": now}); err != nil {
|
||||||
log.ZError(ctx, "updateUsersConversationFiled failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
|
log.ZError(ctx, "updateUsersConversationField failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := c.msgNotificationSender.UserDeleteMsgsNotification(ctx, conversation.OwnerUserID, conversation.ConversationID, seqs); err != nil {
|
if err := c.msgNotificationSender.UserDeleteMsgsNotification(ctx, conversation.OwnerUserID, conversation.ConversationID, seqs); err != nil {
|
||||||
|
@ -23,41 +23,39 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
"github.com/robfig/cron/v3"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
"github.com/robfig/cron/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartTask() error {
|
func StartTask(config *config.GlobalConfig) error {
|
||||||
fmt.Println("cron task start, config", config.Config.ChatRecordsClearTime)
|
fmt.Println("cron task start, config", config.ChatRecordsClearTime)
|
||||||
|
|
||||||
msgTool, err := InitMsgTool()
|
msgTool, err := InitMsgTool(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
msgTool.convertTools()
|
msgTool.convertTools()
|
||||||
|
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// register cron tasks
|
// register cron tasks
|
||||||
var crontab = cron.New()
|
var crontab = cron.New()
|
||||||
fmt.Println("start chatRecordsClearTime cron task", "cron config", config.Config.ChatRecordsClearTime)
|
fmt.Printf("Start chatRecordsClearTime cron task, cron config: %s\n", config.ChatRecordsClearTime)
|
||||||
_, err = crontab.AddFunc(config.Config.ChatRecordsClearTime, cronWrapFunc(rdb, "cron_clear_msg_and_fix_seq", msgTool.AllConversationClearMsgAndFixSeq))
|
_, err = crontab.AddFunc(config.ChatRecordsClearTime, cronWrapFunc(config, rdb, "cron_clear_msg_and_fix_seq", msgTool.AllConversationClearMsgAndFixSeq))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("start msgDestruct cron task", "cron config", config.Config.MsgDestructTime)
|
fmt.Printf("Start msgDestruct cron task, cron config: %s\n", config.MsgDestructTime)
|
||||||
_, err = crontab.AddFunc(config.Config.MsgDestructTime, cronWrapFunc(rdb, "cron_conversations_destruct_msgs", msgTool.ConversationsDestructMsgs))
|
_, err = crontab.AddFunc(config.MsgDestructTime, cronWrapFunc(config, rdb, "cron_conversations_destruct_msgs", msgTool.ConversationsDestructMsgs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err, "cron_conversations_destruct_msgs")
|
||||||
}
|
}
|
||||||
|
|
||||||
// start crontab
|
// start crontab
|
||||||
@ -93,8 +91,8 @@ func netlock(rdb redis.UniversalClient, key string, ttl time.Duration) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func cronWrapFunc(rdb redis.UniversalClient, key string, fn func()) func() {
|
func cronWrapFunc(config *config.GlobalConfig, rdb redis.UniversalClient, key string, fn func()) func() {
|
||||||
enableCronLocker := config.Config.EnableCronLocker
|
enableCronLocker := config.EnableCronLocker
|
||||||
return func() {
|
return func() {
|
||||||
// if don't enable cron-locker, call fn directly.
|
// if don't enable cron-locker, call fn directly.
|
||||||
if !enableCronLocker {
|
if !enableCronLocker {
|
||||||
|
@ -15,12 +15,17 @@
|
|||||||
package tools
|
package tools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -61,7 +66,7 @@ func TestCronWrapFunc(t *testing.T) {
|
|||||||
start := time.Now()
|
start := time.Now()
|
||||||
key := fmt.Sprintf("cron-%v", rand.Int31())
|
key := fmt.Sprintf("cron-%v", rand.Int31())
|
||||||
crontab := cron.New(cron.WithSeconds())
|
crontab := cron.New(cron.WithSeconds())
|
||||||
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(rdb, key, cb))
|
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(config.NewGlobalConfig(), rdb, key, cb))
|
||||||
crontab.Start()
|
crontab.Start()
|
||||||
<-done
|
<-done
|
||||||
|
|
||||||
@ -71,7 +76,11 @@ func TestCronWrapFunc(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCronWrapFuncWithNetlock(t *testing.T) {
|
func TestCronWrapFuncWithNetlock(t *testing.T) {
|
||||||
config.Config.EnableCronLocker = true
|
conf, err := initCfg()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
conf.EnableCronLocker = true
|
||||||
rdb := redis.NewClient(&redis.Options{})
|
rdb := redis.NewClient(&redis.Options{})
|
||||||
defer rdb.Close()
|
defer rdb.Close()
|
||||||
|
|
||||||
@ -80,10 +89,10 @@ func TestCronWrapFuncWithNetlock(t *testing.T) {
|
|||||||
crontab := cron.New(cron.WithSeconds())
|
crontab := cron.New(cron.WithSeconds())
|
||||||
|
|
||||||
key := fmt.Sprintf("cron-%v", rand.Int31())
|
key := fmt.Sprintf("cron-%v", rand.Int31())
|
||||||
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(rdb, key, func() {
|
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(conf, rdb, key, func() {
|
||||||
done <- "host1"
|
done <- "host1"
|
||||||
}))
|
}))
|
||||||
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(rdb, key, func() {
|
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(conf, rdb, key, func() {
|
||||||
done <- "host2"
|
done <- "host2"
|
||||||
}))
|
}))
|
||||||
crontab.Start()
|
crontab.Start()
|
||||||
@ -94,3 +103,22 @@ func TestCronWrapFuncWithNetlock(t *testing.T) {
|
|||||||
|
|
||||||
crontab.Stop()
|
crontab.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initCfg() (*config.GlobalConfig, error) {
|
||||||
|
const (
|
||||||
|
defaultCfgPath = "../../../../../config/config.yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
cfgPath := flag.String("c", defaultCfgPath, "Path to the configuration file")
|
||||||
|
data, err := os.ReadFile(*cfgPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(err, "ReadFile unmarshal failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
conf := config.NewGlobalConfig()
|
||||||
|
err = yaml.Unmarshal(data, &conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(err, "InitConfig unmarshal failed")
|
||||||
|
}
|
||||||
|
return conf, nil
|
||||||
|
}
|
||||||
|
@ -18,32 +18,26 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
|
||||||
|
|
||||||
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
|
||||||
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/mw"
|
"github.com/OpenIMSDK/tools/mw"
|
||||||
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
|
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MsgTool struct {
|
type MsgTool struct {
|
||||||
@ -52,10 +46,12 @@ type MsgTool struct {
|
|||||||
userDatabase controller.UserDatabase
|
userDatabase controller.UserDatabase
|
||||||
groupDatabase controller.GroupDatabase
|
groupDatabase controller.GroupDatabase
|
||||||
msgNotificationSender *notification.MsgNotificationSender
|
msgNotificationSender *notification.MsgNotificationSender
|
||||||
|
Config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase,
|
||||||
|
msgNotificationSender *notification.MsgNotificationSender, config *config.GlobalConfig,
|
||||||
) *MsgTool {
|
) *MsgTool {
|
||||||
return &MsgTool{
|
return &MsgTool{
|
||||||
msgDatabase: msgDatabase,
|
msgDatabase: msgDatabase,
|
||||||
@ -63,32 +59,33 @@ func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controlle
|
|||||||
groupDatabase: groupDatabase,
|
groupDatabase: groupDatabase,
|
||||||
conversationDatabase: conversationDatabase,
|
conversationDatabase: conversationDatabase,
|
||||||
msgNotificationSender: msgNotificationSender,
|
msgNotificationSender: msgNotificationSender,
|
||||||
|
Config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitMsgTool() (*MsgTool, error) {
|
func InitMsgTool(config *config.GlobalConfig) (*MsgTool, error) {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
discov, err := kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
discov, err := kdisc.NewDiscoveryRegister(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
||||||
userDB, err := mgo.NewUserMongo(mongo.GetDatabase())
|
userDB, err := mgo.NewUserMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
msgDatabase, err := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase())
|
msgDatabase, err := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase(config.Mongo.Database), config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase())
|
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase(config.Mongo.Database))
|
||||||
ctxTx := tx.NewMongo(mongo.GetClient())
|
ctxTx := tx.NewMongo(mongo.GetClient())
|
||||||
userDatabase := controller.NewUserDatabase(
|
userDatabase := controller.NewUserDatabase(
|
||||||
userDB,
|
userDB,
|
||||||
@ -96,19 +93,19 @@ func InitMsgTool() (*MsgTool, error) {
|
|||||||
ctxTx,
|
ctxTx,
|
||||||
userMongoDB,
|
userMongoDB,
|
||||||
)
|
)
|
||||||
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase())
|
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase())
|
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase())
|
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase())
|
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -118,9 +115,9 @@ func InitMsgTool() (*MsgTool, error) {
|
|||||||
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB),
|
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB),
|
||||||
ctxTx,
|
ctxTx,
|
||||||
)
|
)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(discov)
|
msgRpcClient := rpcclient.NewMessageRpcClient(discov, config)
|
||||||
msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient))
|
msgNotificationSender := notification.NewMsgNotificationSender(config, rpcclient.WithRpcClient(&msgRpcClient))
|
||||||
msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase, msgNotificationSender)
|
msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase, msgNotificationSender, config)
|
||||||
return msgTool, nil
|
return msgTool, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,8 +179,8 @@ func (c *MsgTool) AllConversationClearMsgAndFixSeq() {
|
|||||||
|
|
||||||
func (c *MsgTool) ClearConversationsMsg(ctx context.Context, conversationIDs []string) {
|
func (c *MsgTool) ClearConversationsMsg(ctx context.Context, conversationIDs []string) {
|
||||||
for _, conversationID := range conversationIDs {
|
for _, conversationID := range conversationIDs {
|
||||||
if err := c.msgDatabase.DeleteConversationMsgsAndSetMinSeq(ctx, conversationID, int64(config.Config.RetainChatRecords*24*60*60)); err != nil {
|
if err := c.msgDatabase.DeleteConversationMsgsAndSetMinSeq(ctx, conversationID, int64(c.Config.RetainChatRecords*24*60*60)); err != nil {
|
||||||
log.ZError(ctx, "DeleteUserSuperGroupMsgsAndSetMinSeq failed", err, "conversationID", conversationID, "DBRetainChatRecords", config.Config.RetainChatRecords)
|
log.ZError(ctx, "DeleteUserSuperGroupMsgsAndSetMinSeq failed", err, "conversationID", conversationID, "DBRetainChatRecords", c.Config.RetainChatRecords)
|
||||||
}
|
}
|
||||||
if err := c.checkMaxSeq(ctx, conversationID); err != nil {
|
if err := c.checkMaxSeq(ctx, conversationID); err != nil {
|
||||||
log.ZError(ctx, "fixSeq failed", err, "conversationID", conversationID)
|
log.ZError(ctx, "fixSeq failed", err, "conversationID", conversationID)
|
||||||
@ -197,7 +194,8 @@ func (c *MsgTool) checkMaxSeqWithMongo(ctx context.Context, conversationID strin
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if math.Abs(float64(maxSeqMongo-maxSeqCache)) > 10 {
|
if math.Abs(float64(maxSeqMongo-maxSeqCache)) > 10 {
|
||||||
log.ZError(ctx, "cache max seq and mongo max seq is diff > 10", nil, "maxSeqMongo", maxSeqMongo, "minSeqMongo", minSeqMongo, "maxSeqCache", maxSeqCache, "conversationID", conversationID)
|
err = fmt.Errorf("cache max seq and mongo max seq is diff > 10, maxSeqMongo:%d,minSeqMongo:%d,maxSeqCache:%d,conversationID:%s", maxSeqMongo, minSeqMongo, maxSeqCache, conversationID)
|
||||||
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -219,7 +217,6 @@ func (c *MsgTool) checkMaxSeq(ctx context.Context, conversationID string) error
|
|||||||
func (c *MsgTool) FixAllSeq(ctx context.Context) error {
|
func (c *MsgTool) FixAllSeq(ctx context.Context) error {
|
||||||
conversationIDs, err := c.conversationDatabase.GetAllConversationIDs(ctx)
|
conversationIDs, err := c.conversationDatabase.GetAllConversationIDs(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZError(ctx, "GetAllConversationIDs failed", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, conversationID := range conversationIDs {
|
for _, conversationID := range conversationIDs {
|
||||||
|
@ -18,7 +18,6 @@ import (
|
|||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ type LocationElem struct {
|
|||||||
Longitude float64 `mapstructure:"longitude" validate:"required"`
|
Longitude float64 `mapstructure:"longitude" validate:"required"`
|
||||||
Latitude float64 `mapstructure:"latitude" validate:"required"`
|
Latitude float64 `mapstructure:"latitude" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
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"`
|
||||||
|
@ -23,64 +23,63 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/tokenverify"
|
"github.com/OpenIMSDK/tools/tokenverify"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Secret() jwt.Keyfunc {
|
func Secret(secret string) jwt.Keyfunc {
|
||||||
return func(token *jwt.Token) (any, error) {
|
return func(token *jwt.Token) (any, error) {
|
||||||
return []byte(config.Config.Secret), nil
|
return []byte(secret), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) {
|
func CheckAccessV3(ctx context.Context, ownerUserID string, config *config.GlobalConfig) (err error) {
|
||||||
opUserID := mcontext.GetOpUserID(ctx)
|
opUserID := mcontext.GetOpUserID(ctx)
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(opUserID, config.Config.Manager.UserID) {
|
if len(config.Manager.UserID) > 0 && utils.IsContain(opUserID, config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if utils.IsContain(opUserID, config.Config.IMAdmin.UserID) {
|
if utils.IsContain(opUserID, config.IMAdmin.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if opUserID == ownerUserID {
|
if opUserID == ownerUserID {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errs.ErrNoPermission.Wrap(utils.GetSelfFuncName())
|
return errs.ErrNoPermission.Wrap("ownerUserID", ownerUserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsAppManagerUid(ctx context.Context) bool {
|
func IsAppManagerUid(ctx context.Context, config *config.GlobalConfig) bool {
|
||||||
return (len(config.Config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID)) ||
|
return (len(config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Manager.UserID)) ||
|
||||||
utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.IMAdmin.UserID)
|
utils.IsContain(mcontext.GetOpUserID(ctx), config.IMAdmin.UserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAdmin(ctx context.Context) error {
|
func CheckAdmin(ctx context.Context, config *config.GlobalConfig) error {
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) {
|
if len(config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.IMAdmin.UserID) {
|
if utils.IsContain(mcontext.GetOpUserID(ctx), config.IMAdmin.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx)))
|
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx)))
|
||||||
}
|
}
|
||||||
func CheckIMAdmin(ctx context.Context) error {
|
func CheckIMAdmin(ctx context.Context, config *config.GlobalConfig) error {
|
||||||
if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.IMAdmin.UserID) {
|
if utils.IsContain(mcontext.GetOpUserID(ctx), config.IMAdmin.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) {
|
if len(config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not CheckIMAdmin userID", mcontext.GetOpUserID(ctx)))
|
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not CheckIMAdmin userID", mcontext.GetOpUserID(ctx)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseRedisInterfaceToken(redisToken any) (*tokenverify.Claims, error) {
|
func ParseRedisInterfaceToken(redisToken any, secret string) (*tokenverify.Claims, error) {
|
||||||
return tokenverify.GetClaimFromToken(string(redisToken.([]uint8)), Secret())
|
return tokenverify.GetClaimFromToken(string(redisToken.([]uint8)), Secret(secret))
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsManagerUserID(opUserID string) bool {
|
func IsManagerUserID(opUserID string, config *config.GlobalConfig) bool {
|
||||||
return (len(config.Config.Manager.UserID) > 0 && utils.IsContain(opUserID, config.Config.Manager.UserID)) || utils.IsContain(opUserID, config.Config.IMAdmin.UserID)
|
return (len(config.Manager.UserID) > 0 && utils.IsContain(opUserID, config.Manager.UserID)) || utils.IsContain(opUserID, config.IMAdmin.UserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func WsVerifyToken(token, userID string, platformID int) error {
|
func WsVerifyToken(token, userID, secret string, platformID int) error {
|
||||||
claim, err := tokenverify.GetClaimFromToken(token, Secret())
|
claim, err := tokenverify.GetClaimFromToken(token, Secret(secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ package callbackstruct
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
common "github.com/OpenIMSDK/protocol/sdkws"
|
common "github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,33 +16,42 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/internal/api"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ApiCmd struct {
|
type ApiCmd struct {
|
||||||
*RootCmd
|
*RootCmd
|
||||||
|
initFunc func(config *config.GlobalConfig, port int, promPort int) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApiCmd() *ApiCmd {
|
func NewApiCmd() *ApiCmd {
|
||||||
ret := &ApiCmd{NewRootCmd("api")}
|
ret := &ApiCmd{RootCmd: NewRootCmd("api"), initFunc: api.Start}
|
||||||
ret.SetRootCmdPt(ret)
|
ret.SetRootCmdPt(ret)
|
||||||
|
ret.addPreRun()
|
||||||
|
ret.addRunE()
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ApiCmd) AddApi(f func(port int, promPort int) error) {
|
func (a *ApiCmd) addPreRun() {
|
||||||
|
a.Command.PreRun = func(cmd *cobra.Command, args []string) {
|
||||||
|
a.port = a.getPortFlag(cmd)
|
||||||
|
a.prometheusPort = a.getPrometheusPortFlag(cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *ApiCmd) addRunE() {
|
||||||
a.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
a.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
return f(a.getPortFlag(cmd), a.getPrometheusPortFlag(cmd))
|
return a.initFunc(a.config, a.port, a.prometheusPort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ApiCmd) GetPortFromConfig(portType string) int {
|
func (a *ApiCmd) GetPortFromConfig(portType string) int {
|
||||||
if portType == constant.FlagPort {
|
if portType == constant.FlagPort {
|
||||||
return config2.Config.Api.OpenImApiPort[0]
|
return a.config.Api.OpenImApiPort[0]
|
||||||
} else if portType == constant.FlagPrometheusPort {
|
} else if portType == constant.FlagPrometheusPort {
|
||||||
return config2.Config.Prometheus.ApiPrometheusPort[0]
|
return a.config.Prometheus.ApiPrometheusPort[0]
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -14,25 +14,35 @@
|
|||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import "github.com/spf13/cobra"
|
import (
|
||||||
|
"github.com/openimsdk/open-im-server/v3/internal/tools"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
type CronTaskCmd struct {
|
type CronTaskCmd struct {
|
||||||
*RootCmd
|
*RootCmd
|
||||||
|
initFunc func(config *config.GlobalConfig) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCronTaskCmd() *CronTaskCmd {
|
func NewCronTaskCmd() *CronTaskCmd {
|
||||||
ret := &CronTaskCmd{NewRootCmd("cronTask", WithCronTaskLogName())}
|
ret := &CronTaskCmd{RootCmd: NewRootCmd("cronTask", WithCronTaskLogName()),
|
||||||
|
initFunc: tools.StartTask}
|
||||||
|
ret.addRunE()
|
||||||
ret.SetRootCmdPt(ret)
|
ret.SetRootCmdPt(ret)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CronTaskCmd) addRunE(f func() error) {
|
func (c *CronTaskCmd) addRunE() {
|
||||||
c.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
c.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
return f()
|
return c.initFunc(c.config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CronTaskCmd) Exec(f func() error) error {
|
func (c *CronTaskCmd) Exec() error {
|
||||||
c.addRunE(f)
|
|
||||||
return c.Execute()
|
return c.Execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CronTaskCmd) GetPortFromConfig(portType string) int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user