Compare commits

...

33 Commits

Author SHA1 Message Date
Xinwei Xiong 76b35210aa Merge pull request #1719 from FGadvancer/release-v3.5
fix: group messages sync failed.
2024-01-09 10:57:38 +08:00
Gordon 093f9a3b34 fix: group messages sync failed. 2024-01-09 10:17:39 +08:00
Xinwei Xiong 7ad8a7241d Merge pull request #1712 from luhaoling/realea3.5
fix: fix some bug
2024-01-08 21:37:56 +08:00
luhaoling c71bcefcbe fix: fix some bug 2024-01-08 18:27:50 +08:00
Xinwei Xiong c4a8602428 Merge pull request #1690 from openimsdk/feat/optimizing-mongo-env
fix openim config mongo passwd env
2024-01-05 10:10:35 +08:00
Xinwei Xiong (cubxxw) b17b364b02 fix openim config mongo passwd env
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
2024-01-05 10:02:37 +08:00
Xinwei Xiong 7e2c535f37 Merge pull request #1687 from openimsdk/main
rebase openim main to release-v3.5
2024-01-04 20:57:56 +08:00
Xinwei Xiong e0244d9ca7 Update docker-start-all.sh fix MSG_TRANSFER_PROM_PORT (#1679)
* fix: fix the bug

* fix: fix the imAdmin permission and searchNoficitaion resp

* 2023 Annual Summary Reflections and Aspirations

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

* fix: dissmissGroup and lack of keyword bug (#1678)

* Update docker-start-all.sh

* Update env-template.yaml

* Update docker-start-all.sh

---------

Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
Co-authored-by: luhaoling <2198702716@qq.com>
Co-authored-by: Brabem <69128477+luhaoling@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>
2024-01-04 12:51:21 +00:00
skiffer-git 6764fa5e70 MongoDB supports non-root users (#1684)
* MongoDB supports non-root users

Signed-off-by: skiffer-git <44203734@qq.com>

* Update component.go

* Update env-template.yaml

* Update docker-compose.yml

* Update environment.sh

* Update openim.yaml

* Update mongo-init.sh

---------

Signed-off-by: skiffer-git <44203734@qq.com>
Co-authored-by: Xinwei Xiong <3293172751@qq.com>
2024-01-04 12:50:29 +00:00
OpenIM Robot a3acba5eea Merge pull request #1683 from openimsdk/cubxxw-patch-2
Update docker-start-all.sh
2024-01-04 18:25:20 +08:00
Xinwei Xiong baf0d1888c Update docker-start-all.sh 2024-01-04 18:24:54 +08:00
Xinwei Xiong 5b99eb21e7 Merge pull request #1680 from openimsdk/cubxxw-patch-1
Update docker-start-all.sh fix MSG_TRANSFER_PROM_PORT
2024-01-04 17:43:26 +08:00
OpenIM Bot 58ab340d1e Update env-template.yaml 2024-01-04 17:42:57 +08:00
Xinwei Xiong d8eec588de Merge branch 'release-v3.5' into cubxxw-patch-1 2024-01-04 17:40:40 +08:00
Xinwei Xiong b19d1f1726 Update docker-start-all.sh 2024-01-04 17:39:32 +08:00
Brabem d446bdb943 fix: dissmissGroup and lack of keyword bug (#1678) 2024-01-04 17:24:51 +08:00
Brabem d3047d73b6 fix: dissmissGroup and lack of keyword bug (#1672)
* feat: add GetConversationsUnreadSeqAndMaxSeq func

* feat: add GetConversationsUnreadSeqAndMaxSeq func

* feat: add GetConversationsUnreadSeqAndMaxSeq func

* fix: fix the conflect

* feat: add GetConversationList Api

* fix: fix the error

* fix: move the GetConversationList to conversation folder

* fix: fix the go.mod

* fix: add InitiateFormData and CompleteFormData

* fix: fix the error

* fix: find error

* fix: test

* feat: add notification API

* fix: find error

* fix: fix the error

* fix: fix the PinFriend error

* fix: fix the Ex error

* fix: find the error

* fix: fix the rpc error

* fix: fix the error

* fix: fix the log error

* fix: fix the error1

* fix: fix the error

* fix: fix the script

* fix: fix the error

* fix: fix the error

* fix: fix the error of tag

* fix: fix the protocol

* fix: fix the error

* fix: fix the error

* fix: fix the err not wrap

* fix: fix the error

* fix: fix GetGroupMembers by nickname

* fix: support search userInfo by nickname or userID

* fix: fix the search by nickname error

* fix: fix the mod
2024-01-04 08:04:15 +00:00
Xinwei Xiong 09c3229d9d feat(main): fix openim docker start openim server internal port lock (#1673)
* fix: fix the bug

* fix: fix the imAdmin permission and searchNoficitaion resp

* 2023 Annual Summary Reflections and Aspirations

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

---------

Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
Co-authored-by: luhaoling <2198702716@qq.com>
2024-01-04 08:01:32 +00:00
Xinwei Xiong 4abddd8247 Merge pull request #1674 from openimsdk/feat/add-docker-start
feat(release-v3.5): fix openim docker start openim server internal port lock
2024-01-04 15:59:55 +08:00
Xinwei Xiong c70ee5cbfb Merge branch 'release-v3.5' into feat/add-docker-start 2024-01-04 15:47:31 +08:00
Xinwei Xiong (cubxxw) 7bb44b8b88 2023 Annual Summary Reflections and Aspirations
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
2024-01-04 15:40:14 +08:00
Xinwei Xiong e1c2e94ec9 Update env-template.yaml (#1670)
* Update env-template.yaml

* Update env-template.yaml

* Update env-template.yaml
2024-01-04 06:15:14 +00:00
Xinwei Xiong 019ef60616 Merge pull request #1666 from luhaoling/releases
fix: fix the imAdmin permission and searchNoficitaion resp
2024-01-03 18:27:16 +08:00
luhaoling 16bc053d09 fix: fix the imAdmin permission and searchNoficitaion resp 2024-01-03 18:11:02 +08:00
Brabem 9e2a256817 fix: fix the imAdmin permission (#1664)
* fix: fix the error

* fix: fix the SearchNotificationAccount resp

* fix: fix the god

* Update install-im-server.sh

* Update install-im-server.sh

* fix: fix the searchNotificationAccounts

* fix: fix the imAdmin competence

* fix: fix the error

* fix: fix the checkAdminV3

---------

Co-authored-by: Xinwei Xiong <3293172751@qq.com>
2024-01-03 17:24:02 +08:00
Brabem 587533df4d fix: update Notification update resp (#1663)
* fix: fix the error

* fix: fix the SearchNotificationAccount resp

* fix: fix the god

* Update install-im-server.sh

* Update install-im-server.sh

---------

Co-authored-by: Xinwei Xiong <3293172751@qq.com>
2024-01-03 07:46:38 +00:00
luhaoling 61f83212b2 fix: fix the bug 2024-01-03 15:39:31 +08:00
Gordon 5d1cf8c061 fix: Adjust the logic in multiTerminalLoginChecker to prevent onlineUserNum from decreasing below zero, thereby avoiding negative values. (#1658)
* fix: add notifications for some notifications.

* fix: modify dismissed group's status.

* fix: Adjust the logic in multiTerminalLoginChecker to prevent onlineUserNum from decreasing below zero, thereby avoiding negative values.
2024-01-03 07:32:42 +00:00
Brabem f1ba5c2bff fix: fix the error (#1653) 2024-01-03 02:07:01 +00:00
Xinwei Xiong 11108e1ddf fix: release openim version not auto build (#1660) 2024-01-02 12:59:26 +00:00
Gordon c19bafc49d fix: modify dismissed group's status. (#1655)
* fix: add notifications for some notifications.

* fix: modify dismissed group's status.
2024-01-02 07:37:05 +00:00
Xinwei Xiong d594d6f517 fix: install-im-server (#1648)
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
2024-01-02 04:42:46 +00:00
chao 3fffc2f212 feat: support websocket first message method response code (#1651)
* upgrade package and rtc convert

* upgrade package and rtc convert

* upgrade package and rtc convert

* upgrade package and rtc convert

* friend user

* s3 form data

* s3 form data

* s3 form data

* s3 form data

* s3 form data

* s3 form data

* s3 form data

* s3 form data

* s3 form data

* ws

* ws

* ws

* ws

* ws
2024-01-02 03:51:09 +00:00
28 changed files with 318 additions and 190 deletions
+25 -1
View File
@@ -3,12 +3,36 @@
before: before:
hooks: hooks:
- make clean
# You may remove this if you don't use go modules. # You may remove this if you don't use go modules.
- make tidy - make tidy
- make copyright.add - make copyright.add
# you may remove this if you don't need go generate # you may remove this if you don't need go generate
- go generate ./... - go generate ./...
git:
# What should be used to sort tags when gathering the current and previous
# tags if there are more than one tag in the same commit.
#
# Default: '-version:refname'
tag_sort: -version:creatordate
# What should be used to specify prerelease suffix while sorting tags when gathering
# the current and previous tags if there are more than one tag in the same commit.
#
# Since: v1.17
prerelease_suffix: "-"
# Tags to be ignored by GoReleaser.
# This means that GoReleaser will not pick up tags that match any of the
# provided values as either previous or current tags.
#
# Templates: allowed.
# Since: v1.21.
ignore_tags:
- nightly
# - "{{.Env.IGNORE_TAG}}"
snapshot: snapshot:
name_template: "{{ incpatch .Version }}-next" name_template: "{{ incpatch .Version }}-next"
@@ -495,4 +519,4 @@ checksum:
algorithm: sha256 algorithm: sha256
release: release:
prerelease: auto prerelease: auto
+16 -13
View File
@@ -84,19 +84,27 @@ OPENIM_IP=${OPENIM_IP}
# Default: ZOOKEEPER_PORT=12181 # Default: ZOOKEEPER_PORT=12181
ZOOKEEPER_PORT=${ZOOKEEPER_PORT} ZOOKEEPER_PORT=${ZOOKEEPER_PORT}
# Port on which MongoDB service is running. # MongoDB service port configuration.
# Default: MONGO_PORT=37017 # Default: MONGO_PORT=37017
# MONGO_PORT=${MONGO_PORT} # MONGO_PORT=${MONGO_PORT}
# Username to authenticate with the MongoDB service. # Username for MongoDB admin user. Used for service authentication.
# Default: MONGO_USERNAME=root # Default: MONGO_USERNAME=root
# MONGO_USERNAME=${MONGO_USERNAME} # MONGO_USERNAME=${MONGO_USERNAME}
# Password to authenticate with the MongoDB service. # Password for MongoDB admin user. Used for service authentication.
# Default: MONGO_PASSWORD=openIM123 # Default: MONGO_PASSWORD=openIM123
MONGO_PASSWORD=${MONGO_PASSWORD} MONGO_PASSWORD=${MONGO_PASSWORD}
# Name of the database in MongoDB to be used. # Username for a regular OpenIM user in MongoDB.
# Default: MONGO_OPENIM_USERNAME=openIM
MONGO_OPENIM_USERNAME=${MONGO_OPENIM_USERNAME}
# Password for a regular OpenIM user in MongoDB.
# Default: MONGO_OPENIM_PASSWORD=openIM123456
MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD}
# Specifies the database name to be used within MongoDB.
# Default: MONGO_DATABASE=openIM_v3 # Default: MONGO_DATABASE=openIM_v3
MONGO_DATABASE=${MONGO_DATABASE} MONGO_DATABASE=${MONGO_DATABASE}
@@ -177,7 +185,6 @@ OPENIM_WS_PORT=${OPENIM_WS_PORT}
# Default: API_OPENIM_PORT=10002 # Default: API_OPENIM_PORT=10002
API_OPENIM_PORT=${API_OPENIM_PORT} API_OPENIM_PORT=${API_OPENIM_PORT}
# ====================================== # ======================================
# ========== OpenIM Chat =============== # ========== OpenIM Chat ===============
# ====================================== # ======================================
@@ -190,9 +197,9 @@ CHAT_IMAGE_VERSION=${CHAT_IMAGE_VERSION}
# Default: OPENIM_CHAT_API_PORT=10008 # Default: OPENIM_CHAT_API_PORT=10008
OPENIM_CHAT_API_PORT=${OPENIM_CHAT_API_PORT} OPENIM_CHAT_API_PORT=${OPENIM_CHAT_API_PORT}
# Directory path for storing data files or related information for OpenIM chat. # Port for the OpenIM admin API.
# Default: OPENIM_CHAT_DATA_DIR=./openim-chat/main # Default: OPENIM_ADMIN_API_PORT=10009
OPENIM_CHAT_DATA_DIR=${OPENIM_CHAT_DATA_DIR} OPENIM_ADMIN_API_PORT=${OPENIM_ADMIN_API_PORT}
# ====================================== # ======================================
# ========== OpenIM Admin ============== # ========== OpenIM Admin ==============
@@ -201,10 +208,6 @@ OPENIM_CHAT_DATA_DIR=${OPENIM_CHAT_DATA_DIR}
# Branch name for OpenIM server. # Branch name for OpenIM server.
# Default: SERVER_IMAGE_VERSION=main # Default: SERVER_IMAGE_VERSION=main
SERVER_IMAGE_VERSION=${SERVER_IMAGE_VERSION} SERVER_IMAGE_VERSION=${SERVER_IMAGE_VERSION}
# Port for the OpenIM admin API.
# Default: OPENIM_ADMIN_API_PORT=10009
OPENIM_ADMIN_API_PORT=${OPENIM_ADMIN_API_PORT}
# Port for the node exporter. # Port for the node exporter.
# Default: NODE_EXPORTER_PORT=19100 # Default: NODE_EXPORTER_PORT=19100
@@ -224,4 +227,4 @@ OPENIM_ADMIN_FRONT_PORT=${OPENIM_ADMIN_FRONT_PORT}
# Port for the alertmanager. # Port for the alertmanager.
# Default: ALERT_MANAGER_PORT=19093 # Default: ALERT_MANAGER_PORT=19093
ALERT_MANAGER_PORT=${ALERT_MANAGER_PORT} ALERT_MANAGER_PORT=${ALERT_MANAGER_PORT}
+2 -2
View File
@@ -53,8 +53,8 @@ mongo:
# Maximum connection pool size # Maximum connection pool size
address: [ ${MONGO_ADDRESS}:${MONGO_PORT} ] address: [ ${MONGO_ADDRESS}:${MONGO_PORT} ]
database: ${MONGO_DATABASE} database: ${MONGO_DATABASE}
username: ${MONGO_USERNAME} username: ${MONGO_OPENIM_USERNAME}
password: ${MONGO_PASSWORD} password: ${MONGO_OPENIM_PASSWORD}
maxPoolSize: ${MONGO_MAX_POOL_SIZE} maxPoolSize: ${MONGO_MAX_POOL_SIZE}
###################### Redis configuration information ###################### ###################### Redis configuration information ######################
+7 -9
View File
@@ -10,6 +10,8 @@ networks:
- subnet: '${DOCKER_BRIDGE_SUBNET:-172.28.0.0/16}' - subnet: '${DOCKER_BRIDGE_SUBNET:-172.28.0.0/16}'
gateway: '${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}' gateway: '${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}'
services: services:
mongodb: mongodb:
image: mongo:${MONGODB_IMAGE_VERSION-6.0.2} image: mongo:${MONGODB_IMAGE_VERSION-6.0.2}
@@ -21,13 +23,15 @@ services:
- "${DATA_DIR:-./}/components/mongodb/data/db:/data/db" - "${DATA_DIR:-./}/components/mongodb/data/db:/data/db"
- "${DATA_DIR:-./}/components/mongodb/data/logs:/data/logs" - "${DATA_DIR:-./}/components/mongodb/data/logs:/data/logs"
- "${DATA_DIR:-./}/components/mongodb/data/conf:/etc/mongo" - "${DATA_DIR:-./}/components/mongodb/data/conf:/etc/mongo"
- ./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro - "./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro"
environment: environment:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
- wiredTigerCacheSizeGB=1 - wiredTigerCacheSizeGB=1
- MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME:-root} - MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME:-root}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD:-openIM123} - MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD:-openIM123}
- MONGO_INITDB_DATABASE=${MONGO_DATABASE:-openIM_v3} - MONGO_INITDB_DATABASE=${MONGO_DATABASE:-openIM_v3}
- MONGO_OPENIM_USERNAME=${MONGO_OPENIM_USERNAME:-openIM} # Non-root username
- MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD:-openIM123456} # Non-root password
restart: always restart: always
networks: networks:
server: server:
@@ -122,9 +126,9 @@ services:
server: server:
ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS:-172.28.0.7} ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS:-172.28.0.7}
## Uncomment and configure the following services as needed # Uncomment and configure the following services as needed
# openim-admin: # openim-admin:
# image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin:toc-base-open-docker.35 # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin-front:v3.4.0
# container_name: openim-admin # container_name: openim-admin
# restart: always # restart: always
# ports: # ports:
@@ -167,12 +171,6 @@ services:
# hostname: grafana # hostname: grafana
# user: root # user: root
# restart: always # restart: always
# environment:
# - GF_SECURITY_ALLOW_EMBEDDING=true
# - GF_SESSION_COOKIE_SAMESITE=none
# - GF_SESSION_COOKIE_SECURE=true
# - GF_AUTH_ANONYMOUS_ENABLED=true
# - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
# ports: # ports:
# - "${GRAFANA_PORT:-13000}:3000" # - "${GRAFANA_PORT:-13000}:3000"
# volumes: # volumes:
+4 -2
View File
@@ -304,8 +304,10 @@ This section involves setting up MongoDB, including its port, address, and crede
| -------------- | -------------- | ----------------------- | | -------------- | -------------- | ----------------------- |
| MONGO_PORT | "27017" | Port used by MongoDB. | | MONGO_PORT | "27017" | Port used by MongoDB. |
| MONGO_ADDRESS | [Generated IP] | IP address for MongoDB. | | MONGO_ADDRESS | [Generated IP] | IP address for MongoDB. |
| MONGO_USERNAME | [User Defined] | Username for MongoDB. | | MONGO_USERNAME | [User Defined] | Admin Username for MongoDB. |
| MONGO_PASSWORD | [User Defined] | Password for MongoDB. | | MONGO_PASSWORD | [User Defined] | Admin Password for MongoDB. |
| MONGO_OPENIM_PASSWORD | [User Defined] | OpenIM Username for MongoDB. |
| MONGO_OPENIM_PASSWORD | [User Defined] | OpenIM Password for MongoDB. |
### 2.8. <a name='TencentCloudCOSConfiguration'></a>Tencent Cloud COS Configuration ### 2.8. <a name='TencentCloudCOSConfiguration'></a>Tencent Cloud COS Configuration
+3 -3
View File
@@ -4,8 +4,8 @@ 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.42 github.com/OpenIMSDK/protocol v0.0.46
github.com/OpenIMSDK/tools v0.0.21 github.com/OpenIMSDK/tools v0.0.23
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
@@ -155,4 +155,4 @@ require (
go.uber.org/zap v1.24.0 // indirect go.uber.org/zap v1.24.0 // indirect
golang.org/x/crypto v0.14.0 // indirect golang.org/x/crypto v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
) )
+2 -2
View File
@@ -18,8 +18,8 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c= github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c=
github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ= github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
github.com/OpenIMSDK/protocol v0.0.42 h1:vIWXqZJZZ1ddleJA25fxhjZ1GyEHATpYM3wVWh4/+PY= github.com/OpenIMSDK/protocol v0.0.46 h1:LKfwcC3pUcJKSxiIyj82fc479BuDbDtsCrPxa7bHxmo=
github.com/OpenIMSDK/protocol v0.0.42/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= github.com/OpenIMSDK/protocol v0.0.46/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
github.com/OpenIMSDK/tools v0.0.21 h1:iTapc2mIEVH/xl5Nd6jfwPub11Pgp44tVcE1rjB3a48= github.com/OpenIMSDK/tools v0.0.21 h1:iTapc2mIEVH/xl5Nd6jfwPub11Pgp44tVcE1rjB3a48=
github.com/OpenIMSDK/tools v0.0.21/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/OpenIMSDK/tools v0.0.21/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
+1
View File
@@ -26,6 +26,7 @@ const (
Compression = "compression" Compression = "compression"
GzipCompressionProtocol = "gzip" GzipCompressionProtocol = "gzip"
BackgroundStatus = "isBackground" BackgroundStatus = "isBackground"
MsgResp = "isMsgResp"
) )
const ( const (
+78 -61
View File
@@ -16,7 +16,10 @@ package msggateway
import ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"fmt"
"github.com/OpenIMSDK/tools/apiresp"
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
@@ -342,11 +345,7 @@ func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Clien
if !clientOK { if !clientOK {
return return
} }
ws.clients.deleteClients(newClient.UserID, oldClients)
isDeleteUser := ws.clients.deleteClients(newClient.UserID, oldClients)
if isDeleteUser {
ws.onlineUserNum.Add(-1)
}
for _, c := range oldClients { for _, c := range oldClients {
err := c.KickOnlineMessage() err := c.KickOnlineMessage()
if err != nil { if err != nil {
@@ -422,84 +421,102 @@ func (ws *WsServer) unregisterClient(client *Client) {
) )
} }
func (ws *WsServer) wsHandler(w http.ResponseWriter, r *http.Request) { func (ws *WsServer) ParseWSArgs(r *http.Request) (args *WSArgs, err error) {
connContext := newContext(w, r) var v WSArgs
defer func() {
args = &v
}()
query := r.URL.Query()
v.MsgResp, _ = strconv.ParseBool(query.Get(MsgResp))
if ws.onlineUserConnNum.Load() >= ws.wsMaxConnNum { if ws.onlineUserConnNum.Load() >= ws.wsMaxConnNum {
httpError(connContext, errs.ErrConnOverMaxNumLimit) return nil, errs.ErrConnOverMaxNumLimit.Wrap("over max conn num limit")
return
} }
var ( if v.Token = query.Get(Token); v.Token == "" {
token string return nil, errs.ErrConnArgsErr.Wrap("token is empty")
userID string
platformIDStr string
exists bool
compression bool
)
token, exists = connContext.Query(Token)
if !exists {
httpError(connContext, errs.ErrConnArgsErr)
return
} }
userID, exists = connContext.Query(WsUserID) if v.UserID = query.Get(WsUserID); v.UserID == "" {
if !exists { return nil, errs.ErrConnArgsErr.Wrap("sendID is empty")
httpError(connContext, errs.ErrConnArgsErr)
return
} }
platformIDStr, exists = connContext.Query(PlatformID) platformIDStr := query.Get(PlatformID)
if !exists { if platformIDStr == "" {
httpError(connContext, errs.ErrConnArgsErr) return nil, errs.ErrConnArgsErr.Wrap("platformID is empty")
return
} }
platformID, err := strconv.Atoi(platformIDStr) platformID, err := strconv.Atoi(platformIDStr)
if err != nil { if err != nil {
httpError(connContext, errs.ErrConnArgsErr) return nil, errs.ErrConnArgsErr.Wrap("platformID is not int")
return
} }
if err = authverify.WsVerifyToken(token, userID, platformID); err != nil { v.PlatformID = platformID
httpError(connContext, err) if err = authverify.WsVerifyToken(v.Token, v.UserID, platformID); err != nil {
return return nil, err
} }
m, err := ws.cache.GetTokensWithoutError(context.Background(), userID, platformID) if query.Get(Compression) == GzipCompressionProtocol {
v.Compression = true
}
if r.Header.Get(Compression) == GzipCompressionProtocol {
v.Compression = true
}
m, err := ws.cache.GetTokensWithoutError(context.Background(), v.UserID, platformID)
if err != nil { if err != nil {
httpError(connContext, err) return nil, err
return
} }
if v, ok := m[token]; ok { if v, ok := m[v.Token]; ok {
switch v { switch v {
case constant.NormalToken: case constant.NormalToken:
case constant.KickedToken: case constant.KickedToken:
httpError(connContext, errs.ErrTokenKicked.Wrap()) return nil, errs.ErrTokenKicked.Wrap()
return
default: default:
httpError(connContext, errs.ErrTokenUnknown.Wrap()) return nil, errs.ErrTokenUnknown.Wrap(fmt.Sprintf("token status is %d", v))
}
} else {
return nil, errs.ErrTokenNotExist.Wrap()
}
return &v, nil
}
type WSArgs struct {
Token string
UserID string
PlatformID int
Compression bool
MsgResp bool
}
func (ws *WsServer) wsHandler(w http.ResponseWriter, r *http.Request) {
connContext := newContext(w, r)
args, pErr := ws.ParseWSArgs(r)
var wsLongConn *GWebSocket
if args.MsgResp {
wsLongConn = newGWebSocket(WebSocket, ws.handshakeTimeout, ws.writeBufferSize)
if err := wsLongConn.GenerateLongConn(w, r); err != nil {
httpError(connContext, err)
return
}
data, err := json.Marshal(apiresp.ParseError(pErr))
if err != nil {
_ = wsLongConn.Close()
return
}
if err := wsLongConn.WriteMessage(MessageText, data); err != nil {
_ = wsLongConn.Close()
return
}
if pErr != nil {
_ = wsLongConn.Close()
return return
} }
} else { } else {
httpError(connContext, errs.ErrTokenNotExist.Wrap()) if pErr != nil {
return httpError(connContext, pErr)
} return
wsLongConn := newGWebSocket(WebSocket, ws.handshakeTimeout, ws.writeBufferSize)
err = wsLongConn.GenerateLongConn(w, r)
if err != nil {
httpError(connContext, err)
return
}
compressProtoc, exists := connContext.Query(Compression)
if exists {
if compressProtoc == GzipCompressionProtocol {
compression = true
} }
} wsLongConn = newGWebSocket(WebSocket, ws.handshakeTimeout, ws.writeBufferSize)
compressProtoc, exists = connContext.GetHeader(Compression) if err := wsLongConn.GenerateLongConn(w, r); err != nil {
if exists { httpError(connContext, err)
if compressProtoc == GzipCompressionProtocol { return
compression = true
} }
} }
client := ws.clientPool.Get().(*Client) client := ws.clientPool.Get().(*Client)
client.ResetClient(connContext, wsLongConn, connContext.GetBackground(), compression, ws, token) client.ResetClient(connContext, wsLongConn, connContext.GetBackground(), args.Compression, ws, args.Token)
ws.registerChan <- client ws.registerChan <- client
go client.readMessage() go client.readMessage()
} }
+44 -6
View File
@@ -476,13 +476,42 @@ func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbgroup.GetGro
func (s *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGroupMemberListReq) (*pbgroup.GetGroupMemberListResp, error) { func (s *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGroupMemberListReq) (*pbgroup.GetGroupMemberListResp, error) {
resp := &pbgroup.GetGroupMemberListResp{} resp := &pbgroup.GetGroupMemberListResp{}
total, members, err := s.db.PageGetGroupMember(ctx, req.GroupID, req.Pagination) var (
total int64
members []*relationtb.GroupMemberModel
err error
)
if req.Keyword == "" {
total, members, err = s.db.PageGetGroupMember(ctx, req.GroupID, req.Pagination)
} else {
members, err = s.db.FindGroupMemberAll(ctx, req.GroupID)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := s.PopulateGroupMember(ctx, members...); err != nil { if err := s.PopulateGroupMember(ctx, members...); err != nil {
return nil, err return nil, err
} }
if req.Keyword != "" {
groupMembers := make([]*relationtb.GroupMemberModel, 0)
for _, member := range members {
if member.UserID == req.Keyword {
groupMembers = append(groupMembers, member)
total++
continue
}
if member.Nickname == req.Keyword {
groupMembers = append(groupMembers, member)
total++
continue
}
}
GMembers := utils.Paginate(groupMembers, int(req.Pagination.GetPageNumber()), int(req.Pagination.GetShowNumber()))
resp.Members = utils.Batch(convert.Db2PbGroupMember, GMembers)
resp.Total = uint32(total)
return resp, nil
}
resp.Total = uint32(total) resp.Total = uint32(total)
resp.Members = utils.Batch(convert.Db2PbGroupMember, members) resp.Members = utils.Batch(convert.Db2PbGroupMember, members)
return resp, nil return resp, nil
@@ -1042,20 +1071,29 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq) (*pbgroup.GetGroupsResp, error) { func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq) (*pbgroup.GetGroupsResp, error) {
resp := &pbgroup.GetGroupsResp{} resp := &pbgroup.GetGroupsResp{}
var ( var (
groups []*relationtb.GroupModel group []*relationtb.GroupModel
err error err error
) )
if req.GroupID != "" { if req.GroupID != "" {
groups, err = s.db.FindGroup(ctx, []string{req.GroupID}) group, err = s.db.FindGroup(ctx, []string{req.GroupID})
resp.Total = uint32(len(groups)) resp.Total = uint32(len(group))
} else { } else {
var total int64 var total int64
total, groups, err = s.db.SearchGroup(ctx, req.GroupName, req.Pagination) total, group, err = s.db.SearchGroup(ctx, req.GroupName, req.Pagination)
resp.Total = uint32(total) resp.Total = uint32(total)
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
var groups []*relationtb.GroupModel
for _, v := range group {
if v.Status == constant.GroupStatusDismissed {
resp.Total--
continue
}
groups = append(groups, v)
}
groupIDs := utils.Slice(groups, func(e *relationtb.GroupModel) string { groupIDs := utils.Slice(groups, func(e *relationtb.GroupModel) string {
return e.GroupID return e.GroupID
}) })
+46 -57
View File
@@ -17,6 +17,7 @@ package user
import ( import (
"context" "context"
"errors" "errors"
"github.com/OpenIMSDK/tools/pagination"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"math/rand" "math/rand"
"strings" "strings"
@@ -58,6 +59,11 @@ type userServer struct {
RegisterCenter registry.SvcDiscoveryRegistry RegisterCenter registry.SvcDiscoveryRegistry
} }
func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
//TODO implement me
panic("implement me")
}
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
rdb, err := cache.NewRedis() rdb, err := cache.NewRedis()
if err != nil { if err != nil {
@@ -228,7 +234,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR
} }
func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) { func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) {
total, users, err := s.Page(ctx, req.Pagination) total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, req.Pagination)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -379,11 +385,6 @@ 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) {
// Assuming you have a method in s.UserDatabase to add a user command
err := s.UserDatabase.AddUserCommand(ctx, req.UserID, req.Type, req.Uuid, req.Value)
if err != nil {
return nil, err
}
return &pbuser.ProcessUserCommandAddResp{}, nil return &pbuser.ProcessUserCommandAddResp{}, nil
} }
@@ -395,42 +396,19 @@ func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.P
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &pbuser.ProcessUserCommandDeleteResp{}, nil return &pbuser.ProcessUserCommandDeleteResp{}, nil
} }
// 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) {
// Assuming you have a method in s.UserDatabase to update a user command
err := s.UserDatabase.UpdateUserCommand(ctx, req.UserID, req.Type, req.Uuid, req.Value)
if err != nil {
return nil, err
}
return &pbuser.ProcessUserCommandUpdateResp{}, nil return &pbuser.ProcessUserCommandUpdateResp{}, nil
} }
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) {
// Fetch user commands from the database
commands, err := s.UserDatabase.GetUserCommands(ctx, req.UserID, req.Type)
if err != nil {
return nil, err
}
// Initialize commandInfoSlice as an empty slice
commandInfoSlice := make([]*pbuser.CommandInfoResp, 0, len(commands))
for _, command := range commands {
// No need to use index since command is already a pointer
commandInfoSlice = append(commandInfoSlice, &pbuser.CommandInfoResp{
Uuid: command.Uuid,
Value: command.Value,
CreateTime: command.CreateTime,
})
}
// Return the response with the slice // Return the response with the slice
return &pbuser.ProcessUserCommandGetResp{KVArray: commandInfoSlice}, nil return &pbuser.ProcessUserCommandGetResp{}, nil
} }
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) {
@@ -438,22 +416,23 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
return nil, err return nil, err
} }
var userID string if req.UserID == "" {
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
userId := s.genUserID() userId := s.genUserID()
_, err := s.UserDatabase.FindWithError(ctx, []string{userId}) _, err := s.UserDatabase.FindWithError(ctx, []string{userId})
if err == nil { if err == nil {
continue continue
}
req.UserID = userId
break
}
if req.UserID == "" {
return nil, errs.ErrInternalServer.Wrap("gen user id failed")
} }
userID = userId
break
}
if userID == "" {
return nil, errs.ErrInternalServer.Wrap("gen user id failed")
} }
user := &tablerelation.UserModel{ user := &tablerelation.UserModel{
UserID: userID, UserID: req.UserID,
Nickname: req.NickName, Nickname: req.NickName,
FaceURL: req.FaceURL, FaceURL: req.FaceURL,
CreateTime: time.Now(), CreateTime: time.Now(),
@@ -463,7 +442,11 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
return nil, err return nil, err
} }
return &pbuser.AddNotificationAccountResp{}, nil return &pbuser.AddNotificationAccountResp{
UserID: req.UserID,
NickName: req.NickName,
FaceURL: req.FaceURL,
}, nil
} }
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) {
@@ -497,30 +480,33 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.
return nil, err return nil, err
} }
if req.NickName != "" { var users []*relation.UserModel
users, err := s.UserDatabase.FindByNickname(ctx, req.NickName) var err error
if req.Keyword != "" {
users, err = s.UserDatabase.Find(ctx, []string{req.Keyword})
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp := s.userModelToResp(users) resp := s.userModelToResp(users, req.Pagination)
return resp, nil if resp.Total != 0 {
} return resp, nil
}
if req.UserID != "" { users, err = s.UserDatabase.FindByNickname(ctx, req.Keyword)
users, err := s.UserDatabase.Find(ctx, []string{req.UserID})
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp := s.userModelToResp(users) resp = s.userModelToResp(users, req.Pagination)
return resp, nil
return resp, nil return resp, nil
} }
_, users, err := s.UserDatabase.Page(ctx, req.Pagination) users, err = s.UserDatabase.FindNotification(ctx, constant.AppNotificationAdmin)
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp := s.userModelToResp(users) resp := s.userModelToResp(users, req.Pagination)
return resp, nil return resp, nil
} }
@@ -554,11 +540,11 @@ func (s *userServer) genUserID() string {
return string(data) return string(data)
} }
func (s *userServer) userModelToResp(users []*relation.UserModel) *pbuser.SearchNotificationAccountResp { func (s *userServer) userModelToResp(users []*relation.UserModel, pagination pagination.Pagination) *pbuser.SearchNotificationAccountResp {
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 || v.AppMangerLevel == constant.AppAdmin { if v.AppMangerLevel == constant.AppNotificationAdmin && !utils.IsContain(v.UserID, config.Config.IMAdmin.UserID) {
temp := &pbuser.NotificationAccountInfo{ temp := &pbuser.NotificationAccountInfo{
UserID: v.UserID, UserID: v.UserID,
FaceURL: v.FaceURL, FaceURL: v.FaceURL,
@@ -568,5 +554,8 @@ func (s *userServer) userModelToResp(users []*relation.UserModel) *pbuser.Search
total += 1 total += 1
} }
} }
return &pbuser.SearchNotificationAccountResp{Total: total, NotificationAccounts: accounts}
notificationAccounts := utils.Paginate(accounts, int(pagination.GetPageNumber()), int(pagination.GetShowNumber()))
return &pbuser.SearchNotificationAccountResp{Total: total, NotificationAccounts: notificationAccounts}
} }
+8 -2
View File
@@ -38,6 +38,9 @@ func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) {
if utils.IsContain(opUserID, config.Config.Manager.UserID) { if utils.IsContain(opUserID, config.Config.Manager.UserID) {
return nil return nil
} }
if utils.IsContain(opUserID, config.Config.IMAdmin.UserID) {
return nil
}
if opUserID == ownerUserID { if opUserID == ownerUserID {
return nil return nil
} }
@@ -45,13 +48,16 @@ func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) {
} }
func IsAppManagerUid(ctx context.Context) bool { func IsAppManagerUid(ctx context.Context) bool {
return utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) return utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) || utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.IMAdmin.UserID)
} }
func CheckAdmin(ctx context.Context) error { func CheckAdmin(ctx context.Context) error {
if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) { if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) {
return nil return nil
} }
if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.IMAdmin.UserID) {
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) error {
@@ -69,7 +75,7 @@ func ParseRedisInterfaceToken(redisToken any) (*tokenverify.Claims, error) {
} }
func IsManagerUserID(opUserID string) bool { func IsManagerUserID(opUserID string) bool {
return utils.IsContain(opUserID, config.Config.Manager.UserID) return utils.IsContain(opUserID, config.Config.Manager.UserID) || utils.IsContain(opUserID, config.Config.IMAdmin.UserID)
} }
func WsVerifyToken(token, userID string, platformID int) error { func WsVerifyToken(token, userID string, platformID int) error {
+1 -1
View File
@@ -279,7 +279,7 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context,
for _, v := range existConversationUserIDs { for _, v := range existConversationUserIDs {
cache = cache.DelConversations(v, conversationID) cache = cache.DelConversations(v, conversationID)
} }
return c.cache.ExecDel(ctx) return cache.ExecDel(ctx)
}) })
} }
+1 -1
View File
@@ -197,7 +197,7 @@ func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data ma
func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, deleteMember bool) error { func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, deleteMember bool) error {
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
c := g.cache.NewCache() c := g.cache.NewCache()
if err := g.groupDB.UpdateState(ctx, groupID, constant.GroupStatusDismissed); err != nil { if err := g.groupDB.UpdateStatus(ctx, groupID, constant.GroupStatusDismissed); err != nil {
return err return err
} }
if deleteMember { if deleteMember {
+13
View File
@@ -40,12 +40,16 @@ type UserDatabase interface {
Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error)
// Find userInfo By Nickname // Find userInfo By Nickname
FindByNickname(ctx context.Context, nickname string) (users []*relation.UserModel, err error) FindByNickname(ctx context.Context, nickname string) (users []*relation.UserModel, err error)
// Find notificationAccounts
FindNotification(ctx context.Context, level int64) (users []*relation.UserModel, err error)
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db // Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db
Create(ctx context.Context, users []*relation.UserModel) (err error) Create(ctx context.Context, users []*relation.UserModel) (err error)
// Update update (non-zero value) external guarantee userID exists // Update update (non-zero value) external guarantee userID exists
//Update(ctx context.Context, user *relation.UserModel) (err error) //Update(ctx context.Context, user *relation.UserModel) (err error)
// UpdateByMap update (zero value) external guarantee userID exists // UpdateByMap update (zero value) external guarantee userID exists
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
// FindUser
PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
// Page If not found, no error is returned // Page If not found, no error is returned
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
// IsExist true as long as one exists // IsExist true as long as one exists
@@ -140,6 +144,11 @@ func (u *userDatabase) FindByNickname(ctx context.Context, nickname string) (use
return u.userDB.TakeByNickname(ctx, nickname) return u.userDB.TakeByNickname(ctx, nickname)
} }
// Find notificationAccouts
func (u *userDatabase) FindNotification(ctx context.Context, level int64) (users []*relation.UserModel, err error) {
return u.userDB.TakeNotification(ctx, level)
}
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db. // Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db.
func (u *userDatabase) Create(ctx context.Context, users []*relation.UserModel) (err error) { func (u *userDatabase) Create(ctx context.Context, users []*relation.UserModel) (err error) {
return u.tx.Transaction(ctx, func(ctx context.Context) error { return u.tx.Transaction(ctx, func(ctx context.Context) error {
@@ -175,6 +184,10 @@ func (u *userDatabase) Page(ctx context.Context, pagination pagination.Paginatio
return u.userDB.Page(ctx, pagination) return u.userDB.Page(ctx, pagination)
} }
func (u *userDatabase) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
return u.userDB.PageFindUser(ctx, level, pagination)
}
// IsExist Does userIDs exist? As long as there is one, it will be true. // IsExist Does userIDs exist? As long as there is one, it will be true.
func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) { func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) {
users, err := u.userDB.Find(ctx, userIDs) users, err := u.userDB.Find(ctx, userIDs)
+2 -2
View File
@@ -49,8 +49,8 @@ func (g *GroupMgo) Create(ctx context.Context, groups []*relation.GroupModel) (e
return mgoutil.InsertMany(ctx, g.coll, groups) return mgoutil.InsertMany(ctx, g.coll, groups)
} }
func (g *GroupMgo) UpdateState(ctx context.Context, groupID string, state int32) (err error) { func (g *GroupMgo) UpdateStatus(ctx context.Context, groupID string, status int32) (err error) {
return g.UpdateMap(ctx, groupID, map[string]any{"state": state}) return g.UpdateMap(ctx, groupID, map[string]any{"status": status})
} }
func (g *GroupMgo) UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) { func (g *GroupMgo) UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) {
+7 -3
View File
@@ -51,7 +51,11 @@ func (g *GroupMemberMgo) Create(ctx context.Context, groupMembers []*relation.Gr
} }
func (g *GroupMemberMgo) Delete(ctx context.Context, groupID string, userIDs []string) (err error) { func (g *GroupMemberMgo) Delete(ctx context.Context, groupID string, userIDs []string) (err error) {
return mgoutil.DeleteMany(ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}}) filter := bson.M{"group_id": groupID}
if len(userIDs) > 0 {
filter["user_id"] = bson.M{"$in": userIDs}
}
return mgoutil.DeleteMany(ctx, g.coll, filter)
} }
func (g *GroupMemberMgo) UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) error { func (g *GroupMemberMgo) UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) error {
@@ -84,8 +88,8 @@ func (g *GroupMemberMgo) FindRoleLevelUserIDs(ctx context.Context, groupID strin
} }
func (g *GroupMemberMgo) SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*relation.GroupMemberModel, err error) { func (g *GroupMemberMgo) SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*relation.GroupMemberModel, err error) {
//TODO implement me filter := bson.M{"group_id": groupID, "nickname": bson.M{"$regex": keyword}}
panic("implement me") return mgoutil.FindPage[*relation.GroupMemberModel](ctx, g.coll, filter, pagination)
} }
func (g *GroupMemberMgo) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { func (g *GroupMemberMgo) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) {
+8
View File
@@ -65,6 +65,10 @@ func (u *UserMgo) Take(ctx context.Context, userID string) (user *relation.UserM
return mgoutil.FindOne[*relation.UserModel](ctx, u.coll, bson.M{"user_id": userID}) return mgoutil.FindOne[*relation.UserModel](ctx, u.coll, bson.M{"user_id": userID})
} }
func (u *UserMgo) TakeNotification(ctx context.Context, level int64) (user []*relation.UserModel, err error) {
return mgoutil.Find[*relation.UserModel](ctx, u.coll, bson.M{"app_manger_level": level})
}
func (u *UserMgo) TakeByNickname(ctx context.Context, nickname string) (user []*relation.UserModel, err error) { func (u *UserMgo) TakeByNickname(ctx context.Context, nickname string) (user []*relation.UserModel, err error) {
return mgoutil.Find[*relation.UserModel](ctx, u.coll, bson.M{"nickname": nickname}) return mgoutil.Find[*relation.UserModel](ctx, u.coll, bson.M{"nickname": nickname})
} }
@@ -73,6 +77,10 @@ func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (c
return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination) return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination)
} }
func (u *UserMgo) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{"app_manger_level": level}, pagination)
}
func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) { func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) {
return mgoutil.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"user_id": 1})) return mgoutil.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"user_id": 1}))
} }
+1 -1
View File
@@ -42,7 +42,7 @@ type GroupModel struct {
type GroupModelInterface interface { type GroupModelInterface interface {
Create(ctx context.Context, groups []*GroupModel) (err error) Create(ctx context.Context, groups []*GroupModel) (err error)
UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error)
UpdateState(ctx context.Context, groupID string, state int32) (err error) UpdateStatus(ctx context.Context, groupID string, status int32) (err error)
Find(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error) Find(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error)
Take(ctx context.Context, groupID string) (group *GroupModel, err error) Take(ctx context.Context, groupID string) (group *GroupModel, err error)
Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*GroupModel, err error) Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*GroupModel, err error)
+2
View File
@@ -53,8 +53,10 @@ type UserModelInterface interface {
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
Find(ctx context.Context, userIDs []string) (users []*UserModel, err error) Find(ctx context.Context, userIDs []string) (users []*UserModel, err error)
Take(ctx context.Context, userID string) (user *UserModel, err error) Take(ctx context.Context, userID string) (user *UserModel, err error)
TakeNotification(ctx context.Context, level int64) (user []*UserModel, err error)
TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error) TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error)
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
Exist(ctx context.Context, userID string) (exist bool, err error) Exist(ctx context.Context, userID string) (exist bool, err error)
GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error)
GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)
+4 -4
View File
@@ -78,8 +78,8 @@ func buildMongoURI() string {
return config.Config.Mongo.Uri return config.Config.Mongo.Uri
} }
username := os.Getenv("MONGO_USERNAME") username := os.Getenv("MONGO_OPENIM_USERNAME")
password := os.Getenv("MONGO_PASSWORD") password := os.Getenv("MONGO_OPENIM_PASSWORD")
address := os.Getenv("MONGO_ADDRESS") address := os.Getenv("MONGO_ADDRESS")
port := os.Getenv("MONGO_PORT") port := os.Getenv("MONGO_PORT")
database := os.Getenv("MONGO_DATABASE") database := os.Getenv("MONGO_DATABASE")
@@ -103,9 +103,9 @@ func buildMongoURI() string {
maxPoolSize = fmt.Sprint(config.Config.Mongo.MaxPoolSize) maxPoolSize = fmt.Sprint(config.Config.Mongo.MaxPoolSize)
} }
uriFormat := "mongodb://%s/%s?maxPoolSize=%s&authSource=admin" uriFormat := "mongodb://%s/%s?maxPoolSize=%s"
if username != "" && password != "" { if username != "" && password != "" {
uriFormat = "mongodb://%s:%s@%s/%s?maxPoolSize=%s&authSource=admin" uriFormat = "mongodb://%s:%s@%s/%s?maxPoolSize=%s"
return fmt.Sprintf(uriFormat, username, password, address, database, maxPoolSize) return fmt.Sprintf(uriFormat, username, password, address, database, maxPoolSize)
} }
return fmt.Sprintf(uriFormat, address, database, maxPoolSize) return fmt.Sprintf(uriFormat, address, database, maxPoolSize)
+3
View File
@@ -64,6 +64,9 @@ func NewUserRpcClient(client discoveryregistry.SvcDiscoveryRegistry) UserRpcClie
// GetUsersInfo retrieves information for multiple users based on their user IDs. // GetUsersInfo retrieves information for multiple users based on their user IDs.
func (u *UserRpcClient) GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error) { func (u *UserRpcClient) GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error) {
if len(userIDs) == 0 {
return []*sdkws.UserInfo{}, nil
}
resp, err := u.Client.GetDesignateUsers(ctx, &user.GetDesignateUsersReq{ resp, err := u.Client.GetDesignateUsers(ctx, &user.GetDesignateUsersReq{
UserIDs: userIDs, UserIDs: userIDs,
}) })
+1 -1
View File
@@ -36,4 +36,4 @@ sleep 5
"${OPENIM_ROOT}"/scripts/check-all.sh "${OPENIM_ROOT}"/scripts/check-all.sh
tail -f ${LOG_FILE} tail -f ${LOG_FILE}
+13 -3
View File
@@ -43,10 +43,20 @@ fi
"${OPENIM_ROOT}"/scripts/init-config.sh "${OPENIM_ROOT}"/scripts/init-config.sh
pushd "${OPENIM_ROOT}" pushd "${OPENIM_ROOT}"
${DOCKER_COMPOSE_COMMAND} stop ${DOCKER_COMPOSE_COMMAND} stop
curl https://gitee.com/openimsdk/openim-docker/raw/main/example/full-openim-server-and-chat.yml -o docker-compose.yml curl https://raw.githubusercontent.com/openimsdk/openim-docker/main/docker-compose.yaml -o docker-compose.yml
${DOCKER_COMPOSE_COMMAND} up -d ${DOCKER_COMPOSE_COMMAND} up -d
sleep 60
# Wait for a short period to allow containers to initialize
sleep 30
# Check the status of the containers
if ! ${DOCKER_COMPOSE_COMMAND} ps | grep -q 'Up'; then
echo "Error: One or more docker containers failed to start."
${DOCKER_COMPOSE_COMMAND} logs
fi
sleep 30 # Keep the original 60-second wait, adjusted for the 10-second check above
${DOCKER_COMPOSE_COMMAND} logs openim-server ${DOCKER_COMPOSE_COMMAND} logs openim-server
${DOCKER_COMPOSE_COMMAND} ps ${DOCKER_COMPOSE_COMMAND} ps
popd popd
+2 -2
View File
@@ -35,8 +35,8 @@ docker run -d \
-e MONGO_INITDB_ROOT_USERNAME=${OPENIM_USER} \ -e MONGO_INITDB_ROOT_USERNAME=${OPENIM_USER} \
-e MONGO_INITDB_ROOT_PASSWORD=${PASSWORD} \ -e MONGO_INITDB_ROOT_PASSWORD=${PASSWORD} \
-e MONGO_INITDB_DATABASE=openIM \ -e MONGO_INITDB_DATABASE=openIM \
-e MONGO_USERNAME=${OPENIM_USER} \ -e MONGO_OPENIM_USERNAME=${OPENIM_USER} \
-e MONGO_PASSWORD=${PASSWORD} \ -e MONGO_OPENIM_PASSWORD=${PASSWORD} \
--restart always \ --restart always \
mongo:6.0.2 --wiredTigerCacheSizeGB 1 --auth mongo:6.0.2 --wiredTigerCacheSizeGB 1 --auth
+7 -2
View File
@@ -171,9 +171,14 @@ def "MONGO_URI" # MongoDB的URI
def "MONGO_PORT" "37017" # MongoDB的端口 def "MONGO_PORT" "37017" # MongoDB的端口
def "MONGO_ADDRESS" "${DOCKER_BRIDGE_GATEWAY}" # MongoDB的地址 def "MONGO_ADDRESS" "${DOCKER_BRIDGE_GATEWAY}" # MongoDB的地址
def "MONGO_DATABASE" "${DATABASE_NAME}" # MongoDB的数据库名 def "MONGO_DATABASE" "${DATABASE_NAME}" # MongoDB的数据库名
def "MONGO_USERNAME" "${OPENIM_USER}" # MongoDB的用户名 def "MONGO_USERNAME" "root" # MongoDB的管理员身份用户名
# MongoDB的密码 # MongoDB的管理员身份密码
readonly MONGO_PASSWORD=${MONGO_PASSWORD:-"${PASSWORD}"} readonly MONGO_PASSWORD=${MONGO_PASSWORD:-"${PASSWORD}"}
# Mongo OpenIM 身份用户名
def "MONGO_OPENIM_USERNAME" "openIM"
# Mongo OpenIM 身份密码
readonly MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD:-'openIM123456'}
def "MONGO_MAX_POOL_SIZE" "100" # 最大连接池大小 def "MONGO_MAX_POOL_SIZE" "100" # 最大连接池大小
###################### Object 配置信息 ###################### ###################### Object 配置信息 ######################
+12 -6
View File
@@ -12,15 +12,21 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
mongo -- "$MONGO_INITDB_DATABASE" <<EOF set -e
db = db.getSiblingDB('admin')
mongosh <<EOF
use admin
db.auth('$MONGO_INITDB_ROOT_USERNAME', '$MONGO_INITDB_ROOT_PASSWORD') db.auth('$MONGO_INITDB_ROOT_USERNAME', '$MONGO_INITDB_ROOT_PASSWORD')
db = db.getSiblingDB('$MONGO_INITDB_DATABASE') db = db.getSiblingDB('$MONGO_INITDB_DATABASE')
db.createUser({ db.createUser({
user: "$MONGO_USERNAME", user: "$MONGO_OPENIM_USERNAME",
pwd: "$MONGO_PASSWORD", pwd: "$MONGO_OPENIM_PASSWORD",
roles: [ roles: [
{ role: 'root', db: '$MONGO_INITDB_DATABASE' } // Assign appropriate roles here
{ role: 'readWrite', db: '$MONGO_INITDB_DATABASE' }
] ]
}) });
EOF EOF
+5 -6
View File
@@ -25,10 +25,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/minio/minio-go/v7"
"github.com/redis/go-redis/v9"
"gopkg.in/yaml.v3"
"github.com/IBM/sarama" "github.com/IBM/sarama"
"github.com/OpenIMSDK/tools/errs" "github.com/OpenIMSDK/tools/errs"
"github.com/go-zookeeper/zk" "github.com/go-zookeeper/zk"
@@ -38,6 +34,9 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/minio/minio-go/v7/pkg/credentials" "github.com/minio/minio-go/v7/pkg/credentials"
"github.com/minio/minio-go/v7"
"github.com/redis/go-redis/v9"
"gopkg.in/yaml.v3"
) )
const ( const (
@@ -172,10 +171,10 @@ func buildMongoURI() string {
mongodbHosts := strings.Join(config.Config.Mongo.Address, ",") mongodbHosts := strings.Join(config.Config.Mongo.Address, ",")
if username != "" && password != "" { if username != "" && password != "" {
return fmt.Sprintf("mongodb://%s:%s@%s/%s?maxPoolSize=%d&authSource=admin", return fmt.Sprintf("mongodb://%s:%s@%s/%s?maxPoolSize=%d",
username, password, mongodbHosts, database, maxPoolSize) username, password, mongodbHosts, database, maxPoolSize)
} }
return fmt.Sprintf("mongodb://%s/%s?maxPoolSize=%d&authSource=admin", return fmt.Sprintf("mongodb://%s/%s?maxPoolSize=%d",
mongodbHosts, database, maxPoolSize) mongodbHosts, database, maxPoolSize)
} }