From f3939793ab51b6f44a4e81d409fa9c5e92830181 Mon Sep 17 00:00:00 2001 From: Xinwei Xiong <3293172751@qq.com> Date: Sat, 9 Sep 2023 11:06:50 +0800 Subject: [PATCH 1/4] fix: openim logs release v3.3 (#1048) --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 126409d3d..0fa2d0093 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -180,7 +180,7 @@ services: # retries: 5 # volumes: # - ./logs:/openim/openim-server/logs -# - ./_output:/openim/openim-server/_output +# - ./_output/logs:/openim/openim-server/_output/logs # - ./config:/openim/openim-server/config # - ./scripts:/openim/openim-server/scripts # restart: always From 72e5c4a0bfbd783251444a9ff47841430d2c4737 Mon Sep 17 00:00:00 2001 From: Xinwei Xiong <3293172751@qq.com> Date: Sat, 9 Sep 2023 14:26:24 +0800 Subject: [PATCH 2/4] fix: set openim volume (#1051) * fix: fix openim web port Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: fix openim web port Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: set openim volume --------- Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> --- .github/workflows/build-openim-web-image.yml | 4 +- CHANGELOG/CHANGELOG.md | 11 +- Dockerfile | 4 +- docker-compose.yml | 143 ++++++------------- scripts/install/openim-push.sh | 2 +- 5 files changed, 53 insertions(+), 111 deletions(-) diff --git a/.github/workflows/build-openim-web-image.yml b/.github/workflows/build-openim-web-image.yml index 471d7688e..6e8e7d823 100644 --- a/.github/workflows/build-openim-web-image.yml +++ b/.github/workflows/build-openim-web-image.yml @@ -84,7 +84,7 @@ jobs: id: meta2 uses: docker/metadata-action@v4.6.0 with: - images: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server + images: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-web - name: Log in to AliYun Docker Hub uses: docker/login-action@v2 @@ -117,7 +117,7 @@ jobs: id: meta3 uses: docker/metadata-action@v4.6.0 with: - images: ghcr.io/openimsdk/openim-server + images: ghcr.io/openimsdk/openim-web - name: Log in to GitHub Container Registry uses: docker/login-action@v2 diff --git a/CHANGELOG/CHANGELOG.md b/CHANGELOG/CHANGELOG.md index 41df11bba..2358b5fb8 100644 --- a/CHANGELOG/CHANGELOG.md +++ b/CHANGELOG/CHANGELOG.md @@ -89,9 +89,9 @@ $ git-chglog --config custom/dir/config.yml ## create next tag ```bash -git-chglog --next-tag 2.0.0 -o CHANGELOG.md -git commit -am "release 2.0.0" -git tag 2.0.0 +$ git-chglog --next-tag 2.0.0 -o CHANGELOG.md +$ git commit -am "release 2.0.0" +$ git tag 2.0.0 ``` | Query | Description | Example | @@ -112,6 +112,9 @@ git tag 2.0.0 + [OpenIM CHANGELOG-V2.9](CHANGELOG-2.9.md) + [OpenIM CHANGELOG-V3.0](CHANGELOG-3.0.md) + [OpenIM CHANGELOG-V3.1](CHANGELOG-3.1.md) ++ [OpenIM CHANGELOG-V3.2](CHANGELOG-3.2.md) ++ [OpenIM CHANGELOG-V3.3](CHANGELOG-3.3.md) + ## Introduction @@ -121,7 +124,7 @@ In both the open-source and closed-source software development communities, it i The most common format for version numbers is as follows: -``` +```bash major.minor[.patch[.build]] ``` diff --git a/Dockerfile b/Dockerfile index 5bd3930e0..f738d4457 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,7 @@ WORKDIR ${SERVER_WORKDIR} # Copy scripts and binary files to the production image COPY --from=builder ${OPENIM_SERVER_BINDIR} /openim/openim-server/_output/bin -COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts -COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config +# COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts +# COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config CMD ["/openim/openim-server/scripts/docker-start-all.sh"] diff --git a/docker-compose.yml b/docker-compose.yml index 0fa2d0093..543d5558f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -#fixme Clone openIM Server project before using docker-compose,project address:https://github.com/openimsdk/open-im-server.git +#fixme Clone openIM Server project before using docker-compose,project address:https://github.com/OpenIMSDK/Open-IM-Server.git version: '3' networks: @@ -10,29 +10,6 @@ networks: - subnet: '${DOCKER_BRIDGE_SUBNET}' gateway: '${DOCKER_BRIDGE_GATEWAY}' -volumes: - mysql_data: - mongodb_data: - mongodb_logs: - mongodb_config: - redis_data: - redis_config: - kafka_data: - minio_data: - minio_config: - openim_server_logs: - openim_server_output: - openim_server_config: - openim_server_scripts: - openim_chat_logs: - openim_chat_output: - openim_chat_config: - openim_chat_scripts: - openim_server_prometheus_config: - openim_server_grafana_datasource: - openim_server_grafana_config: - openim_server_grafana_dashboard: - services: mysql: image: mysql:5.7 @@ -40,7 +17,7 @@ services: - "${MYSQL_PORT}:3306" container_name: mysql volumes: - - mysql_data:/var/lib/mysql + - "${DATA_DIR}/components/mysql/data:/var/lib/mysql" - "/etc/localtime:/etc/localtime" environment: MYSQL_ROOT_PASSWORD: "${MYSQL_PASSWORD}" @@ -56,10 +33,10 @@ services: container_name: mongo command: --wiredTigerCacheSizeGB 1 --auth volumes: - - mongodb_data:/data/db - - mongodb_logs:/data/logs - - mongodb_config:/etc/mongo - - "./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro" + - "${DATA_DIR}/components/mongodb/data/db:/data/db" + - "${DATA_DIR}/components/mongodb/data/logs:/data/logs" + - "${DATA_DIR}/components/mongodb/data/conf:/etc/mongo" + - ./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro" environment: - TZ=Asia/Shanghai - wiredTigerCacheSizeGB=1 @@ -77,8 +54,8 @@ services: ports: - "${REDIS_PORT}:6379" volumes: - - redis_data:/data - - redis_config:/usr/local/redis/config/redis.conf + - "${DATA_DIR}/components/redis/data:/data" + - "${DATA_DIR}/components/redis/config/redis.conf:/usr/local/redis/config/redis.conf" environment: TZ: Asia/Shanghai restart: always @@ -118,8 +95,6 @@ services: bash -c " /opt/bitnami/scripts/kafka/run.sh & sleep 5; /opt/bitnami/kafka/create_topic.sh; wait " - extra_hosts: - - "host.docker.internal:host-gateway" environment: - TZ=Asia/Shanghai - KAFKA_CFG_NODE_ID=0 @@ -140,8 +115,8 @@ services: - "9090:9090" container_name: minio volumes: - - minio_data:/data - - minio_config:/root/.minio + - "${DATA_DIR}/components/mnt/data:/data" + - "${DATA_DIR}/components/mnt/config:/root/.minio" environment: MINIO_ROOT_USER: "${MINIO_ACCESS_KEY}" MINIO_ROOT_PASSWORD: "${MINIO_SECRET_KEY}" @@ -153,6 +128,8 @@ services: openim-web: image: ghcr.io/openimsdk/openim-web:latest + # image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-web:latest + # image: openim/openim-web:latest container_name: openim-web environment: - OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH} @@ -165,8 +142,8 @@ services: ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS} # openim-server: -# # image: ghcr.io/openimsdk/openim-server:main -# image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server:main +# image: ghcr.io/openimsdk/openim-server:main +# # image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server:main # # image: openim/openim-server:main # # build: . # container_name: openim-server @@ -199,69 +176,31 @@ services: # server: # ipv4_address: ${OPENIM_SERVER_NETWORK_ADDRESS} - # openim-chat: - # # image: ghcr.io/openimsdk/openim-chat:main - # image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-chat:main - # # image: ghcr.io/openimsdk/openim-chat:main - # container_name: openim-chat - # healthcheck: - # test: ["CMD", "/openim/openim-chat/scripts/check_all.sh"] - # interval: 300s - # timeout: 10s - # retries: 5 - # ports: - # - ${OPENIM_CHAT_API_PORT}:10008 - # - ${OPENIM_ADMIN_API_PORT}:10009 - # volumes: - # - openim_chat_logs:/openim/openim-chat/logs - # - openim_chat_output:/openim/openim-chat/_output - # - openim_chat_config:/openim/openim-chat/config - # - openim_chat_scripts:/openim/openim-chat/scripts - # restart: always - # user: root:root - # depends_on: - # - mysql - # - mongodb - # - redis - # - minio - # - server - # logging: - # driver: json-file - # options: - # max-size: "1g" - # max-file: "2" - # networks: - # server: - # ipv4_address: ${OPENIM_CHAT_NETWORK_ADDRESS} - - # prometheus: - # image: prom/prometheus - # volumes: - # - openim_server_prometheus_config:/etc/prometheus - # container_name: prometheus - # ports: - # - ${PROMETHEUS_PORT}:9091 - # command: --web.listen-address=:9091 --config.file="/etc/prometheus" - # networks: - # server: - # ipv4_address: ${PROMETHEUS_NETWORK_ADDRESS} - - # grafana: - # image: grafana/grafana - # volumes: - # - openim_server_grafana_datasource:/etc/grafana/provisioning/datasources - # - openim_server_grafana_config:/etc/grafana - # - openim_server_grafana_dashboard:/var/lib/grafana/dashboards - # container_name: grafana - # ports: - # - ${GRAFANA_PORT}:3000 - # networks: - # server: - # ipv4_address: ${GRAFANA_NETWORK_ADDRESS} +# prometheus: +# image: prom/prometheus +# volumes: +# - ./.docker-compose_cfg/prometheus-compose.yml:/etc/prometheus/prometheus.yml +# container_name: prometheus +# ports: +# - ${PROMETHEUS_PORT}:9091 +# depends_on: +# - openim-server +# command: --web.listen-address=:9091 --config.file="/etc/prometheus/prometheus.yml" +# networks: +# openim-server: +# ipv4_address: ${PROMETHEUS_NETWORK_ADDRESS} - # node-exporter: - # image: quay.io/prometheus/node-exporter - # container_name: node-exporter - # restart: always - # ports: - # - "9100:9100" +# grafana: +# image: grafana/grafana +# volumes: +# - ./.docker-compose_cfg/datasource-compose.yaml:/etc/grafana/provisioning/datasources/datasource.yaml +# - ./.docker-compose_cfg/grafana.ini:/etc/grafana/grafana.ini +# - ./.docker-compose_cfg/node-exporter-full_rev1.json:/var/lib/grafana/dashboards/node-exporter-full_rev1.json +# container_name: grafana +# ports: +# - ${GRAFANA_PORT}:3000 +# depends_on: +# - prometheus +# networks: +# openim-server: +# ipv4_address: ${GRAFANA_NETWORK_ADDRESS} \ No newline at end of file diff --git a/scripts/install/openim-push.sh b/scripts/install/openim-push.sh index e57edfaf6..aa5ebe7d4 100755 --- a/scripts/install/openim-push.sh +++ b/scripts/install/openim-push.sh @@ -71,7 +71,7 @@ function openim::push::start() for (( i=0; i<${#OPENIM_PUSH_PORTS_ARRAY[@]}; i++ )); do openim::log::info "start push process, port: ${OPENIM_PUSH_PORTS_ARRAY[$i]}, prometheus port: ${PUSH_PROM_PORTS_ARRAY[$i]}" - nohup ${OPENIM_PUSH_BINARY} --port ${OPENIM_PUSH_PORTS_ARRAY[$i]} --prometheus_port ${PUSH_PROM_PORTS_ARRAY[$i]} >> ${LOG_FILE} 2>&1 & + nohup ${OPENIM_PUSH_BINARY} --port ${OPENIM_PUSH_PORTS_ARRAY[$i]} -c ${OPENIM_PUSH_CONFIG} --prometheus_port ${PUSH_PROM_PORTS_ARRAY[$i]} >> ${LOG_FILE} 2>&1 & done openim::util::check_process_names ${SERVER_NAME} From 2628874a2668bdac411de467646ca4aec6663dca Mon Sep 17 00:00:00 2001 From: Xinwei Xiong <3293172751@qq.com> Date: Sat, 9 Sep 2023 15:57:46 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=8E=AF=20Optimize=20the=20deployment?= =?UTF-8?q?=20scheme=20to=20provide=20kubernetes=20deployment=20strategy?= =?UTF-8?q?=20(#1050)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: fix openim web port Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: fix openim web port Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: github gh images Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: github gh images Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: go mod package Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> --------- Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> --- .env | 2 +- README.md | 73 +++++++--------------------------------------- config/config.yaml | 4 +-- scripts/demo.sh | 23 +++++++++++++-- 4 files changed, 34 insertions(+), 68 deletions(-) diff --git a/.env b/.env index b2252cc9c..2f2766ef6 100644 --- a/.env +++ b/.env @@ -30,7 +30,7 @@ MINIO_ENDPOINT=http://172.28.0.1:10005 # Base URL for the application programming interface (API). # Default: API_URL=http://172.28.0.1:10002 -API_URL=http://172.28.0.1:10002 +API_URL=http://127.0.0.1:10002 # Directory path for storing data files or related information. # Default: DATA_DIR=./ diff --git a/README.md b/README.md index 504dcd012..d1af632bf 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ +Go Reference

@@ -81,7 +82,7 @@ Further enhancing your experience, we also provide an SDK client, wherein most c 5. **Open Source :open_hands:** - ✅ The code of OpenIM is open source, self-controlled data, aimed at building a globally leading IM open source community, including client SDK and server + ✅ The code of OpenIM is open source, self-controlled data, aimed at building a globally leading [IM open source community](https://github.com/OpenIMSDK), including [client SDK](https://github.com/openimsdk/openim-sdk-core) and server ✅ Based on open source Server, many excellent open source projects have been developed, such as [OpenKF](https://github.com/OpenIMSDK/OpenKF) (Open source AI customer service system) @@ -111,7 +112,7 @@ Further enhancing your experience, we also provide an SDK client, wherein most c ## :rocket: Quick Start -You can quickly learn OpenIM engineering solutions, all it takes is one simple command: +You can quickly learn OpenIM engineering solutions, all it takes is one simple command: ```bash $ make demo @@ -119,64 +120,18 @@ $ make demo 🤲 In order to facilitate the user experience, we have provided a variety of deployment solutions, you can choose your own deployment method according to the list below: -
Deploying with Docker Compose +
Deploying with Docker Compose +It is recommended to use Docker Compose for deployment, which can easily and quickly deploy the entire OpenIM service on a single node -> docker compose will not be maintained in future versions, but it is still the easiest and most convenient way to organize docker compose deployments into a separate project https://github.com/openim-sigs/openim-docker to maintain. ++ [https://github.com/openimsdk/openim-docker](https://github.com/openimsdk/openim-docker) -**1. Clone the project** - - -```bash -git clone -b main https://github.com/openim-sigs/openim-docker openim/openim-docker && export openim=$(pwd)/openim && cd $openim/openim-docker && ./scripts/init-config.sh && docker-compose up -d -``` > **Note** +> > If you don't know OpenIM's versioning policy, 📚Read our release policy: https://github.com/openimsdk/open-im-server/blob/main/docs/conversions/version.md -**2. Configure the config file** - -If you tried to get started quickly with `make demo`, then you know that our config file is generated by automation. - -You can use `make init` to quickly initialize a configuration file - -Modify the automation script: - -```bash -cat scripts/install/environment.sh -``` - -1. Recommended using environment variables: - -```bash -export PASSWORD="openIM123" # Set password -export USER="root" # Set username -# Choose chat version and server version https://github.com/openimsdk/open-im-server/blob/main/docs/conversions/images.md, eg: main, release-v*.* -export CHAT_BRANCH="main" -export SERVER_BRANCH="main" -#... Other environment variables -# MONGO_USERNAME: This sets the MongoDB username -# MONGO_PASSWORD: Set the MongoDB password -# MONGO_DATABASE: Sets the MongoDB database name -# MINIO_ENDPOINT: set the MinIO service address -# DOCKER_BRIDGE_SUBNET: set the docker bridge network address -export DOCKER_BRIDGE_SUBNET="172.28.0.0/16" -# API_URL: under network environment, set OpenIM Server API address -export API_URL="http://127.0.0.1:10002" -``` - -If you wish to use more custom features, read our [config documentation](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/environment.md). - - -Next, update the configuration using make init: - -```bash -$ make init -$ git diff -``` - -
Compile from Source @@ -211,16 +166,11 @@ Deploy basic components at the click of a command: ```bash # install openim dependency $ git clone https://github.com/openimsdk/open-im-server openim/openim-server && export openim=$(pwd)/openim/openim-server && cd $openim/openim-server && git checkout $OPENIM_VERSION -$ curl https://raw.githubusercontent.com/OpenIMSDK/openim-docker/main/example/basic-openim-server-dependency.yml -o basic-openim-server-dependency.yml && make init && docker compose -f basic-openim-server-dependency.yml up -d && make start +$ make init && docker compose -f basic-openim-server-dependency.yml up -d && make start && make check ``` > `make help` to help you see the instructions supported by OpenIM. -Use `make check` to check all component starts - -```bash -$ make check -``` You can use the `make help-all` see OpenIM in action. @@ -240,8 +190,9 @@ Read: https://github.com/openimsdk/open-im-server/blob/main/deployments/README.m
-
Open IM Ports +
Open IM and Chat Ports ++ oepnim-server warehouse: https://github.com/openimsdk/open-im-server | TCP Port | Description | Operation | | --------- | ------------------------------------------------------------ | ----------------------------------------------------- | @@ -249,10 +200,6 @@ Read: https://github.com/openimsdk/open-im-server/blob/main/deployments/README.m | TCP:10002 | api port, such as user, friend, group, message interfaces. | Port release or nginx reverse proxy, and firewall off | | TCP:10005 | Required when choosing minio storage (openIM uses minio storage by default) | Port release or nginx reverse proxy, and firewall off | -
- -
Open Chat Ports - + chat warehouse: https://github.com/OpenIMSDK/chat diff --git a/config/config.yaml b/config/config.yaml index c1059581b..9d6b3c335 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -132,14 +132,14 @@ api: # minio.signEndpoint is minio public network address object: enable: "minio" - apiURL: "http://172.28.0.1:10002" + apiURL: "http://http://127.0.0.1:10002" minio: bucket: "openim" endpoint: "http://172.28.0.1:10005" accessKeyID: "root" secretAccessKey: "openIM123" sessionToken: '' - signEndpoint: "http://172.28.0.1:10005" + signEndpoint: "http://127.0.0.1:10005" cos: bucketURL: https://temp-1252357374.cos.ap-chengdu.myqcloud.com secretID: '' diff --git a/scripts/demo.sh b/scripts/demo.sh index 51a8a7aa7..329e04f0f 100755 --- a/scripts/demo.sh +++ b/scripts/demo.sh @@ -13,6 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. +if ! command -v pv &> /dev/null +then + echo "pv not found, installing..." + if [ -e /etc/debian_version ]; then + sudo apt-get update + sudo apt-get install -y pv + elif [ -e /etc/redhat-release ]; then + sudo yum install -y pv + else + echo "Unsupported OS, please install pv manually." + exit 1 + fi +fi + readonly t_reset=$(tput sgr0) readonly green=$(tput bold; tput setaf 2) readonly yellow=$(tput bold; tput setaf 3) @@ -58,8 +72,11 @@ clear openim::util::desc "========> Start the basic openim docker components" openim::util::desc "========> You can use docker-compose ps to check the status of the container" -openim::util::run "curl https://raw.githubusercontent.com/OpenIMSDK/openim-docker/main/example/basic-openim-server-dependency.yml -o basic-openim-server-dependency.yml" -openim::util::run "docker compose up --f basic-openim-server-dependency.yml up -d" +openim::util::run "docker compose up -d" +clear + +openim::util::desc "========> Use make init-githooks Initialize git hooks " +openim::util::run "make init-githooks" clear openim::util::desc "The specification is pretty high, you need to be bound on your branch name, as well as commit messages" @@ -133,3 +150,5 @@ clear openim::util::desc "Add copyright" openim::util::run "make add-copyright" clear + +exit 0 From 3e1b147160d8bf210aa3cf9ad35929be681d3428 Mon Sep 17 00:00:00 2001 From: withchao <48119764+withchao@users.noreply.github.com> Date: Mon, 11 Sep 2023 20:03:07 +0800 Subject: [PATCH 4/4] feat: choose whether to push group messages offline based on the user's session option settings (#1054) * fix: repeated modification session notification * fix: repeated modification session notification * fix: jpush return a nil pointer panic * fix: push redis pkg * fix: OANotification * feat: add rpc GetConversationNeedOfflinePushUserIDs * update pkg * cicd: robot automated Change * offlinePushMsg * conversation * conversation * cicd: robot automated Change * conversation * cicd: robot automated Change * conversation --------- Co-authored-by: withchao --- go.mod | 2 +- go.sum | 4 +-- internal/api/conversation.go | 4 +++ internal/api/route.go | 1 + internal/push/push_to_client.go | 23 ++++++++++++----- internal/rpc/conversation/conversaion.go | 27 ++++++++++++++++++++ pkg/common/db/cache/conversation.go | 27 ++++++++++++++++++++ pkg/common/db/controller/conversation.go | 20 ++++++++++++--- pkg/common/db/relation/conversation_model.go | 23 +++++++++++++++++ pkg/common/db/table/relation/conversation.go | 1 + 10 files changed, 119 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 43251a4cf..7e3af7de2 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require github.com/google/uuid v1.3.1 require ( github.com/IBM/sarama v1.41.1 - github.com/OpenIMSDK/protocol v0.0.18 + github.com/OpenIMSDK/protocol v0.0.21 github.com/OpenIMSDK/tools v0.0.14 github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/go-redis/redis v6.15.9+incompatible diff --git a/go.sum b/go.sum index e94b507ae..5b180156e 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,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/IBM/sarama v1.41.1 h1:B4/TdHce/8Ipza+qrLIeNJ9D1AOxZVp/3uDv6H/dp2M= github.com/IBM/sarama v1.41.1/go.mod h1:JFCPURVskaipJdKRFkiE/OZqQHw7jqliaJmRwXCmSSw= -github.com/OpenIMSDK/protocol v0.0.18 h1:hXukFiDMLZx7s+hDCQePIK9ABiHyNlobNL4MppvOuMY= -github.com/OpenIMSDK/protocol v0.0.18/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= +github.com/OpenIMSDK/protocol v0.0.21 h1:5H6H+hJ9d/VgRqttvxD/zfK9Asd+4M8Eknk5swSbUVY= +github.com/OpenIMSDK/protocol v0.0.21/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= github.com/OpenIMSDK/tools v0.0.14 h1:WLof/+WxyPyRST+QkoTKubYCiV73uCLiL8pgnpH/yKQ= github.com/OpenIMSDK/tools v0.0.14/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= diff --git a/internal/api/conversation.go b/internal/api/conversation.go index 4e068b775..e422de677 100644 --- a/internal/api/conversation.go +++ b/internal/api/conversation.go @@ -44,3 +44,7 @@ func (o *ConversationApi) GetConversations(c *gin.Context) { func (o *ConversationApi) SetConversations(c *gin.Context) { a2r.Call(conversation.ConversationClient.SetConversations, o.Client, c) } + +func (o *ConversationApi) GetConversationOfflinePushUserIDs(c *gin.Context) { + a2r.Call(conversation.ConversationClient.GetConversationOfflinePushUserIDs, o.Client, c) +} diff --git a/internal/api/route.go b/internal/api/route.go index e1722523b..221e180a1 100644 --- a/internal/api/route.go +++ b/internal/api/route.go @@ -198,6 +198,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive conversationGroup.POST("/get_conversation", c.GetConversation) conversationGroup.POST("/get_conversations", c.GetConversations) conversationGroup.POST("/set_conversations", c.SetConversations) + conversationGroup.POST("/get_conversation_offline_push_user_ids", c.GetConversationOfflinePushUserIDs) } statisticsGroup := r.Group("/statistics", ParseToken) diff --git a/internal/push/push_to_client.go b/internal/push/push_to_client.go index edd03ce98..66b003eaa 100644 --- a/internal/push/push_to_client.go +++ b/internal/push/push_to_client.go @@ -19,6 +19,8 @@ import ( "encoding/json" "errors" + "github.com/OpenIMSDK/protocol/conversation" + "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/OpenIMSDK/protocol/constant" @@ -117,7 +119,6 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg if err != nil { return err } - break } } } @@ -234,15 +235,23 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws if len(offlinePushUserIDs) > 0 { needOfflinePushUserIDs = offlinePushUserIDs } - err = p.offlinePushMsg(ctx, groupID, msg, offlinePushUserIDs) + resp, err := p.conversationRpcClient.Client.GetConversationOfflinePushUserIDs( + ctx, + &conversation.GetConversationOfflinePushUserIDsReq{ConversationID: utils.GenGroupConversationID(groupID), UserIDs: needOfflinePushUserIDs}, + ) if err != nil { - log.ZError(ctx, "offlinePushMsg failed", err, "groupID", groupID, "msg", msg) return err } - _, err := p.GetConnsAndOnlinePush(ctx, msg, utils.IntersectString(needOfflinePushUserIDs, WebAndPcBackgroundUserIDs)) - if err != nil { - log.ZError(ctx, "offlinePushMsg failed", err, "groupID", groupID, "msg", msg, "userIDs", utils.IntersectString(needOfflinePushUserIDs, WebAndPcBackgroundUserIDs)) - return err + if len(resp.UserIDs) > 0 { + err = p.offlinePushMsg(ctx, groupID, msg, resp.UserIDs) + if err != nil { + log.ZError(ctx, "offlinePushMsg failed", err, "groupID", groupID, "msg", msg) + return err + } + if _, err := p.GetConnsAndOnlinePush(ctx, msg, utils.IntersectString(resp.UserIDs, WebAndPcBackgroundUserIDs)); err != nil { + log.ZError(ctx, "offlinePushMsg failed", err, "groupID", groupID, "msg", msg, "userIDs", utils.IntersectString(needOfflinePushUserIDs, WebAndPcBackgroundUserIDs)) + return err + } } } } diff --git a/internal/rpc/conversation/conversaion.go b/internal/rpc/conversation/conversaion.go index 9f97c3c67..4b5b43fe8 100644 --- a/internal/rpc/conversation/conversaion.go +++ b/internal/rpc/conversation/conversaion.go @@ -300,3 +300,30 @@ func (c *conversationServer) GetConversationsByConversationID( } return &pbconversation.GetConversationsByConversationIDResp{Conversations: convert.ConversationsDB2Pb(conversations)}, nil } + +func (c *conversationServer) GetConversationOfflinePushUserIDs( + ctx context.Context, + req *pbconversation.GetConversationOfflinePushUserIDsReq, +) (*pbconversation.GetConversationOfflinePushUserIDsResp, error) { + if req.ConversationID == "" { + return nil, errs.ErrArgs.Wrap("conversationID is empty") + } + if len(req.UserIDs) == 0 { + return &pbconversation.GetConversationOfflinePushUserIDsResp{}, nil + } + userIDs, err := c.conversationDatabase.GetConversationNotReceiveMessageUserIDs(ctx, req.ConversationID) + if err != nil { + return nil, err + } + if len(userIDs) == 0 { + return &pbconversation.GetConversationOfflinePushUserIDsResp{UserIDs: req.UserIDs}, nil + } + userIDSet := make(map[string]struct{}) + for _, userID := range req.UserIDs { + userIDSet[userID] = struct{}{} + } + for _, userID := range userIDs { + delete(userIDSet, userID) + } + return &pbconversation.GetConversationOfflinePushUserIDsResp{UserIDs: utils.Keys(userIDSet)}, nil +} diff --git a/pkg/common/db/cache/conversation.go b/pkg/common/db/cache/conversation.go index d02b021e3..083cf6d0b 100644 --- a/pkg/common/db/cache/conversation.go +++ b/pkg/common/db/cache/conversation.go @@ -38,6 +38,7 @@ const ( recvMsgOptKey = "RECV_MSG_OPT:" superGroupRecvMsgNotNotifyUserIDsKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS:" superGroupRecvMsgNotNotifyUserIDsHashKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS_HASH:" + conversationNotReceiveMessageUserIDsKey = "CONVERSATION_NOT_RECEIVE_MESSAGE_USER_IDS:" conversationExpireTime = time.Second * 60 * 60 * 12 ) @@ -83,6 +84,8 @@ type ConversationCache interface { conversationIDs []string, ) ([]*relationtb.ConversationModel, error) DelConversationByConversationID(conversationIDs ...string) ConversationCache + GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) + DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) ConversationCache } func NewConversationRedis( @@ -153,6 +156,10 @@ func (c *ConversationRedisCache) getConversationHasReadSeqKey(ownerUserID, conve return conversationHasReadSeqKey + ownerUserID + ":" + conversationID } +func (c *ConversationRedisCache) getConversationNotReceiveMessageUserIDsKey(conversationID string) string { + return conversationNotReceiveMessageUserIDsKey + conversationID +} + func (c *ConversationRedisCache) GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) { return getCache( ctx, @@ -432,3 +439,23 @@ func (c *ConversationRedisCache) GetConversationsByConversationID( func (c *ConversationRedisCache) DelConversationByConversationID(conversationIDs ...string) ConversationCache { panic("implement me") } + +func (c *ConversationRedisCache) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) { + return getCache( + ctx, + c.rcClient, + c.getConversationNotReceiveMessageUserIDsKey(conversationID), + c.expireTime, + func(ctx context.Context) ([]string, error) { + return c.conversationDB.GetConversationNotReceiveMessageUserIDs(ctx, conversationID) + }, + ) +} + +func (c *ConversationRedisCache) DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) ConversationCache { + cache := c.NewCache() + for _, conversationID := range conversationIDs { + cache.AddKeys(c.getConversationNotReceiveMessageUserIDsKey(conversationID)) + } + return cache +} diff --git a/pkg/common/db/controller/conversation.go b/pkg/common/db/controller/conversation.go index 806e09331..c3dd6980e 100644 --- a/pkg/common/db/controller/conversation.go +++ b/pkg/common/db/controller/conversation.go @@ -53,6 +53,7 @@ type ConversationDatabase interface { GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.ConversationModel, error) + GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) } func NewConversationDatabase(conversation relationtb.ConversationModelInterface, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase { @@ -88,6 +89,9 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, cache = cache.DelUserAllHasReadSeqs(userID, conversation.ConversationID) } } + if _, ok := filedMap["recv_msg_opt"]; ok { + cache = cache.DelConversationNotReceiveMessageUserIDs(conversation.ConversationID) + } } NotUserIDs := utils.DifferenceString(haveUserIDs, userIDs) log.ZDebug(ctx, "SetUsersConversationFiledTx", "NotUserIDs", NotUserIDs, "haveUserIDs", haveUserIDs, "userIDs", userIDs) @@ -121,7 +125,12 @@ func (c *conversationDatabase) UpdateUsersConversationFiled(ctx context.Context, if err != nil { return err } - return c.cache.DelUsersConversation(conversationID, userIDs...).ExecDel(ctx) + cache := c.cache.NewCache() + cache = cache.DelUsersConversation(conversationID, userIDs...) + if _, ok := args["recv_msg_opt"]; ok { + cache = cache.DelConversationNotReceiveMessageUserIDs(conversationID) + } + return cache.ExecDel(ctx) } func (c *conversationDatabase) CreateConversation(ctx context.Context, conversations []*relationtb.ConversationModel) error { @@ -132,6 +141,7 @@ func (c *conversationDatabase) CreateConversation(ctx context.Context, conversat cache := c.cache.NewCache() for _, conversation := range conversations { cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID) + cache = cache.DelConversationNotReceiveMessageUserIDs(conversation.ConversationID) userIDs = append(userIDs, conversation.OwnerUserID) } return cache.DelConversationIDs(userIDs...).DelUserConversationIDsHash(userIDs...).ExecDel(ctx) @@ -224,7 +234,7 @@ func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUs if err != nil { return err } - cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID) + cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID).DelConversationNotReceiveMessageUserIDs(utils.Slice(notExistConversations, func(e *relationtb.ConversationModel) string { return e.ConversationID })...) } return nil }); err != nil { @@ -250,7 +260,7 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context, for _, v := range notExistUserIDs { conversation := relationtb.ConversationModel{ConversationType: constant.SuperGroupChatType, GroupID: groupID, OwnerUserID: v, ConversationID: conversationID} conversations = append(conversations, &conversation) - cache = cache.DelConversations(v, conversationID) + cache = cache.DelConversations(v, conversationID).DelConversationNotReceiveMessageUserIDs(conversationID) } cache = cache.DelConversationIDs(notExistUserIDs...).DelUserConversationIDsHash(notExistUserIDs...) if len(conversations) > 0 { @@ -296,3 +306,7 @@ func (c *conversationDatabase) GetConversationsByConversationID(ctx context.Cont func (c *conversationDatabase) GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.ConversationModel, error) { return c.conversationDB.GetConversationIDsNeedDestruct(ctx) } + +func (c *conversationDatabase) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) { + return c.cache.GetConversationNotReceiveMessageUserIDs(ctx, conversationID) +} diff --git a/pkg/common/db/relation/conversation_model.go b/pkg/common/db/relation/conversation_model.go index dcc18be17..d5ca92ec2 100644 --- a/pkg/common/db/relation/conversation_model.go +++ b/pkg/common/db/relation/conversation_model.go @@ -17,6 +17,8 @@ package relation import ( "context" + "github.com/OpenIMSDK/tools/errs" + "gorm.io/gorm" "github.com/OpenIMSDK/protocol/constant" @@ -214,3 +216,24 @@ func (c *ConversationGorm) GetConversationIDsNeedDestruct( "", ) } + +func (c *ConversationGorm) GetConversationRecvMsgOpt(ctx context.Context, userID string, conversationID string) (int32, error) { + var recvMsgOpt int32 + return recvMsgOpt, errs.Wrap( + c.db(ctx). + Model(&relation.ConversationModel{}). + Where("conversation_id = ? and owner_user_id in ?", conversationID, userID). + Pluck("recv_msg_opt", &recvMsgOpt). + Error, + ) +} + +func (c *ConversationGorm) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) { + var userIDs []string + return userIDs, errs.Wrap( + c.db(ctx). + Model(&relation.ConversationModel{}). + Where("conversation_id = ? and recv_msg_opt <> ?", conversationID, constant.ReceiveMessage). + Pluck("owner_user_id", &userIDs).Error, + ) +} diff --git a/pkg/common/db/table/relation/conversation.go b/pkg/common/db/table/relation/conversation.go index 99c01e5b7..7e6c6bdf8 100644 --- a/pkg/common/db/table/relation/conversation.go +++ b/pkg/common/db/table/relation/conversation.go @@ -66,5 +66,6 @@ type ConversationModelInterface interface { GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (hashReadSeqs map[string]int64, err error) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*ConversationModel, error) GetConversationIDsNeedDestruct(ctx context.Context) ([]*ConversationModel, error) + GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) NewTx(tx any) ConversationModelInterface }