Compare commits
2 Commits
v3.4.2
...
sweep/asse
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23d36f2c89 | ||
|
|
9bc84f241d |
@@ -20,6 +20,7 @@ CHANGELOG/
|
||||
|
||||
# Ignore deployment-related files
|
||||
docker-compose.yaml
|
||||
deployments/
|
||||
|
||||
# Ignore assets
|
||||
assets/
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
# Copyright © 2023 OpenIM. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# ======================================
|
||||
# ========= Basic Configuration ========
|
||||
# ======================================
|
||||
|
||||
# The user for authentication or system operations.
|
||||
# Default: OPENIM_USER=root
|
||||
# Default: USER=root
|
||||
USER=root
|
||||
|
||||
# Password associated with the specified user for authentication.
|
||||
@@ -41,19 +55,57 @@ DOCKER_BRIDGE_SUBNET=172.28.0.0/16
|
||||
# Default: DOCKER_BRIDGE_GATEWAY=172.28.0.1
|
||||
DOCKER_BRIDGE_GATEWAY=172.28.0.1
|
||||
|
||||
MONGO_NETWORK_ADDRESS=172.28.0.2
|
||||
REDIS_NETWORK_ADDRESS=172.28.0.3
|
||||
KAFKA_NETWORK_ADDRESS=172.28.0.4
|
||||
ZOOKEEPER_NETWORK_ADDRESS=172.28.0.5
|
||||
MINIO_NETWORK_ADDRESS=172.28.0.6
|
||||
OPENIM_WEB_NETWORK_ADDRESS=172.28.0.7
|
||||
OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.8
|
||||
OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.9
|
||||
PROMETHEUS_NETWORK_ADDRESS=172.28.0.10
|
||||
GRAFANA_NETWORK_ADDRESS=172.28.0.11
|
||||
NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.12
|
||||
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=172.28.0.13
|
||||
ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.14
|
||||
# Address or hostname for the MySQL network.
|
||||
# Default: MYSQL_NETWORK_ADDRESS=172.28.0.2
|
||||
MYSQL_NETWORK_ADDRESS=172.28.0.2
|
||||
|
||||
# Address or hostname for the MongoDB network.
|
||||
# Default: MONGO_NETWORK_ADDRESS=172.28.0.3
|
||||
MONGO_NETWORK_ADDRESS=172.28.0.3
|
||||
|
||||
# Address or hostname for the Redis network.
|
||||
# Default: REDIS_NETWORK_ADDRESS=172.28.0.4
|
||||
REDIS_NETWORK_ADDRESS=172.28.0.4
|
||||
|
||||
# Address or hostname for the Kafka network.
|
||||
# Default: KAFKA_NETWORK_ADDRESS=172.28.0.5
|
||||
KAFKA_NETWORK_ADDRESS=172.28.0.5
|
||||
|
||||
# Address or hostname for the ZooKeeper network.
|
||||
# Default: ZOOKEEPER_NETWORK_ADDRESS=172.28.0.6
|
||||
ZOOKEEPER_NETWORK_ADDRESS=172.28.0.6
|
||||
|
||||
# Address or hostname for the MinIO network.
|
||||
# Default: MINIO_NETWORK_ADDRESS=172.28.0.7
|
||||
MINIO_NETWORK_ADDRESS=172.28.0.7
|
||||
|
||||
# Address or hostname for the OpenIM web network.
|
||||
# Default: OPENIM_WEB_NETWORK_ADDRESS=172.28.0.8
|
||||
OPENIM_WEB_NETWORK_ADDRESS=172.28.0.8
|
||||
|
||||
# Address or hostname for the OpenIM server network.
|
||||
# Default: OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.9
|
||||
OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.9
|
||||
|
||||
# Address or hostname for the OpenIM chat network.
|
||||
# Default: OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.10
|
||||
OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.10
|
||||
|
||||
# Address or hostname for the Prometheus network.
|
||||
# Default: PROMETHEUS_NETWORK_ADDRESS=172.28.0.11
|
||||
PROMETHEUS_NETWORK_ADDRESS=172.28.0.11
|
||||
|
||||
# Address or hostname for the Grafana network.
|
||||
# Default: GRAFANA_NETWORK_ADDRESS=172.28.0.12
|
||||
GRAFANA_NETWORK_ADDRESS=172.28.0.12
|
||||
|
||||
# Address or hostname for the node_exporter network.
|
||||
# Default: NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.13
|
||||
NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.13
|
||||
|
||||
# Address or hostname for the OpenIM admin network.
|
||||
# Default: OPENIM_ADMIN_NETWORK_ADDRESS=172.28.0.14
|
||||
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=172.28.0.14
|
||||
|
||||
# ===============================================
|
||||
# = Component Extension Configuration =
|
||||
@@ -63,24 +115,38 @@ ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.14
|
||||
# ----- ZooKeeper Configuration -----
|
||||
# Address or hostname for the ZooKeeper service.
|
||||
# Default: ZOOKEEPER_ADDRESS=172.28.0.1
|
||||
ZOOKEEPER_ADDRESS=172.28.0.5
|
||||
ZOOKEEPER_ADDRESS=172.28.0.6
|
||||
|
||||
# Port for ZooKeeper service.
|
||||
# Default: ZOOKEEPER_PORT=12181
|
||||
ZOOKEEPER_PORT=12181
|
||||
|
||||
# ----- MySQL Configuration -----
|
||||
|
||||
# Address or hostname for the MySQL service.
|
||||
# Default: MYSQL_ADDRESS=172.28.0.1
|
||||
MYSQL_ADDRESS=172.28.0.2
|
||||
|
||||
# Port on which MySQL database service is running.
|
||||
# Default: MYSQL_PORT=13306
|
||||
MYSQL_PORT=13306
|
||||
|
||||
# Password to authenticate with the MySQL database service.
|
||||
# Default: MYSQL_PASSWORD=openIM123
|
||||
MYSQL_PASSWORD=openIM123
|
||||
|
||||
# ----- MongoDB Configuration -----
|
||||
# Address or hostname for the MongoDB service.
|
||||
# Default: MONGO_ADDRESS=172.28.0.1
|
||||
MONGO_ADDRESS=172.28.0.2
|
||||
MONGO_ADDRESS=172.28.0.3
|
||||
|
||||
# Port on which MongoDB service is running.
|
||||
# Default: MONGO_PORT=37017
|
||||
# MONGO_PORT=37017
|
||||
MONGO_PORT=37017
|
||||
|
||||
# Username to authenticate with the MongoDB service.
|
||||
# Default: MONGO_USERNAME=root
|
||||
# MONGO_USERNAME=root
|
||||
MONGO_USERNAME=root
|
||||
|
||||
# Password to authenticate with the MongoDB service.
|
||||
# Default: MONGO_PASSWORD=openIM123
|
||||
@@ -93,7 +159,7 @@ MONGO_DATABASE=openIM_v3
|
||||
# ----- Redis Configuration -----
|
||||
# Address or hostname for the Redis service.
|
||||
# Default: REDIS_ADDRESS=172.28.0.1
|
||||
REDIS_ADDRESS=172.28.0.3
|
||||
REDIS_ADDRESS=172.28.0.4
|
||||
|
||||
# Port on which Redis in-memory data structure store is running.
|
||||
# Default: REDIS_PORT=16379
|
||||
@@ -106,10 +172,7 @@ REDIS_PASSWORD=openIM123
|
||||
# ----- Kafka Configuration -----
|
||||
# Address or hostname for the Kafka service.
|
||||
# Default: KAFKA_ADDRESS=172.28.0.1
|
||||
KAFKA_ADDRESS=172.28.0.4
|
||||
|
||||
# Kakfa username to authenticate with the Kafka service.
|
||||
# KAFKA_USERNAME=''
|
||||
KAFKA_ADDRESS=172.28.0.5
|
||||
|
||||
# Port on which Kafka distributed streaming platform is running.
|
||||
# Default: KAFKA_PORT=19092
|
||||
@@ -130,7 +193,7 @@ KAFKA_OFFLINEMSG_MONGO_TOPIC=offlineMsgToMongoMysql
|
||||
# ----- MinIO Configuration ----
|
||||
# Address or hostname for the MinIO object storage service.
|
||||
# Default: MINIO_ADDRESS=172.28.0.1
|
||||
MINIO_ADDRESS=172.28.0.6
|
||||
MINIO_ADDRESS=172.28.0.7
|
||||
|
||||
# Port on which MinIO object storage service is running.
|
||||
# Default: MINIO_PORT=10005
|
||||
@@ -138,7 +201,7 @@ MINIO_PORT=10005
|
||||
|
||||
# Access key to authenticate with the MinIO service.
|
||||
# Default: MINIO_ACCESS_KEY=root
|
||||
# MINIO_ACCESS_KEY=root
|
||||
MINIO_ACCESS_KEY=root
|
||||
|
||||
# Secret key corresponding to the access key for MinIO authentication.
|
||||
# Default: MINIO_SECRET_KEY=openIM123
|
||||
@@ -147,7 +210,7 @@ MINIO_SECRET_KEY=openIM123
|
||||
# ----- Prometheus Configuration -----
|
||||
# Address or hostname for the Prometheus service.
|
||||
# Default: PROMETHEUS_ADDRESS=172.28.0.1
|
||||
PROMETHEUS_ADDRESS=172.28.0.10
|
||||
PROMETHEUS_ADDRESS=172.28.0.11
|
||||
|
||||
# Port on which Prometheus service is running.
|
||||
# Default: PROMETHEUS_PORT=19090
|
||||
@@ -156,11 +219,11 @@ PROMETHEUS_PORT=19090
|
||||
# ----- Grafana Configuration -----
|
||||
# Address or hostname for the Grafana service.
|
||||
# Default: GRAFANA_ADDRESS=172.28.0.1
|
||||
GRAFANA_ADDRESS=172.28.0.11
|
||||
GRAFANA_ADDRESS=172.28.0.12
|
||||
|
||||
# Port on which Grafana service is running.
|
||||
# Default: GRAFANA_PORT=13000
|
||||
GRAFANA_PORT=13000
|
||||
# Default: GRAFANA_PORT=3000
|
||||
GRAFANA_PORT=3000
|
||||
|
||||
# ======================================
|
||||
# ============ OpenIM Web ===============
|
||||
@@ -176,7 +239,7 @@ OPENIM_WEB_PORT=11001
|
||||
|
||||
# Address or hostname for the OpenIM web service.
|
||||
# Default: OPENIM_WEB_ADDRESS=172.28.0.1
|
||||
OPENIM_WEB_ADDRESS=172.28.0.7
|
||||
OPENIM_WEB_ADDRESS=172.28.0.8
|
||||
|
||||
# ======================================
|
||||
# ========= OpenIM Server ==============
|
||||
@@ -184,7 +247,7 @@ OPENIM_WEB_ADDRESS=172.28.0.7
|
||||
|
||||
# Address or hostname for the OpenIM server.
|
||||
# Default: OPENIM_SERVER_ADDRESS=172.28.0.1
|
||||
OPENIM_SERVER_ADDRESS=172.28.0.8
|
||||
OPENIM_SERVER_ADDRESS=172.28.0.9
|
||||
|
||||
# Port for the OpenIM WebSockets.
|
||||
# Default: OPENIM_WS_PORT=10001
|
||||
@@ -205,7 +268,7 @@ CHAT_BRANCH=main
|
||||
|
||||
# Address or hostname for the OpenIM chat service.
|
||||
# Default: OPENIM_CHAT_ADDRESS=172.28.0.1
|
||||
OPENIM_CHAT_ADDRESS=172.28.0.9
|
||||
OPENIM_CHAT_ADDRESS=172.28.0.10
|
||||
|
||||
# Port for the OpenIM chat API.
|
||||
# Default: OPENIM_CHAT_API_PORT=10008
|
||||
@@ -237,13 +300,9 @@ NODE_EXPORTER_PORT=19100
|
||||
PROMETHEUS_PORT=19090
|
||||
|
||||
# Port for the grafana.
|
||||
# Default: GRAFANA_PORT=13000
|
||||
GRAFANA_PORT=13000
|
||||
# Default: GRAFANA_PORT=3000
|
||||
GRAFANA_PORT=3000
|
||||
|
||||
# Port for the admin front.
|
||||
# Default: OPENIM_ADMIN_FRONT_PORT=11002
|
||||
OPENIM_ADMIN_FRONT_PORT=11002
|
||||
|
||||
# Port for the alertmanager.
|
||||
# Default: ALERT_MANAGER_PORT=19093
|
||||
ALERT_MANAGER_PORT=19093
|
||||
139
.github/workflows/build-openim-web-image.yml
vendored
Normal file
139
.github/workflows/build-openim-web-image.yml
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
# Copyright © 2023 OpenIM open source community. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
name: Build OpenIM Web Docker image
|
||||
|
||||
on:
|
||||
# schedule:
|
||||
# - cron: '30 3 * * *'
|
||||
push:
|
||||
branches:
|
||||
# - main
|
||||
- release-*
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: "1.20"
|
||||
|
||||
jobs:
|
||||
build-openim-web-dockerhub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
# docker.io/openim/openim-web:latest
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5.0.0
|
||||
with:
|
||||
images: openim/openim-web
|
||||
# generate Docker tags based on the following events/attributes
|
||||
tags: |
|
||||
type=schedule
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=sha
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./build/images/openim-tools/openim-web/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
build-openim-web-aliyun:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
# registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-web:latest
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta2
|
||||
uses: docker/metadata-action@v5.0.0
|
||||
with:
|
||||
images: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-web
|
||||
|
||||
- name: Log in to AliYun Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: registry.cn-hangzhou.aliyuncs.com
|
||||
username: ${{ secrets.ALIREGISTRY_USERNAME }}
|
||||
password: ${{ secrets.ALIREGISTRY_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./build/images/openim-tools/openim-web/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta2.outputs.tags }}
|
||||
labels: ${{ steps.meta2.outputs.labels }}
|
||||
|
||||
build-openim-web-ghcr:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
# ghcr.io/openimsdk/openim-web:latest
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta2
|
||||
uses: docker/metadata-action@v5.0.0
|
||||
with:
|
||||
images: ghcr.io/openimsdk/openim-web
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./build/images/openim-tools/openim-web/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta2.outputs.tags }}
|
||||
labels: ${{ steps.meta2.outputs.labels }}
|
||||
7
.github/workflows/e2e-test.yml
vendored
7
.github/workflows/e2e-test.yml
vendored
@@ -22,9 +22,6 @@ on:
|
||||
# run e2e test every 4 hours
|
||||
- cron: 0 */4 * * *
|
||||
|
||||
env:
|
||||
CALLBACK_ENABLE: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Test
|
||||
@@ -73,9 +70,9 @@ jobs:
|
||||
|
||||
- name: Docker Operations
|
||||
run: |
|
||||
sudo make init
|
||||
curl -o docker-compose.yml https://raw.githubusercontent.com/OpenIMSDK/openim-docker/main/example/basic-openim-server-dependency.yml
|
||||
sudo docker compose up -d
|
||||
sudo sleep 20
|
||||
sudo sleep 60
|
||||
|
||||
- name: Module Operations
|
||||
run: |
|
||||
|
||||
3
.github/workflows/opencommit.yml
vendored
3
.github/workflows/opencommit.yml
vendored
@@ -51,5 +51,4 @@ jobs:
|
||||
OCO_EMOJI: false
|
||||
OCO_MODEL: gpt-3.5-turbo-16k
|
||||
OCO_LANGUAGE: en
|
||||
OCO_PROMPT_MODULE: conventional-commit
|
||||
continue-on-error: true
|
||||
OCO_PROMPT_MODULE: conventional-commit
|
||||
5
.github/workflows/openimci.yml
vendored
5
.github/workflows/openimci.yml
vendored
@@ -156,9 +156,9 @@ jobs:
|
||||
|
||||
- name: Docker Operations
|
||||
run: |
|
||||
sudo make init
|
||||
curl -o docker-compose.yml https://raw.githubusercontent.com/OpenIMSDK/openim-docker/main/example/basic-openim-server-dependency.yml
|
||||
sudo docker compose up -d
|
||||
sudo sleep 20
|
||||
sudo sleep 60
|
||||
|
||||
- name: Module Operations
|
||||
run: |
|
||||
@@ -195,5 +195,4 @@ jobs:
|
||||
|
||||
- name: Test Docker Build
|
||||
run: |
|
||||
sudo make init
|
||||
sudo make image
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -391,5 +391,3 @@ Sessionx.vim
|
||||
dist/
|
||||
.env
|
||||
config/config.yaml
|
||||
config/alertmanager.yml
|
||||
config/prometheus.yml
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.43.0 (0)
|
||||
-->
|
||||
<!-- Title: %3 Pages: 1 -->
|
||||
<svg width="447pt" height="165pt"
|
||||
viewBox="0.00 0.00 447.00 164.74" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(36 128.74)">
|
||||
<title>%3</title>
|
||||
<polygon fill="dimgray" stroke="transparent" points="-36,36 -36,-128.74 411,-128.74 411,36 -36,36"/>
|
||||
<text text-anchor="middle" x="187.5" y="-77.54" font-family="Helvetica,sans-Serif" font-size="14.00">Sweep's Plan & Progress</text>
|
||||
<!-- start -->
|
||||
<g id="node1" class="node">
|
||||
<title>start</title>
|
||||
</g>
|
||||
<!-- e9278104-5ca8-4ff3-9348-96db9869a52a -->
|
||||
<g id="node3" class="node">
|
||||
<title>e9278104-5ca8-4ff3-9348-96db9869a52a</title>
|
||||
<ellipse fill="#ee0000" stroke="black" cx="184.5" cy="-26.87" rx="132.46" ry="26.74"/>
|
||||
<text text-anchor="middle" x="184.5" y="-30.67" font-family="Helvetica,sans-Serif" font-size="14.00">✗ Modify</text>
|
||||
<text text-anchor="middle" x="184.5" y="-15.67" font-family="Helvetica,sans-Serif" font-size="14.00">internal/rpc/user/user.go</text>
|
||||
</g>
|
||||
<!-- start->e9278104-5ca8-4ff3-9348-96db9869a52a -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>start->e9278104-5ca8-4ff3-9348-96db9869a52a</title>
|
||||
<path fill="none" stroke="black" d="M1.03,-26.87C4.1,-26.87 20.28,-26.87 41.85,-26.87"/>
|
||||
<polygon fill="black" stroke="black" points="42.12,-30.37 52.12,-26.87 42.12,-23.37 42.12,-30.37"/>
|
||||
<text text-anchor="middle" x="26.64" y="-33.67" font-family="Helvetica,sans-Serif" font-size="14.00">Start</text>
|
||||
</g>
|
||||
<!-- end -->
|
||||
<g id="node2" class="node">
|
||||
<title>end</title>
|
||||
</g>
|
||||
<!-- e9278104-5ca8-4ff3-9348-96db9869a52a->end -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>e9278104-5ca8-4ff3-9348-96db9869a52a->end</title>
|
||||
<path fill="none" stroke="black" d="M316.98,-26.87C336.34,-26.87 353.23,-26.87 363.61,-26.87"/>
|
||||
<polygon fill="black" stroke="black" points="363.85,-30.37 373.85,-26.87 363.85,-23.37 363.85,-30.37"/>
|
||||
<text text-anchor="middle" x="345.36" y="-33.67" font-family="Helvetica,sans-Serif" font-size="14.00">Finish</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -25,8 +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 ${SERVER_WORKDIR}/deployments /openim/openim-server/deployments
|
||||
# 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"]
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.43.0 (0)
|
||||
-->
|
||||
<!-- Title: %3 Pages: 1 -->
|
||||
<svg width="447pt" height="165pt"
|
||||
viewBox="0.00 0.00 447.00 164.74" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(36 128.74)">
|
||||
<title>%3</title>
|
||||
<polygon fill="dimgray" stroke="transparent" points="-36,36 -36,-128.74 411,-128.74 411,36 -36,36"/>
|
||||
<text text-anchor="middle" x="187.5" y="-77.54" font-family="Helvetica,sans-Serif" font-size="14.00">Sweep's Plan & Progress</text>
|
||||
<!-- start -->
|
||||
<g id="node1" class="node">
|
||||
<title>start</title>
|
||||
</g>
|
||||
<!-- e9278104-5ca8-4ff3-9348-96db9869a52a -->
|
||||
<g id="node3" class="node">
|
||||
<title>e9278104-5ca8-4ff3-9348-96db9869a52a</title>
|
||||
<ellipse fill="yellow" stroke="black" cx="184.5" cy="-26.87" rx="132.46" ry="26.74"/>
|
||||
<text text-anchor="middle" x="184.5" y="-30.67" font-family="Helvetica,sans-Serif" font-size="14.00">⋯ Modify</text>
|
||||
<text text-anchor="middle" x="184.5" y="-15.67" font-family="Helvetica,sans-Serif" font-size="14.00">internal/rpc/user/user.go</text>
|
||||
</g>
|
||||
<!-- start->e9278104-5ca8-4ff3-9348-96db9869a52a -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>start->e9278104-5ca8-4ff3-9348-96db9869a52a</title>
|
||||
<path fill="none" stroke="black" d="M1.03,-26.87C4.1,-26.87 20.28,-26.87 41.85,-26.87"/>
|
||||
<polygon fill="black" stroke="black" points="42.12,-30.37 52.12,-26.87 42.12,-23.37 42.12,-30.37"/>
|
||||
<text text-anchor="middle" x="26.64" y="-33.67" font-family="Helvetica,sans-Serif" font-size="14.00">Start</text>
|
||||
</g>
|
||||
<!-- end -->
|
||||
<g id="node2" class="node">
|
||||
<title>end</title>
|
||||
</g>
|
||||
<!-- e9278104-5ca8-4ff3-9348-96db9869a52a->end -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>e9278104-5ca8-4ff3-9348-96db9869a52a->end</title>
|
||||
<path fill="none" stroke="black" d="M316.98,-26.87C336.34,-26.87 353.23,-26.87 363.61,-26.87"/>
|
||||
<polygon fill="black" stroke="black" points="363.85,-30.37 373.85,-26.87 363.85,-23.37 363.85,-30.37"/>
|
||||
<text text-anchor="middle" x="345.36" y="-33.67" font-family="Helvetica,sans-Serif" font-size="14.00">Finish</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -18,13 +18,11 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
ginProm "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||
@@ -35,8 +33,6 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
||||
ginProm "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -55,12 +51,13 @@ func run(port int, proPort int) error {
|
||||
if port == 0 || proPort == 0 {
|
||||
err := "port or proPort is empty:" + strconv.Itoa(port) + "," + strconv.Itoa(proPort)
|
||||
log.ZError(context.Background(), err, nil)
|
||||
|
||||
return fmt.Errorf(err)
|
||||
}
|
||||
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
log.ZError(context.Background(), "Failed to initialize Redis", err)
|
||||
|
||||
return err
|
||||
}
|
||||
log.ZInfo(context.Background(), "api start init discov client")
|
||||
@@ -71,29 +68,30 @@ func run(port int, proPort int) error {
|
||||
client, err = kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
||||
if err != nil {
|
||||
log.ZError(context.Background(), "Failed to initialize discovery register", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if err = client.CreateRpcRootNodes(config.Config.GetServiceNames()); err != nil {
|
||||
log.ZError(context.Background(), "Failed to create RPC root nodes", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
log.ZInfo(context.Background(), "api register public config to discov")
|
||||
if err = client.RegisterConf2Registry(constant.OpenIMCommonConfigKey, config.Config.EncodeConfig()); err != nil {
|
||||
log.ZError(context.Background(), "Failed to register public config to discov", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
log.ZInfo(context.Background(), "api register public config to discov success")
|
||||
router := api.NewGinRouter(client, rdb)
|
||||
//////////////////////////////
|
||||
if config.Config.Prometheus.Enable {
|
||||
p := ginProm.NewPrometheus("app", prommetrics.GetGinCusMetrics("Api"))
|
||||
p.SetListenAddress(fmt.Sprintf(":%d", proPort))
|
||||
p.Use(router)
|
||||
}
|
||||
/////////////////////////////////
|
||||
log.ZInfo(context.Background(), "api init router success")
|
||||
|
||||
var address string
|
||||
if config.Config.Api.ListenIP != "" {
|
||||
address = net.JoinHostPort(config.Config.Api.ListenIP, strconv.Itoa(port))
|
||||
@@ -102,25 +100,10 @@ func run(port int, proPort int) error {
|
||||
}
|
||||
log.ZInfo(context.Background(), "start api server", "address", address, "OpenIM version", config.Version)
|
||||
|
||||
server := http.Server{Addr: address, Handler: router}
|
||||
go func() {
|
||||
err = server.ListenAndServe()
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
log.ZError(context.Background(), "api run failed", err, "address", address)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
err = router.Run(address)
|
||||
if err != nil {
|
||||
log.ZError(context.Background(), "api run failed", err, "address", address)
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
||||
<-sigs
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// graceful shutdown operation.
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
log.ZError(context.Background(), "failed to api-server shutdown", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ func main() {
|
||||
msgGatewayCmd.AddWsPortFlag()
|
||||
msgGatewayCmd.AddPortFlag()
|
||||
msgGatewayCmd.AddPrometheusPortFlag()
|
||||
|
||||
if err := msgGatewayCmd.Exec(); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ templates:
|
||||
- /etc/alertmanager/email.tmpl
|
||||
|
||||
route:
|
||||
group_by: ['alertname']
|
||||
group_wait: 5s
|
||||
group_interval: 5s
|
||||
repeat_interval: 5m
|
||||
@@ -27,7 +26,7 @@ route:
|
||||
receivers:
|
||||
- name: email
|
||||
email_configs:
|
||||
- to: 'alert@example.com'
|
||||
- to: {EMAIL_TO:-'alert@example.com'}
|
||||
html: '{{ template "email.to.html" . }}'
|
||||
headers: { Subject: "[OPENIM-SERVER]Alarm" }
|
||||
send_resolved: true
|
||||
@@ -35,6 +35,26 @@ zookeeper:
|
||||
username: ''
|
||||
password: ''
|
||||
|
||||
###################### Mysql ######################
|
||||
# MySQL configuration
|
||||
# Currently, only single machine setup is supported
|
||||
#
|
||||
# Maximum number of open connections
|
||||
# Maximum number of idle connections
|
||||
# Maximum lifetime in seconds a connection can be reused
|
||||
# Log level: 1=slient, 2=error, 3=warn, 4=info
|
||||
# Slow query threshold in milliseconds
|
||||
mysql:
|
||||
address: [ 172.28.0.1:13306 ]
|
||||
username: root
|
||||
password: openIM123
|
||||
database: openIM_v3
|
||||
maxOpenConn: 1000
|
||||
maxIdleConn: 100
|
||||
maxLifeTime: 60
|
||||
logLevel: 4
|
||||
slowThreshold: 500
|
||||
|
||||
###################### Mongo ######################
|
||||
# MongoDB configuration
|
||||
# If uri is not empty, it will be used directly
|
||||
@@ -115,14 +135,14 @@ api:
|
||||
# minio.signEndpoint is minio public network address
|
||||
object:
|
||||
enable: "minio"
|
||||
apiURL: "http://172.28.0.1:10002"
|
||||
apiURL: "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"
|
||||
publicRead: false
|
||||
cos:
|
||||
bucketURL: https://temp-1252357374.cos.ap-chengdu.myqcloud.com
|
||||
@@ -138,21 +158,13 @@ object:
|
||||
accessKeySecret: ''
|
||||
sessionToken: ''
|
||||
publicRead: false
|
||||
kodo:
|
||||
endpoint: "http://s3.cn-east-1.qiniucs.com"
|
||||
bucket: "demo-9999999"
|
||||
bucketURL: "http://your.domain.com"
|
||||
accessKeyID: ''
|
||||
accessKeySecret: ''
|
||||
sessionToken: ''
|
||||
publicRead: false
|
||||
|
||||
###################### RPC Port Configuration ######################
|
||||
# RPC service ports
|
||||
# These ports are passed into the program by the script and are not recommended to modify
|
||||
# For launching multiple programs, just fill in multiple ports separated by commas
|
||||
# For example, [10110, 10111]
|
||||
rpcPort:
|
||||
rpcPort:
|
||||
openImUserPort: [ 10110 ]
|
||||
openImFriendPort: [ 10120 ]
|
||||
openImMessagePort: [ 10130 ]
|
||||
@@ -300,7 +312,7 @@ iosPush:
|
||||
# Timeout in seconds
|
||||
# Whether to continue execution if callback fails
|
||||
callback:
|
||||
url: ""
|
||||
url:
|
||||
beforeSendSingleMsg:
|
||||
enable: false
|
||||
timeout: 5
|
||||
@@ -308,7 +320,6 @@ callback:
|
||||
afterSendSingleMsg:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeSendGroupMsg:
|
||||
enable: false
|
||||
timeout: 5
|
||||
@@ -316,7 +327,6 @@ callback:
|
||||
afterSendGroupMsg:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
msgModify:
|
||||
enable: false
|
||||
timeout: 5
|
||||
@@ -324,15 +334,12 @@ callback:
|
||||
userOnline:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
userOffline:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
userKickOff:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
offlinePush:
|
||||
enable: false
|
||||
timeout: 5
|
||||
@@ -357,10 +364,6 @@ callback:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterCreateGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeMemberJoinGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
@@ -369,129 +372,18 @@ callback:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterSetGroupMemberInfo:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
setMessageReactionExtensions:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
quitGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
killGroupMember:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
dismissGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
joinGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
groupMsgRead:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
singleMsgRead:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
updateUserInfo:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeUserRegister:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterUserRegister:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
transferGroupOwner:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeSetFriendRemark:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterSetFriendRemark:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterGroupMsgRead:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterGroupMsgRevoke:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterJoinGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeInviteUserToGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
joinGroupAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
setGroupInfoAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
setGroupInfoBefore:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
revokeMsgAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
addBlackBefore:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
addFriendAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
addFriendAgreeBefore:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
deleteFriendAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
importFriendsBefore:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
importFriendsAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
removeBlackAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
|
||||
###################### Prometheus ######################
|
||||
# Prometheus configuration for various services
|
||||
# The number of Prometheus ports per service needs to correspond to rpcPort
|
||||
# The number of ports needs to be consistent with msg_transfer_service_num in script/path_info.sh
|
||||
prometheus:
|
||||
enable: false
|
||||
prometheusUrl: 172.28.0.1:13000
|
||||
prometheusUrl: "https://openim.prometheus"
|
||||
apiPrometheusPort: [20100]
|
||||
userPrometheusPort: [ 20110 ]
|
||||
friendPrometheusPort: [ 20120 ]
|
||||
@@ -8,15 +8,4 @@ groups:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Instance {{ $labels.instance }} down"
|
||||
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minutes."
|
||||
|
||||
- name: database_insert_failure_alerts
|
||||
rules:
|
||||
- alert: DatabaseInsertFailed
|
||||
expr: (increase(msg_insert_redis_failed_total[5m]) > 0) or (increase(msg_insert_mongo_failed_total[5m]) > 0)
|
||||
for: 1m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Increase in MsgInsertRedisFailedCounter or MsgInsertMongoFailedCounter detected"
|
||||
description: "Either MsgInsertRedisFailedCounter or MsgInsertMongoFailedCounter has increased in the last 5 minutes, indicating failures in message insert operations to Redis or MongoDB,maybe the redis or mongodb is crash."
|
||||
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minutes."
|
||||
@@ -1,36 +0,0 @@
|
||||
# Examples Directory
|
||||
|
||||
Welcome to the `examples` directory of our project! This directory contains a collection of example files that demonstrate various configurations and setups for our software. These examples are designed to provide you with templates that can be used as a starting point for your own configurations.
|
||||
|
||||
## Overview
|
||||
|
||||
In this directory, you'll find examples for a variety of use cases. Each file is a template with default values and configurations that illustrate best practices and typical scenarios. Whether you're just getting started or looking to implement a complex setup, these examples should help you get on the right track.
|
||||
|
||||
## Structure
|
||||
|
||||
Here's a quick overview of what you'll find in this directory:
|
||||
|
||||
+ `env-example.yaml`: Demonstrates how to set up environment variables.
|
||||
+ `openim-example.yaml`: A sample configuration file for the OpenIM application.
|
||||
+ `prometheus-example.yml`: An example Prometheus configuration for monitoring.
|
||||
+ `alertmanager-example.yml`: A template for setting up Alertmanager configurations.
|
||||
|
||||
## How to Use These Examples
|
||||
|
||||
To use these examples, simply copy the relevant file to your working directory and rename it as needed (e.g., removing the `-example` suffix). Then, modify the file according to your requirements.
|
||||
|
||||
### Tips for Using Example Files:
|
||||
|
||||
1. **Read the Comments**: Each file contains comments that explain various sections and settings. Make sure to read these comments for a better understanding of how to customize the file.
|
||||
2. **Check for Required Changes**: Some examples might require mandatory changes (like setting specific environment variables) before they can be used effectively.
|
||||
3. **Version Compatibility**: Ensure that the example files are compatible with the version of the software you are using.
|
||||
|
||||
## Contributing
|
||||
|
||||
If you have a configuration that you believe would be beneficial to others, please feel free to contribute by opening a pull request with your proposed changes. We appreciate contributions that expand our examples with new scenarios and use cases.
|
||||
|
||||
## Support
|
||||
|
||||
If you encounter any issues or have questions regarding the example files, please open an issue on our repository. Our community is here to help you navigate through any challenges you might face.
|
||||
|
||||
Thank you for exploring our examples, and we hope they will be helpful in setting up and configuring your environment!
|
||||
@@ -84,8 +84,8 @@ $ sudo sealos run labring/kubernetes:v1.25.0 labring/helm:v3.8.2 labring/calico:
|
||||
If you are local, you can also use Kind and Minikube to test, for example, using Kind:
|
||||
|
||||
```bash
|
||||
$ GO111MODULE="on" go get sigs.k8s.io/kind@v0.11.1
|
||||
$ kind create cluster
|
||||
$ sGO111MODULE="on" go get sigs.k8s.io/kind@v0.11.1
|
||||
$ skind create cluster
|
||||
```
|
||||
|
||||
### Installing helm
|
||||
@@ -154,6 +154,8 @@ GO111MODULE=on go get github.com/roboll/helmfile@latest
|
||||
```
|
||||
|
||||
```bash
|
||||
export MYSQL_ADDRESS=im-mysql
|
||||
export MYSQL_PORT=3306
|
||||
export MONGO_ADDRESS=im-mongo
|
||||
export MONGO_PORT=27017
|
||||
export REDIS_ADDRESS=im-redis-master
|
||||
@@ -172,4 +174,4 @@ cp ../config/notification.yaml ./charts/generated-configs/notification.yaml
|
||||
|
||||
```bash
|
||||
helmfile apply
|
||||
```
|
||||
```
|
||||
@@ -27,7 +27,7 @@ route:
|
||||
receivers:
|
||||
- name: email
|
||||
email_configs:
|
||||
- to: '${ALERTMANAGER_EMAIL_TO}'
|
||||
- to: ${ALERTMANAGER_EMAIL_TO}
|
||||
html: '{{ template "email.to.html" . }}'
|
||||
headers: { Subject: "[OPENIM-SERVER]Alarm" }
|
||||
send_resolved: true
|
||||
send_resolved: true
|
||||
@@ -53,6 +53,19 @@ rpcRegisterName:
|
||||
openImAdminName: ${OPENIM_ADMIN_NAME}
|
||||
openImChatName: ${OPENIM_CHAT_NAME}
|
||||
|
||||
###################### MySQL ######################
|
||||
mysql:
|
||||
# address: [ 127.0.0.1:13306 ] #目前仅支持单机
|
||||
# username: root #用户名
|
||||
# password: openIM123 #密码
|
||||
# database: openIM_v2 #不建议修改
|
||||
# maxOpenConn: 1000 #最大连接数
|
||||
# maxIdleConn: 100 #最大空闲连接数
|
||||
# maxLifeTime: 60 #连接可以重复使用的最长时间(秒)
|
||||
# logLevel: 4 #日志级别 1=slient 2=error 3=warn 4=info
|
||||
# slowThreshold: 500 #慢语句阈值 (毫秒)
|
||||
database: openim_enterprise
|
||||
|
||||
###################### Log ######################
|
||||
log:
|
||||
storageLocation: ../logs/ #存放目录
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
# Copyright © 2023 OpenIM. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# ======================================
|
||||
# ========= Basic Configuration ========
|
||||
# ======================================
|
||||
|
||||
# The user for authentication or system operations.
|
||||
# Default: OPENIM_USER=root
|
||||
USER=${OPENIM_USER}
|
||||
# Default: USER=root
|
||||
USER=${USER}
|
||||
|
||||
# Password associated with the specified user for authentication.
|
||||
# Default: PASSWORD=openIM123
|
||||
@@ -41,20 +55,61 @@ DOCKER_BRIDGE_SUBNET=${DOCKER_BRIDGE_SUBNET}
|
||||
# Default: DOCKER_BRIDGE_GATEWAY=172.28.0.1
|
||||
DOCKER_BRIDGE_GATEWAY=${DOCKER_BRIDGE_GATEWAY}
|
||||
|
||||
MONGO_NETWORK_ADDRESS=${MONGO_NETWORK_ADDRESS}
|
||||
REDIS_NETWORK_ADDRESS=${REDIS_NETWORK_ADDRESS}
|
||||
KAFKA_NETWORK_ADDRESS=${KAFKA_NETWORK_ADDRESS}
|
||||
ZOOKEEPER_NETWORK_ADDRESS=${ZOOKEEPER_NETWORK_ADDRESS}
|
||||
MINIO_NETWORK_ADDRESS=${MINIO_NETWORK_ADDRESS}
|
||||
OPENIM_WEB_NETWORK_ADDRESS=${OPENIM_WEB_NETWORK_ADDRESS}
|
||||
OPENIM_SERVER_NETWORK_ADDRESS=${OPENIM_SERVER_NETWORK_ADDRESS}
|
||||
OPENIM_CHAT_NETWORK_ADDRESS=${OPENIM_CHAT_NETWORK_ADDRESS}
|
||||
PROMETHEUS_NETWORK_ADDRESS=${PROMETHEUS_NETWORK_ADDRESS}
|
||||
GRAFANA_NETWORK_ADDRESS=${GRAFANA_NETWORK_ADDRESS}
|
||||
NODE_EXPORTER_NETWORK_ADDRESS=${NODE_EXPORTER_NETWORK_ADDRESS}
|
||||
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=${OPENIM_ADMIN_FRONT_NETWORK_ADDRESS}
|
||||
ALERT_MANAGER_NETWORK_ADDRESS=${ALERT_MANAGER_NETWORK_ADDRESS}
|
||||
# Address or hostname for the MySQL network.
|
||||
# Default: MYSQL_NETWORK_ADDRESS=172.28.0.2
|
||||
MYSQL_NETWORK_ADDRESS=${MYSQL_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the MongoDB network.
|
||||
# Default: MONGO_NETWORK_ADDRESS=172.28.0.3
|
||||
MONGO_NETWORK_ADDRESS=${MONGO_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the Redis network.
|
||||
# Default: REDIS_NETWORK_ADDRESS=172.28.0.4
|
||||
REDIS_NETWORK_ADDRESS=${REDIS_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the Kafka network.
|
||||
# Default: KAFKA_NETWORK_ADDRESS=172.28.0.5
|
||||
KAFKA_NETWORK_ADDRESS=${KAFKA_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the ZooKeeper network.
|
||||
# Default: ZOOKEEPER_NETWORK_ADDRESS=172.28.0.6
|
||||
ZOOKEEPER_NETWORK_ADDRESS=${ZOOKEEPER_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the MinIO network.
|
||||
# Default: MINIO_NETWORK_ADDRESS=172.28.0.7
|
||||
MINIO_NETWORK_ADDRESS=${MINIO_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the OpenIM web network.
|
||||
# Default: OPENIM_WEB_NETWORK_ADDRESS=172.28.0.8
|
||||
OPENIM_WEB_NETWORK_ADDRESS=${OPENIM_WEB_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the OpenIM server network.
|
||||
# Default: OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.9
|
||||
OPENIM_SERVER_NETWORK_ADDRESS=${OPENIM_SERVER_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the OpenIM chat network.
|
||||
# Default: OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.10
|
||||
OPENIM_CHAT_NETWORK_ADDRESS=${OPENIM_CHAT_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the Prometheus network.
|
||||
# Default: PROMETHEUS_NETWORK_ADDRESS=172.28.0.11
|
||||
PROMETHEUS_NETWORK_ADDRESS=${PROMETHEUS_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the Grafana network.
|
||||
# Default: GRAFANA_NETWORK_ADDRESS=172.28.0.12
|
||||
GRAFANA_NETWORK_ADDRESS=${GRAFANA_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the node_exporter network.
|
||||
# Default: NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.13
|
||||
NODE_EXPORTER_NETWORK_ADDRESS=${NODE_EXPORTER_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the OpenIM admin network.
|
||||
# Default: OPENIM_ADMIN_NETWORK_ADDRESS=172.28.0.14
|
||||
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=${OPENIM_ADMIN_FRONT_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the alertmanager network.
|
||||
# Default: ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.15
|
||||
ALERT_MANAGER_NETWORK_ADDRESS=${ALERT_MANAGER_NETWORK_ADDRESS}
|
||||
# ===============================================
|
||||
# = Component Extension Configuration =
|
||||
# ===============================================
|
||||
@@ -69,6 +124,20 @@ ZOOKEEPER_ADDRESS=${ZOOKEEPER_NETWORK_ADDRESS}
|
||||
# Default: ZOOKEEPER_PORT=12181
|
||||
ZOOKEEPER_PORT=${ZOOKEEPER_PORT}
|
||||
|
||||
# ----- MySQL Configuration -----
|
||||
|
||||
# Address or hostname for the MySQL service.
|
||||
# Default: MYSQL_ADDRESS=172.28.0.1
|
||||
MYSQL_ADDRESS=${MYSQL_NETWORK_ADDRESS}
|
||||
|
||||
# Port on which MySQL database service is running.
|
||||
# Default: MYSQL_PORT=13306
|
||||
MYSQL_PORT=${MYSQL_PORT}
|
||||
|
||||
# Password to authenticate with the MySQL database service.
|
||||
# Default: MYSQL_PASSWORD=openIM123
|
||||
MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||
|
||||
# ----- MongoDB Configuration -----
|
||||
# Address or hostname for the MongoDB service.
|
||||
# Default: MONGO_ADDRESS=172.28.0.1
|
||||
@@ -76,11 +145,11 @@ MONGO_ADDRESS=${MONGO_NETWORK_ADDRESS}
|
||||
|
||||
# Port on which MongoDB service is running.
|
||||
# Default: MONGO_PORT=37017
|
||||
# MONGO_PORT=${MONGO_PORT}
|
||||
MONGO_PORT=${MONGO_PORT}
|
||||
|
||||
# Username to authenticate with the MongoDB service.
|
||||
# Default: MONGO_USERNAME=root
|
||||
# MONGO_USERNAME=${MONGO_USERNAME}
|
||||
MONGO_USERNAME=${MONGO_USERNAME}
|
||||
|
||||
# Password to authenticate with the MongoDB service.
|
||||
# Default: MONGO_PASSWORD=openIM123
|
||||
@@ -108,9 +177,6 @@ REDIS_PASSWORD=${REDIS_PASSWORD}
|
||||
# Default: KAFKA_ADDRESS=172.28.0.1
|
||||
KAFKA_ADDRESS=${KAFKA_NETWORK_ADDRESS}
|
||||
|
||||
# Kakfa username to authenticate with the Kafka service.
|
||||
# KAFKA_USERNAME=${KAFKA_USERNAME}
|
||||
|
||||
# Port on which Kafka distributed streaming platform is running.
|
||||
# Default: KAFKA_PORT=19092
|
||||
KAFKA_PORT=${KAFKA_PORT}
|
||||
@@ -138,7 +204,7 @@ MINIO_PORT=${MINIO_PORT}
|
||||
|
||||
# Access key to authenticate with the MinIO service.
|
||||
# Default: MINIO_ACCESS_KEY=root
|
||||
# MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
|
||||
MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
|
||||
|
||||
# Secret key corresponding to the access key for MinIO authentication.
|
||||
# Default: MINIO_SECRET_KEY=openIM123
|
||||
@@ -35,22 +35,35 @@ zookeeper:
|
||||
username: ${ZOOKEEPER_USERNAME}
|
||||
password: ${ZOOKEEPER_PASSWORD}
|
||||
|
||||
###################### Mysql ######################
|
||||
# MySQL configuration
|
||||
# Currently, only single machine setup is supported
|
||||
#
|
||||
# Maximum number of open connections
|
||||
# Maximum number of idle connections
|
||||
# Maximum lifetime in seconds a connection can be reused
|
||||
# Log level: 1=slient, 2=error, 3=warn, 4=info
|
||||
# Slow query threshold in milliseconds
|
||||
mysql:
|
||||
address: [ ${MYSQL_ADDRESS}:${MYSQL_PORT} ]
|
||||
username: ${MYSQL_USERNAME}
|
||||
password: ${MYSQL_PASSWORD}
|
||||
database: ${MYSQL_DATABASE}
|
||||
maxOpenConn: ${MYSQL_MAX_OPEN_CONN}
|
||||
maxIdleConn: ${MYSQL_MAX_IDLE_CONN}
|
||||
maxLifeTime: ${MYSQL_MAX_LIFETIME}
|
||||
logLevel: ${MYSQL_LOG_LEVEL}
|
||||
slowThreshold: ${MYSQL_SLOW_THRESHOLD}
|
||||
|
||||
###################### Mongo ######################
|
||||
# MongoDB configuration
|
||||
|
||||
# If uri is not empty, it will be used directly for the MongoDB connection.
|
||||
# This is a complete MongoDB URI string.
|
||||
# Example: mongodb://user:password@host1:port1,host2:port2/dbname?options
|
||||
mongo:
|
||||
uri: ${MONGO_URI}
|
||||
|
||||
# List of MongoDB server addresses.
|
||||
# Used for constructing the MongoDB URI if 'uri' above is empty.
|
||||
# For a standalone setup, specify the address of the single server.
|
||||
# For a sharded cluster, specify the addresses of the Mongos servers.
|
||||
# Example: [ '172.28.0.1:37017', '172.28.0.2:37017' ]
|
||||
# If uri is not empty, it will be used directly
|
||||
#
|
||||
# MongoDB address for standalone setup, Mongos address for sharded cluster setup
|
||||
# Default MongoDB database name
|
||||
# Maximum connection pool size
|
||||
mongo:
|
||||
uri: ${MONGO_URI}
|
||||
address: [ ${MONGO_ADDRESS}:${MONGO_PORT} ]
|
||||
database: ${MONGO_DATABASE}
|
||||
username: ${MONGO_USERNAME}
|
||||
@@ -145,21 +158,13 @@ object:
|
||||
accessKeySecret: ${OSS_ACCESS_KEY_SECRET}
|
||||
sessionToken: ${OSS_SESSION_TOKEN}
|
||||
publicRead: ${OSS_PUBLIC_READ}
|
||||
kodo:
|
||||
endpoint: "${KODO_ENDPOINT}"
|
||||
bucket: "${KODO_BUCKET}"
|
||||
bucketURL: "${KODO_BUCKET_URL}"
|
||||
accessKeyID: ${KODO_ACCESS_KEY_ID}
|
||||
accessKeySecret: ${KODO_ACCESS_KEY_SECRET}
|
||||
sessionToken: ${KODO_SESSION_TOKEN}
|
||||
publicRead: ${KODO_PUBLIC_READ}
|
||||
|
||||
###################### RPC Port Configuration ######################
|
||||
# RPC service ports
|
||||
# These ports are passed into the program by the script and are not recommended to modify
|
||||
# For launching multiple programs, just fill in multiple ports separated by commas
|
||||
# For example, [10110, 10111]
|
||||
rpcPort:
|
||||
rpcPort:
|
||||
openImUserPort: [ ${OPENIM_USER_PORT} ]
|
||||
openImFriendPort: [ ${OPENIM_FRIEND_PORT} ]
|
||||
openImMessagePort: [ ${OPENIM_MESSAGE_PORT} ]
|
||||
@@ -307,191 +312,71 @@ iosPush:
|
||||
# Timeout in seconds
|
||||
# Whether to continue execution if callback fails
|
||||
callback:
|
||||
url: ""
|
||||
url:
|
||||
beforeSendSingleMsg:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterSendSingleMsg:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
beforeSendGroupMsg:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterSendGroupMsg:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
msgModify:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
userOnline:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
userOffline:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
userKickOff:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
offlinePush:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
onlinePush:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
superGroupOnlinePush:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeAddFriend:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeUpdateUserInfo:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeCreateGroup:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
afterCreateGroup:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeMemberJoinGroup:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeSetGroupMemberInfo:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
afterSetGroupMemberInfo:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
setMessageReactionExtensions:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
quitGroup:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
killGroupMember:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
dismissGroup:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
joinGroup:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
groupMsgRead:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
singleMsgRead:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
updateUserInfo:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
beforeUserRegister:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
afterUserRegister:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
transferGroupOwner:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
beforeSetFriendRemark:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
afterSetFriendRemark:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
afterGroupMsgRead:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
afterGroupMsgRevoke:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
afterJoinGroup:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
beforeInviteUserToGroup:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
joinGroupAfter:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
setGroupInfoAfter:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
setGroupInfoBefore:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
revokeMsgAfter:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
addBlackBefore:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
addFriendAfter:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
addFriendAgreeBefore:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
deleteFriendAfter:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
importFriendsBefore:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
importFriendsAfter:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
removeBlackAfter:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
|
||||
###################### Prometheus ######################
|
||||
# Prometheus configuration for various services
|
||||
# The number of Prometheus ports per service needs to correspond to rpcPort
|
||||
@@ -510,4 +395,4 @@ prometheus:
|
||||
conversationPrometheusPort: [ ${CONVERSATION_PROM_PORT} ]
|
||||
rtcPrometheusPort: [ ${RTC_PROM_PORT} ]
|
||||
thirdPrometheusPort: [ ${THIRD_PROM_PORT} ]
|
||||
messageTransferPrometheusPort: [ ${MSG_TRANSFER_PROM_PORT} ] # List of ports
|
||||
messageTransferPrometheusPort: [ ${MSG_TRANSFER_PROM_PORT} ] # List of ports
|
||||
@@ -7,55 +7,70 @@ networks:
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: '${DOCKER_BRIDGE_SUBNET:-172.28.0.0/16}'
|
||||
gateway: '${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}'
|
||||
- subnet: '${DOCKER_BRIDGE_SUBNET}'
|
||||
gateway: '${DOCKER_BRIDGE_GATEWAY}'
|
||||
|
||||
services:
|
||||
mongodb:
|
||||
image: mongo:${MONGODB_IMAGE_VERSION-6.0.2}
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
ports:
|
||||
- "${MONGO_PORT:-37017}:27017"
|
||||
container_name: mongo
|
||||
command: --wiredTigerCacheSizeGB 1 --auth
|
||||
- "${MYSQL_PORT}:3306"
|
||||
container_name: mysql
|
||||
volumes:
|
||||
- "${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
|
||||
- "${DATA_DIR}/components/mysql/data:/var/lib/mysql"
|
||||
- "/etc/localtime:/etc/localtime"
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- wiredTigerCacheSizeGB=1
|
||||
- MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME:-root}
|
||||
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD:-openIM123}
|
||||
- MONGO_INITDB_DATABASE=${MONGO_DATABASE:-openIM_v3}
|
||||
MYSQL_ROOT_PASSWORD: "${MYSQL_PASSWORD}"
|
||||
restart: always
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${MONGO_NETWORK_ADDRESS:-172.28.0.2}
|
||||
ipv4_address: ${MYSQL_NETWORK_ADDRESS}
|
||||
|
||||
mongodb:
|
||||
image: mongo:6.0.2
|
||||
ports:
|
||||
- "${MONGO_PORT}:27017"
|
||||
container_name: mongo
|
||||
command: --wiredTigerCacheSizeGB 1 --auth
|
||||
volumes:
|
||||
- "${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
|
||||
- MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME}
|
||||
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD}
|
||||
- MONGO_INITDB_DATABASE=${MONGO_DATABASE}
|
||||
restart: always
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${MONGO_NETWORK_ADDRESS}
|
||||
|
||||
redis:
|
||||
image: redis:${REDIS_IMAGE_VERSION:-7.0.0}
|
||||
image: redis:7.0.0
|
||||
container_name: redis
|
||||
ports:
|
||||
- "${REDIS_PORT:-16379}:6379"
|
||||
- "${REDIS_PORT}:6379"
|
||||
volumes:
|
||||
- "${DATA_DIR:-./}/components/redis/data:/data"
|
||||
- "${DATA_DIR:-./}/components/redis/config/redis.conf:/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
|
||||
sysctls:
|
||||
net.core.somaxconn: 1024
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD:-openIM123} --appendonly yes
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${REDIS_NETWORK_ADDRESS:-172.28.0.3}
|
||||
ipv4_address: ${REDIS_NETWORK_ADDRESS}
|
||||
|
||||
zookeeper:
|
||||
image: bitnami/zookeeper:${ZOOKEEPER_IMAGE_VERSION:-3.8}
|
||||
image: bitnami/zookeeper:3.8
|
||||
container_name: zookeeper
|
||||
ports:
|
||||
- "${ZOOKEEPER_PORT:-12181}:2181"
|
||||
- "${ZOOKEEPER_PORT}:2181"
|
||||
volumes:
|
||||
- "/etc/localtime:/etc/localtime"
|
||||
environment:
|
||||
@@ -64,124 +79,131 @@ services:
|
||||
restart: always
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${ZOOKEEPER_NETWORK_ADDRESS:-172.28.0.5}
|
||||
ipv4_address: ${ZOOKEEPER_NETWORK_ADDRESS}
|
||||
|
||||
kafka:
|
||||
image: 'bitnami/kafka:${KAFKA_IMAGE_VERSION:-3.5.1}'
|
||||
image: 'bitnami/kafka:3.5.1'
|
||||
container_name: kafka
|
||||
user: root
|
||||
restart: always
|
||||
user: ${KAFKA_USER:-root}
|
||||
ports:
|
||||
- "${KAFKA_PORT:-19094}:9094"
|
||||
- "${KAFKA_PORT}:9094"
|
||||
volumes:
|
||||
- ./scripts/create-topic.sh:/opt/bitnami/kafka/create-topic.sh
|
||||
- "${DATA_DIR:-./}/components/kafka:/bitnami/kafka"
|
||||
- ${DATA_DIR}/components/kafka:/bitnami/kafka
|
||||
command: >
|
||||
bash -c "/opt/bitnami/scripts/kafka/run.sh & sleep 5; /opt/bitnami/kafka/create-topic.sh; wait"
|
||||
bash -c "
|
||||
/opt/bitnami/scripts/kafka/run.sh & sleep 5; /opt/bitnami/kafka/create-topic.sh; wait
|
||||
"
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- KAFKA_CFG_NODE_ID=0
|
||||
- KAFKA_CFG_PROCESS_ROLES=controller,broker
|
||||
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@<your_host>:9093
|
||||
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
|
||||
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}:${KAFKA_PORT:-19094}
|
||||
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://${DOCKER_BRIDGE_GATEWAY}:${KAFKA_PORT}
|
||||
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
|
||||
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${KAFKA_NETWORK_ADDRESS:-172.28.0.4}
|
||||
ipv4_address: ${KAFKA_NETWORK_ADDRESS}
|
||||
|
||||
minio:
|
||||
image: minio/minio:${MINIO_IMAGE_VERSION:-latest}
|
||||
image: minio/minio
|
||||
ports:
|
||||
- "${MINIO_PORT:-10005}:9000"
|
||||
- "${MINIO_PORT}:9000"
|
||||
- "9090:9090"
|
||||
container_name: minio
|
||||
volumes:
|
||||
- "${DATA_DIR:-./}/components/mnt/data:/data"
|
||||
- "${DATA_DIR:-./}/components/mnt/config:/root/.minio"
|
||||
- "${DATA_DIR}/components/mnt/data:/data"
|
||||
- "${DATA_DIR}/components/mnt/config:/root/.minio"
|
||||
environment:
|
||||
MINIO_ROOT_USER: "${MINIO_ACCESS_KEY:-root}"
|
||||
MINIO_ROOT_PASSWORD: "${MINIO_SECRET_KEY:-openIM123}"
|
||||
MINIO_ROOT_USER: "${MINIO_ACCESS_KEY}"
|
||||
MINIO_ROOT_PASSWORD: "${MINIO_SECRET_KEY}"
|
||||
restart: always
|
||||
command: minio server /data --console-address ':9090'
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${MINIO_NETWORK_ADDRESS:-172.28.0.6}
|
||||
ipv4_address: ${MINIO_NETWORK_ADDRESS}
|
||||
|
||||
openim-web:
|
||||
image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-web:${OPENIM_WEB_IMAGE_VERSION:-latest}
|
||||
# image: ghcr.io/openimsdk/openim-web:latest
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-web:latest
|
||||
# image: openim/openim-web:latest
|
||||
image: ${IMAGE_REGISTRY}/openim-web:latest
|
||||
container_name: openim-web
|
||||
environment:
|
||||
- OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH:-/app/dist}
|
||||
- OPENIM_WEB_PORT=${OPENIM_WEB_PORT:-11001}
|
||||
- OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH}
|
||||
- OPENIM_WEB_PORT=${OPENIM_WEB_PORT}
|
||||
restart: always
|
||||
ports:
|
||||
- "${OPENIM_WEB_PORT:-11001}:11001"
|
||||
- "${OPENIM_WEB_PORT}:11001"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS:-172.28.0.7}
|
||||
ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS}
|
||||
|
||||
# Uncomment and configure the following services as needed
|
||||
# openim-admin:
|
||||
# image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin-front:v3.4.0
|
||||
# container_name: openim-admin
|
||||
# restart: always
|
||||
# ports:
|
||||
# - "${OPENIM_ADMIN_FRONT_PORT:-11002}:80"
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${OPENIM_ADMIN_FRONT_NETWORK_ADDRESS:-172.28.0.13}
|
||||
openim-admin:
|
||||
image: ${IMAGE_REGISTRY}/openim-admin-front:v3.4.0
|
||||
# image: ghcr.io/openimsdk/openim-admin-front:v3.4.0
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-admin-front:v3.4.0
|
||||
# image: openim/openim-admin-front:v3.4.0
|
||||
container_name: openim-admin
|
||||
restart: always
|
||||
ports:
|
||||
- "${OPENIM_ADMIN_FRONT_PORT}:80"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${OPENIM_ADMIN_FRONT_NETWORK_ADDRESS}
|
||||
|
||||
# prometheus:
|
||||
# image: prom/prometheus
|
||||
# container_name: prometheus
|
||||
# hostname: prometheus
|
||||
# restart: always
|
||||
# volumes:
|
||||
# - ./config/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
# - ./config/instance-down-rules.yml:/etc/prometheus/instance-down-rules.yml
|
||||
# ports:
|
||||
# - "${PROMETHEUS_PORT:-19090}:9090"
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${PROMETHEUS_NETWORK_ADDRESS:-172.28.0.10}
|
||||
prometheus:
|
||||
image: prom/prometheus
|
||||
container_name: prometheus
|
||||
hostname: prometheus
|
||||
restart: always
|
||||
volumes:
|
||||
- ./config/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- ./config/instance-down-rules.yml:/etc/prometheus/instance-down-rules.yml
|
||||
ports:
|
||||
- "${PROMETHEUS_PORT}:9090"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${PROMETHEUS_NETWORK_ADDRESS}
|
||||
|
||||
# alertmanager:
|
||||
# image: prom/alertmanager
|
||||
# container_name: alertmanager
|
||||
# hostname: alertmanager
|
||||
# restart: always
|
||||
# volumes:
|
||||
# - ./config/alertmanager.yml:/etc/alertmanager/alertmanager.yml
|
||||
# - ./config/email.tmpl:/etc/alertmanager/email.tmpl
|
||||
# ports:
|
||||
# - "${ALERT_MANAGER_PORT:-19093}:9093"
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${ALERT_MANAGER_NETWORK_ADDRESS:-172.28.0.14}
|
||||
alertmanager:
|
||||
image: prom/alertmanager
|
||||
container_name: alertmanager
|
||||
hostname: alertmanager
|
||||
restart: always
|
||||
volumes:
|
||||
- ./config/alertmanager.yml:/etc/alertmanager/alertmanager.yml
|
||||
- ./config/email.tmpl:/etc/alertmanager/email.tmpl
|
||||
ports:
|
||||
- "${ALERT_MANAGER_PORT}:9093"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${ALERT_MANAGER_NETWORK_ADDRESS}
|
||||
|
||||
# grafana:
|
||||
# image: grafana/grafana
|
||||
# container_name: grafana
|
||||
# hostname: grafana
|
||||
# user: root
|
||||
# restart: always
|
||||
# ports:
|
||||
# - "${GRAFANA_PORT:-13000}:3000"
|
||||
# volumes:
|
||||
# - ${DATA_DIR:-./}/components/grafana:/var/lib/grafana
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${GRAFANA_NETWORK_ADDRESS:-172.28.0.11}
|
||||
grafana:
|
||||
image: grafana/grafana
|
||||
container_name: grafana
|
||||
hostname: grafana
|
||||
user: root
|
||||
restart: always
|
||||
ports:
|
||||
- "${GRAFANA_PORT}:3000"
|
||||
volumes:
|
||||
- ${DATA_DIR}/components/grafana:/var/lib/grafana
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${GRAFANA_NETWORK_ADDRESS}
|
||||
|
||||
# node-exporter:
|
||||
# image: quay.io/prometheus/node-exporter
|
||||
# container_name: node-exporter
|
||||
# hostname: node-exporter
|
||||
# restart: always
|
||||
# ports:
|
||||
# - "${NODE_EXPORTER_PORT:-19100}:9100"
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${NODE_EXPORTER_NETWORK_ADDRESS:-172.28.0.12}
|
||||
node-exporter:
|
||||
image: quay.io/prometheus/node-exporter
|
||||
container_name: node-exporter
|
||||
hostname: node-exporter
|
||||
restart: always
|
||||
ports:
|
||||
- "${NODE_EXPORTER_PORT}:9100"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${NODE_EXPORTER_NETWORK_ADDRESS}
|
||||
|
||||
@@ -2,28 +2,28 @@
|
||||
# Each line is a file pattern followed by one or more owners.
|
||||
|
||||
# README files
|
||||
README.md @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
README.md @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
|
||||
# Contributing guidelines
|
||||
CONTRIBUTING.md @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
CONTRIBUTING.md @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
|
||||
# License files
|
||||
LICENSE @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
LICENSE @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
|
||||
# Makefile
|
||||
Makefile @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
Makefile @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
|
||||
# These owners will be the default owners for everything in
|
||||
# the repo. Unless a later match takes precedence,
|
||||
# @cubxxw and @openimsdk/bot will be requested for
|
||||
# review when someone opens a pull request.
|
||||
* @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
* @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
|
||||
# Order is important; the last matching pattern takes the most
|
||||
# precedence. When someone opens a pull request that only
|
||||
# modifies JS files, only @js-owner and not the global
|
||||
# owner(s) will be requested for a review.
|
||||
*.js @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
*.js @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
|
||||
# You can also use email addresses if you prefer. They'll be
|
||||
# used to look up users just like we do for commit author
|
||||
@@ -35,7 +35,7 @@ Makefile @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiam
|
||||
# be identified in the format @org/team-name. Teams must have
|
||||
# explicit write access to the repository. In this example,
|
||||
# the OpenIMSDK team in the github organization owns all .txt files.
|
||||
*.txt @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
*.txt @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
|
||||
# The `docs/*` pattern will match files like
|
||||
# `docs/getting-started.md` but not further nested files like
|
||||
|
||||
@@ -11,7 +11,7 @@ OpenIM, an intricate project, requires a robust logging mechanism to diagnose is
|
||||
1. **Initialization**: The system begins by determining the verbosity level through the `OPENIM_VERBOSE` variable. If it's not set, a default value of 5 is assigned. This verbosity level dictates the depth of the log details.
|
||||
2. **Log File Setup**: Logs are stored in the directory specified by `OPENIM_OUTPUT`. If this variable isn't explicitly set, it defaults to the `_output` directory relative to the script location. Each log file is named based on the date to facilitate easy identification.
|
||||
3. **Logging Function**: The `echo_log()` function plays a pivotal role by writing messages to both the console (stdout) and the log file.
|
||||
4. **Logging to a file**: The `echo_log()` function writes to the log file by appending the message to the file. It also adds a timestamp to the message. path: `_output/logs/*`, Enable logging by default. Set to false to disable. If you wish to turn off output to log files set `export ENABLE_LOGGING=flase`.
|
||||
4. **Logging to a file**: The `echo_log()` function writes to the log file by appending the message to the file. It also adds a timestamp to the message. path: `_output/logs/*`, Enable logging by default. Set to false to disable. If you wish to turn off output to log files set `ENABLE_LOGGING=flase`.
|
||||
|
||||
### Key Functions & Their Usages
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
* 2.20. [Prometheus Configuration](#PrometheusConfiguration-1)
|
||||
* 2.20.1. [General Configuration](#GeneralConfiguration)
|
||||
* 2.20.2. [Service-Specific Prometheus Ports](#Service-SpecificPrometheusPorts)
|
||||
* 2.21. [Qiniu Cloud Kodo Configuration](#QiniuCloudKODOConfiguration)
|
||||
|
||||
## 0. <a name='TableofContents'></a>OpenIM Config File
|
||||
|
||||
@@ -296,6 +295,19 @@ Feel free to explore the MinIO documentation for more advanced configurations an
|
||||
| `ZOOKEEPER_USERNAME` | `""` | Username for Zookeeper. |
|
||||
| `ZOOKEEPER_PASSWORD` | `""` | Password for Zookeeper. |
|
||||
|
||||
### 2.6. <a name='MySQLConfiguration'></a>MySQL Configuration
|
||||
|
||||
**Description**: Configuration for MySQL, including port, address, and credentials.
|
||||
|
||||
| Parameter | Example Value | Description |
|
||||
| ---------------- | ------------------------ | ------------------- |
|
||||
| `MYSQL_PORT` | `"13306"` | Port for MySQL. |
|
||||
| `MYSQL_ADDRESS` | Docker Bridge Gateway IP | Address for MySQL. |
|
||||
| `MYSQL_USERNAME` | User-defined | Username for MySQL. |
|
||||
| `MYSQL_PASSWORD` | User-defined | Password for MySQL. |
|
||||
|
||||
Note: The configurations for other services (e.g., MONGO, REDIS, KAFKA, etc.) follow a similar pattern to MySQL and can be documented in a similar manner.
|
||||
|
||||
### 2.7. <a name='MongoDBConfiguration'></a>MongoDB Configuration
|
||||
|
||||
This section involves setting up MongoDB, including its port, address, and credentials.
|
||||
@@ -454,7 +466,7 @@ This section involves configuring the log settings, including storage location,
|
||||
This section involves setting up additional configuration variables for Websocket, Push Notifications, and Chat.
|
||||
|
||||
| Parameter | Example Value | Description |
|
||||
|-------------------------|-------------------|------------------------------------|
|
||||
| ----------------------- | ----------------- | ---------------------------------- |
|
||||
| WEBSOCKET_MAX_CONN_NUM | "100000" | Maximum Websocket connections |
|
||||
| WEBSOCKET_MAX_MSG_LEN | "4096" | Maximum Websocket message length |
|
||||
| WEBSOCKET_TIMEOUT | "10" | Websocket timeout |
|
||||
@@ -488,9 +500,9 @@ This section involves setting up additional configuration variables for Websocke
|
||||
| TOKEN_EXPIRE | "90" | Token Expiry Time |
|
||||
| FRIEND_VERIFY | "false" | Friend Verification Enable |
|
||||
| IOS_PUSH_SOUND | "xxx" | iOS |
|
||||
| CALLBACK_ENABLE | "false" | Enable callback |
|
||||
| CALLBACK_TIMEOUT | "5" | Maximum timeout for callback call |
|
||||
| CALLBACK_FAILED_CONTINUE| "true" | fails to continue to the next step |
|
||||
|
||||
|
||||
|
||||
### 2.20. <a name='PrometheusConfiguration-1'></a>Prometheus Configuration
|
||||
|
||||
This section involves configuring Prometheus, including enabling/disabling it and setting up ports for various services.
|
||||
@@ -516,18 +528,3 @@ This section involves configuring Prometheus, including enabling/disabling it an
|
||||
| RTC Service | `RTC_PROM_PORT` | '21300' | Prometheus port for the RTC service. |
|
||||
| Third Service | `THIRD_PROM_PORT` | '21301' | Prometheus port for the Third service. |
|
||||
| Message Transfer Service | `MSG_TRANSFER_PROM_PORT` | '21400, 21401, 21402, 21403' | Prometheus ports for the Message Transfer service. |
|
||||
|
||||
|
||||
### 2.21. <a name='QiniuCloudKODOConfiguration'></a>Qiniu Cloud Kodo Configuration
|
||||
|
||||
This section involves setting up Qiniu Cloud Kodo, including its endpoint, bucket name, and credentials.
|
||||
|
||||
| Parameter | Example Value | Description |
|
||||
| --------------------- | ------------------------------------------------------------ | ---------------------------------------- |
|
||||
| KODO_ENDPOINT | "[http://s3.cn-east-1.qiniucs.com](http://s3.cn-east-1.qiniucs.com)" | Endpoint URL for Qiniu Cloud Kodo. |
|
||||
| KODO_BUCKET | "demo-9999999" | Bucket name for Qiniu Cloud Kodo. |
|
||||
| KODO_BUCKET_URL | "[http://your.domain.com](http://your.domain.com)" | Bucket URL for Qiniu Cloud Kodo. |
|
||||
| KODO_ACCESS_KEY_ID | [User Defined] | Access key ID for Qiniu Cloud Kodo. |
|
||||
| KODO_ACCESS_KEY_SECRET | [User Defined] | Access key secret for Qiniu Cloud Kodo. |
|
||||
| KODO_SESSION_TOKEN | [User Defined] | Session token for Qiniu Cloud Kodo. |
|
||||
| KODO_PUBLIC_READ | "false" | Public read access. |
|
||||
|
||||
@@ -30,7 +30,7 @@ Executing `make tools` ensures verification and installation of the default tool
|
||||
- go-junit-report
|
||||
- go-gitlint
|
||||
|
||||
The installation path is situated at `./_output/tools/`.
|
||||
The installation path is situated at `/root/workspaces/openim/Open-IM-Server/_output/tools/`.
|
||||
|
||||
## Toolset Categories
|
||||
|
||||
|
||||
14
go.mod
14
go.mod
@@ -4,16 +4,16 @@ go 1.19
|
||||
|
||||
require (
|
||||
firebase.google.com/go v3.13.0+incompatible
|
||||
github.com/OpenIMSDK/protocol v0.0.31
|
||||
github.com/OpenIMSDK/tools v0.0.20
|
||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||
github.com/dtm-labs/rockscache v0.1.1
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-playground/validator/v10 v10.15.5
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.63
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
@@ -29,14 +29,19 @@ require (
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.5.2
|
||||
gorm.io/gorm v1.25.5
|
||||
)
|
||||
|
||||
require github.com/google/uuid v1.3.1
|
||||
|
||||
require (
|
||||
github.com/IBM/sarama v1.41.3
|
||||
github.com/OpenIMSDK/protocol v0.0.31
|
||||
github.com/OpenIMSDK/tools v0.0.16
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/redis/go-redis/v9 v9.2.1
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.45
|
||||
go.uber.org/automaxprocs v1.5.3
|
||||
@@ -70,7 +75,6 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-zookeeper/zk v1.0.3 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
@@ -87,7 +91,6 @@ require (
|
||||
github.com/jcmturner/gofork v1.7.6 // indirect
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||
github.com/jinzhu/copier v0.3.5 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -130,7 +133,7 @@ require (
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.13.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
@@ -140,7 +143,6 @@ require (
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gorm.io/gorm v1.23.8 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
23
go.sum
23
go.sum
@@ -20,8 +20,8 @@ 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/OpenIMSDK/protocol v0.0.31 h1:ax43x9aqA6EKNXNukS5MT5BSTqkUmwO4uTvbJLtzCgE=
|
||||
github.com/OpenIMSDK/protocol v0.0.31/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||
github.com/OpenIMSDK/tools v0.0.20 h1:zBTjQZRJ5lR1FIzP9mtWyAvh5dKsmJXQugi4p8X/97k=
|
||||
github.com/OpenIMSDK/tools v0.0.20/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
||||
github.com/OpenIMSDK/tools v0.0.16 h1:te/GIq2imCMsrRPgU9OObYKbzZ3rT08Lih/o+3QFIz0=
|
||||
github.com/OpenIMSDK/tools v0.0.16/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
@@ -100,6 +100,9 @@ github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7N
|
||||
github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
|
||||
github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
|
||||
@@ -190,11 +193,10 @@ github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
|
||||
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
|
||||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
||||
@@ -436,8 +438,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@@ -529,8 +531,11 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
|
||||
gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
|
||||
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
|
||||
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
1
go.work
1
go.work
@@ -13,5 +13,4 @@ use (
|
||||
./tools/component
|
||||
./tools/url2im
|
||||
./tools/data-conversion
|
||||
./tools/up35
|
||||
)
|
||||
|
||||
14
install.sh
14
install.sh
@@ -63,7 +63,7 @@ PROXY=
|
||||
GITHUB_TOKEN=
|
||||
|
||||
# Default user is "root". If you need to modify it, uncomment and replace accordingly.
|
||||
# OPENIM_USER=root
|
||||
# USER=root
|
||||
|
||||
# Default password for redis, mysql, mongo, as well as accessSecret in config/config.yaml.
|
||||
# Remember, it should be a combination of 8 or more numbers and letters. If you want to set a different password, uncomment and replace "openIM123".
|
||||
@@ -244,10 +244,10 @@ function download_source_code() {
|
||||
function set_openim_env() {
|
||||
warn "This command can only be executed once. It will modify the component passwords in docker-compose based on the PASSWORD variable in .env, and modify the component passwords in config/config.yaml. If the password in .env changes, you need to first execute docker-compose down; rm components -rf and then execute this command."
|
||||
# Set default values for user input
|
||||
# If the OPENIM_USER environment variable is not set, it defaults to 'root'
|
||||
if [ -z "$OPENIM_USER" ]; then
|
||||
OPENIM_USER="root"
|
||||
debug "OPENIM_USER is not set. Defaulting to 'root'."
|
||||
# If the USER environment variable is not set, it defaults to 'root'
|
||||
if [ -z "$USER" ]; then
|
||||
USER="root"
|
||||
debug "USER is not set. Defaulting to 'root'."
|
||||
fi
|
||||
|
||||
# If the PASSWORD environment variable is not set, it defaults to 'openIM123'
|
||||
@@ -321,7 +321,7 @@ function cmd_help() {
|
||||
|
||||
function parseinput() {
|
||||
# set default values
|
||||
# OPENIM_USER=root
|
||||
# USER=root
|
||||
# PASSWORD=openIM123
|
||||
# ENDPOINT=http://127.0.0.1:10005
|
||||
# API=http://127.0.0.1:10002/object/
|
||||
@@ -347,7 +347,7 @@ function parseinput() {
|
||||
;;
|
||||
-u|--user)
|
||||
shift
|
||||
OPENIM_USER=$1
|
||||
USER=$1
|
||||
;;
|
||||
-p|--password)
|
||||
shift
|
||||
|
||||
176
install_guide.sh
Executable file
176
install_guide.sh
Executable file
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Welcome to the Open-IM-Server installation scripts."
|
||||
echo "Please select an deploy option:"
|
||||
echo "1. docker-compose install"
|
||||
echo "2. exit"
|
||||
|
||||
clear_openimlog() {
|
||||
rm -rf ./logs/*
|
||||
}
|
||||
|
||||
is_path() {
|
||||
if [ -e "$1" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
is_empty() {
|
||||
if [ -z "$1" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
is_directory_exists() {
|
||||
if [ -d "$1" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
edit_config() {
|
||||
echo "Is edit config.yaml?"
|
||||
echo "1. vi edit config"
|
||||
echo "2. do not edit config"
|
||||
read choice
|
||||
case $choice in
|
||||
1)
|
||||
vi config/config.yaml
|
||||
;;
|
||||
2)
|
||||
echo "do not edit config"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
edit_enterprise_config() {
|
||||
echo "Is edit enterprise config.yaml?"
|
||||
echo "1. vi edit enterprise config"
|
||||
echo "2. do not edit enterprise config"
|
||||
read choice
|
||||
case $choice in
|
||||
1)
|
||||
vi ./.docker-compose_cfg/config.yaml
|
||||
;;
|
||||
2)
|
||||
echo "Do not edit enterprise config"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_docker_compose() {
|
||||
echo "Please input the installation path, default is $(pwd)/Open-IM-Server, press enter to use default"
|
||||
read install_path
|
||||
is_empty $install_path
|
||||
if [ $? -eq 1 ]; then
|
||||
install_path="."
|
||||
fi
|
||||
echo "Installing Open-IM-Server to ${install_path}/Open-IM-Server..."
|
||||
is_path $install_path
|
||||
mkdir -p $install_path
|
||||
cd $install_path
|
||||
is_directory_exists "${install_path}/Open-IM-Server"
|
||||
if [ $? -eq 1 ]; then
|
||||
echo "WARNING: Directory $install_path/Open-IM-Server exist, please ensure your path"
|
||||
echo "1. delete the directory and install"
|
||||
echo "2. exit"
|
||||
read choice
|
||||
case $choice in
|
||||
1)
|
||||
rm -rf "${install_path}/Open-IM-Server"
|
||||
;;
|
||||
2)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
rm -rf ./Open-IM-Server
|
||||
set -e
|
||||
git clone https://github.com/openimsdk/open-im-server.git --recursive;
|
||||
set +e
|
||||
cd ./Open-IM-Server
|
||||
git checkout errcode
|
||||
echo "======== git clone success ========"
|
||||
source .env
|
||||
if [ $DATA_DIR = "./" ]; then
|
||||
DATA_DIR=$(pwd)/components
|
||||
fi
|
||||
echo "Please input the components data directory, deault is ${DATA_DIR}, press enter to use default"
|
||||
read NEW_DATA_DIR
|
||||
is_empty $NEW_DATA_DIR
|
||||
if [ $? -eq 0 ]; then
|
||||
DATA_DIR=$NEW_DATA_DIR
|
||||
fi
|
||||
echo "Please input the user, deault is root, press enter to use default"
|
||||
read NEW_USER
|
||||
is_empty $NEW_USER
|
||||
if [ $? -eq 0 ]; then
|
||||
USER=$NEW_USER
|
||||
fi
|
||||
|
||||
echo "Please input the password, default is openIM123, press enter to use default"
|
||||
read NEW_PASSWORD
|
||||
is_empty $NEW_PASSWORD
|
||||
if [ $? -eq 0 ]; then
|
||||
PASSWORD=$NEW_PASSWORD
|
||||
fi
|
||||
|
||||
echo "Please input the minio_endpoint, default will detect auto, press enter to use default"
|
||||
read NEW_MINIO_ENDPOINT
|
||||
is_empty $NEW_MINIO_ENDPOINT
|
||||
if [ $? -eq 1 ]; then
|
||||
internet_ip=`curl ifconfig.me -s`
|
||||
MINIO_ENDPOINT="http://${internet_ip}:10005"
|
||||
else
|
||||
MINIO_ENDPOINT=$NEW_MINIO_ENDPOINT
|
||||
fi
|
||||
set -e
|
||||
export MINIO_ENDPOINT
|
||||
export USER
|
||||
export PASSWORD
|
||||
export DATA_DIR
|
||||
|
||||
cat <<EOF > .env
|
||||
USER=${USER}
|
||||
PASSWORD=${PASSWORD}
|
||||
MINIO_ENDPOINT=${MINIO_ENDPOINT}
|
||||
DATA_DIR=${DATA_DIR}
|
||||
EOF
|
||||
|
||||
edit_config
|
||||
edit_enterprise_config
|
||||
|
||||
cd scripts;
|
||||
chmod +x *.sh;
|
||||
./init-pwd.sh;
|
||||
./env_check.sh;
|
||||
cd ..;
|
||||
docker-compose up -d;
|
||||
cd scripts;
|
||||
./docker-check-service.sh;
|
||||
}
|
||||
|
||||
read choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
install_docker_compose
|
||||
;;
|
||||
2)
|
||||
|
||||
;;
|
||||
3)
|
||||
;;
|
||||
4)
|
||||
echo "Exiting installation scripts..."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option, please try again."
|
||||
;;
|
||||
esac
|
||||
@@ -15,6 +15,14 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/protocol/msg"
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
@@ -22,14 +30,7 @@ import (
|
||||
"github.com/OpenIMSDK/tools/apiresp"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||
@@ -151,7 +152,7 @@ func (m *MessageApi) DeleteMsgPhysical(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendMsgReq *msg.SendMsgReq, err error) {
|
||||
var data any
|
||||
var data interface{}
|
||||
log.ZDebug(c, "getSendMsgReq", "req", req.Content)
|
||||
switch req.ContentType {
|
||||
case constant.Text:
|
||||
|
||||
@@ -37,7 +37,7 @@ func CallbackUserOnline(ctx context.Context, userID string, platformID int, isAp
|
||||
req := cbapi.CallbackUserOnlineReq{
|
||||
UserStatusCallbackReq: cbapi.UserStatusCallbackReq{
|
||||
UserStatusBaseCallback: cbapi.UserStatusBaseCallback{
|
||||
CallbackCommand: cbapi.CallbackUserOnlineCommand,
|
||||
CallbackCommand: constant.CallbackUserOnlineCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
PlatformID: platformID,
|
||||
Platform: constant.PlatformIDToName(platformID),
|
||||
@@ -49,10 +49,7 @@ func CallbackUserOnline(ctx context.Context, userID string, platformID int, isAp
|
||||
ConnID: connID,
|
||||
}
|
||||
resp := cbapi.CommonCallbackResp{}
|
||||
if err := http.CallBackPostReturn(ctx, callBackURL(), &req, &resp, config.Config.Callback.CallbackUserOnline); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return http.CallBackPostReturn(ctx, callBackURL(), &req, &resp, config.Config.Callback.CallbackUserOnline)
|
||||
}
|
||||
|
||||
func CallbackUserOffline(ctx context.Context, userID string, platformID int, connID string) error {
|
||||
@@ -62,7 +59,7 @@ func CallbackUserOffline(ctx context.Context, userID string, platformID int, con
|
||||
req := &cbapi.CallbackUserOfflineReq{
|
||||
UserStatusCallbackReq: cbapi.UserStatusCallbackReq{
|
||||
UserStatusBaseCallback: cbapi.UserStatusBaseCallback{
|
||||
CallbackCommand: cbapi.CallbackUserOfflineCommand,
|
||||
CallbackCommand: constant.CallbackUserOfflineCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
PlatformID: platformID,
|
||||
Platform: constant.PlatformIDToName(platformID),
|
||||
@@ -73,10 +70,7 @@ func CallbackUserOffline(ctx context.Context, userID string, platformID int, con
|
||||
ConnID: connID,
|
||||
}
|
||||
resp := &cbapi.CallbackUserOfflineResp{}
|
||||
if err := http.CallBackPostReturn(ctx, callBackURL(), req, resp, config.Config.Callback.CallbackUserOffline); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return http.CallBackPostReturn(ctx, callBackURL(), req, resp, config.Config.Callback.CallbackUserOffline)
|
||||
}
|
||||
|
||||
func CallbackUserKickOff(ctx context.Context, userID string, platformID int) error {
|
||||
@@ -86,7 +80,7 @@ func CallbackUserKickOff(ctx context.Context, userID string, platformID int) err
|
||||
req := &cbapi.CallbackUserKickOffReq{
|
||||
UserStatusCallbackReq: cbapi.UserStatusCallbackReq{
|
||||
UserStatusBaseCallback: cbapi.UserStatusBaseCallback{
|
||||
CallbackCommand: cbapi.CallbackUserKickOffCommand,
|
||||
CallbackCommand: constant.CallbackUserKickOffCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
PlatformID: platformID,
|
||||
Platform: constant.PlatformIDToName(platformID),
|
||||
@@ -96,10 +90,7 @@ func CallbackUserKickOff(ctx context.Context, userID string, platformID int) err
|
||||
Seq: time.Now().UnixMilli(),
|
||||
}
|
||||
resp := &cbapi.CommonCallbackResp{}
|
||||
if err := http.CallBackPostReturn(ctx, callBackURL(), req, resp, config.Config.Callback.CallbackUserOffline); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return http.CallBackPostReturn(ctx, callBackURL(), req, resp, config.Config.Callback.CallbackUserOffline)
|
||||
}
|
||||
|
||||
// func callbackUserOnline(operationID, userID string, platformID int, token string, isAppBackground bool, connID
|
||||
|
||||
@@ -22,8 +22,8 @@ import (
|
||||
)
|
||||
|
||||
type Encoder interface {
|
||||
Encode(data any) ([]byte, error)
|
||||
Decode(encodeData []byte, decodeData any) error
|
||||
Encode(data interface{}) ([]byte, error)
|
||||
Decode(encodeData []byte, decodeData interface{}) error
|
||||
}
|
||||
|
||||
type GobEncoder struct{}
|
||||
@@ -32,7 +32,7 @@ func NewGobEncoder() *GobEncoder {
|
||||
return &GobEncoder{}
|
||||
}
|
||||
|
||||
func (g *GobEncoder) Encode(data any) ([]byte, error) {
|
||||
func (g *GobEncoder) Encode(data interface{}) ([]byte, error) {
|
||||
buff := bytes.Buffer{}
|
||||
enc := gob.NewEncoder(&buff)
|
||||
err := enc.Encode(data)
|
||||
@@ -42,7 +42,7 @@ func (g *GobEncoder) Encode(data any) ([]byte, error) {
|
||||
return buff.Bytes(), nil
|
||||
}
|
||||
|
||||
func (g *GobEncoder) Decode(encodeData []byte, decodeData any) error {
|
||||
func (g *GobEncoder) Decode(encodeData []byte, decodeData interface{}) error {
|
||||
buff := bytes.NewBuffer(encodeData)
|
||||
dec := gob.NewDecoder(buff)
|
||||
err := dec.Decode(decodeData)
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
)
|
||||
@@ -44,22 +43,12 @@ func RunWsAndServer(rpcPort, wsPort, prometheusPort int) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hubServer := NewServer(rpcPort, prometheusPort, longServer)
|
||||
|
||||
wg := errgroup.Group{}
|
||||
wg.Go(func() error {
|
||||
err = hubServer.Start()
|
||||
go func() {
|
||||
err := hubServer.Start()
|
||||
if err != nil {
|
||||
return utils.Wrap1(err)
|
||||
panic(utils.Wrap1(err))
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
wg.Go(func() error {
|
||||
return hubServer.LongConnServer.Run()
|
||||
})
|
||||
|
||||
err = wg.Wait()
|
||||
return err
|
||||
}()
|
||||
return hubServer.LongConnServer.Run()
|
||||
}
|
||||
|
||||
@@ -18,12 +18,9 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
@@ -49,7 +46,7 @@ type LongConnServer interface {
|
||||
wsHandler(w http.ResponseWriter, r *http.Request)
|
||||
GetUserAllCons(userID string) ([]*Client, bool)
|
||||
GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool)
|
||||
Validate(s any) error
|
||||
Validate(s interface{}) error
|
||||
SetCacheHandler(cache cache.MsgModel)
|
||||
SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry)
|
||||
KickUserConn(client *Client) error
|
||||
@@ -60,12 +57,6 @@ type LongConnServer interface {
|
||||
MessageHandler
|
||||
}
|
||||
|
||||
var bufferPool = sync.Pool{
|
||||
New: func() any {
|
||||
return make([]byte, 1024)
|
||||
},
|
||||
}
|
||||
|
||||
type WsServer struct {
|
||||
port int
|
||||
wsMaxConnNum int64
|
||||
@@ -126,8 +117,7 @@ func (ws *WsServer) UnRegister(c *Client) {
|
||||
ws.unregisterChan <- c
|
||||
}
|
||||
|
||||
func (ws *WsServer) Validate(s any) error {
|
||||
//?question?
|
||||
func (ws *WsServer) Validate(s interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -151,7 +141,7 @@ func NewWsServer(opts ...Option) (*WsServer, error) {
|
||||
writeBufferSize: config.writeBufferSize,
|
||||
handshakeTimeout: config.handshakeTimeout,
|
||||
clientPool: sync.Pool{
|
||||
New: func() any {
|
||||
New: func() interface{} {
|
||||
return new(Client)
|
||||
},
|
||||
},
|
||||
@@ -166,22 +156,10 @@ func NewWsServer(opts ...Option) (*WsServer, error) {
|
||||
}
|
||||
|
||||
func (ws *WsServer) Run() error {
|
||||
var (
|
||||
client *Client
|
||||
wg errgroup.Group
|
||||
|
||||
sigs = make(chan os.Signal, 1)
|
||||
done = make(chan struct{}, 1)
|
||||
)
|
||||
|
||||
server := http.Server{Addr: ":" + utils.IntToString(ws.port), Handler: nil}
|
||||
|
||||
wg.Go(func() error {
|
||||
var client *Client
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return nil
|
||||
|
||||
case client = <-ws.registerChan:
|
||||
ws.registerClient(client)
|
||||
case client = <-ws.unregisterChan:
|
||||
@@ -190,34 +168,10 @@ func (ws *WsServer) Run() error {
|
||||
ws.multiTerminalLoginChecker(onlineInfo.clientOK, onlineInfo.oldClients, onlineInfo.newClient)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
wg.Go(func() error {
|
||||
http.HandleFunc("/", ws.wsHandler)
|
||||
return server.ListenAndServe()
|
||||
})
|
||||
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
||||
<-sigs
|
||||
|
||||
go func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// graceful exit operation for server
|
||||
_ = server.Shutdown(ctx)
|
||||
_ = wg.Wait()
|
||||
close(done)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
return nil
|
||||
|
||||
case <-time.After(15 * time.Second):
|
||||
return utils.Wrap1(errors.New("timeout exit"))
|
||||
}
|
||||
|
||||
http.HandleFunc("/", ws.wsHandler)
|
||||
// http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) {})
|
||||
return http.ListenAndServe(":"+utils.IntToString(ws.port), nil) // Start listening
|
||||
}
|
||||
|
||||
var concurrentRequest = 3
|
||||
|
||||
@@ -31,6 +31,8 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||
@@ -38,12 +40,20 @@ import (
|
||||
)
|
||||
|
||||
type MsgTransfer struct {
|
||||
persistentCH *PersistentConsumerHandler // 聊天记录持久化到mysql的消费者 订阅的topic: ws2ms_chat
|
||||
historyCH *OnlineHistoryRedisConsumerHandler // 这个消费者聚合消息, 订阅的topic:ws2ms_chat, 修改通知发往msg_to_modify topic, 消息存入redis后Incr Redis, 再发消息到ms2pschat topic推送, 发消息到msg_to_mongo topic持久化
|
||||
historyMongoCH *OnlineHistoryMongoConsumerHandler // mongoDB批量插入, 成功后删除redis中消息,以及处理删除通知消息删除的 订阅的topic: msg_to_mongo
|
||||
// modifyCH *ModifyMsgConsumerHandler // 负责消费修改消息通知的consumer, 订阅的topic: msg_to_modify
|
||||
}
|
||||
|
||||
func StartTransfer(prometheusPort int) error {
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&relationtb.ChatLogModel{}); err != nil {
|
||||
fmt.Printf("gorm: AutoMigrate ChatLogModel err: %v\n", err)
|
||||
}
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -69,16 +79,21 @@ func StartTransfer(prometheusPort int) error {
|
||||
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
msgModel := cache.NewMsgCacheModel(rdb)
|
||||
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
|
||||
msgMysModel := relation.NewChatLogGorm(db)
|
||||
chatLogDatabase := controller.NewChatLogDatabase(msgMysModel)
|
||||
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, msgModel)
|
||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
||||
msgTransfer := NewMsgTransfer(msgDatabase, &conversationRpcClient, &groupRpcClient)
|
||||
msgTransfer := NewMsgTransfer(chatLogDatabase, msgDatabase, &conversationRpcClient, &groupRpcClient)
|
||||
return msgTransfer.Start(prometheusPort)
|
||||
}
|
||||
|
||||
func NewMsgTransfer(msgDatabase controller.CommonMsgDatabase, conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) *MsgTransfer {
|
||||
func NewMsgTransfer(chatLogDatabase controller.ChatLogDatabase,
|
||||
msgDatabase controller.CommonMsgDatabase,
|
||||
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient,
|
||||
) *MsgTransfer {
|
||||
return &MsgTransfer{
|
||||
historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient),
|
||||
persistentCH: NewPersistentConsumerHandler(chatLogDatabase), historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient),
|
||||
historyMongoCH: NewOnlineHistoryMongoConsumerHandler(msgDatabase),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ type TriggerChannelValue struct {
|
||||
|
||||
type Cmd2Value struct {
|
||||
Cmd int
|
||||
Value any
|
||||
Value interface{}
|
||||
}
|
||||
type ContextMsg struct {
|
||||
message *sdkws.MsgData
|
||||
@@ -252,10 +252,7 @@ func (och *OnlineHistoryRedisConsumerHandler) handleNotification(
|
||||
return
|
||||
}
|
||||
log.ZDebug(ctx, "success to next topic", "conversationID", conversationID)
|
||||
err = och.msgDatabase.MsgToMongoMQ(ctx, key, conversationID, storageList, lastSeq)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "MsgToMongoMQ error", err)
|
||||
}
|
||||
och.msgDatabase.MsgToMongoMQ(ctx, key, conversationID, storageList, lastSeq)
|
||||
och.toPushTopic(ctx, key, conversationID, storageList)
|
||||
}
|
||||
}
|
||||
@@ -280,6 +277,9 @@ func (och *OnlineHistoryRedisConsumerHandler) handleMsg(
|
||||
lastSeq, isNewConversation, err := och.msgDatabase.BatchInsertChat2Cache(ctx, conversationID, storageList)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
log.ZError(ctx, "batch data insert to redis err", err, "storageMsgList", storageList)
|
||||
och.singleMsgFailedCountMutex.Lock()
|
||||
och.singleMsgFailedCount += uint64(len(storageList))
|
||||
och.singleMsgFailedCountMutex.Unlock()
|
||||
return
|
||||
}
|
||||
if isNewConversation {
|
||||
@@ -311,10 +311,10 @@ func (och *OnlineHistoryRedisConsumerHandler) handleMsg(
|
||||
}
|
||||
|
||||
log.ZDebug(ctx, "success incr to next topic")
|
||||
err = och.msgDatabase.MsgToMongoMQ(ctx, key, conversationID, storageList, lastSeq)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "MsgToMongoMQ error", err)
|
||||
}
|
||||
och.singleMsgSuccessCountMutex.Lock()
|
||||
och.singleMsgSuccessCount += uint64(len(storageList))
|
||||
och.singleMsgSuccessCountMutex.Unlock()
|
||||
och.msgDatabase.MsgToMongoMQ(ctx, key, conversationID, storageList, lastSeq)
|
||||
och.toPushTopic(ctx, key, conversationID, storageList)
|
||||
}
|
||||
}
|
||||
|
||||
119
internal/msgtransfer/persistent_msg_handler.go
Normal file
119
internal/msgtransfer/persistent_msg_handler.go
Normal file
@@ -0,0 +1,119 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package msgtransfer
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
kfk "github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
|
||||
|
||||
"github.com/IBM/sarama"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type PersistentConsumerHandler struct {
|
||||
persistentConsumerGroup *kfk.MConsumerGroup
|
||||
chatLogDatabase controller.ChatLogDatabase
|
||||
}
|
||||
|
||||
func NewPersistentConsumerHandler(database controller.ChatLogDatabase) *PersistentConsumerHandler {
|
||||
return &PersistentConsumerHandler{
|
||||
persistentConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
||||
KafkaVersion: sarama.V2_0_0_0,
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
|
||||
}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
|
||||
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMySql),
|
||||
chatLogDatabase: database,
|
||||
}
|
||||
}
|
||||
|
||||
func (pc *PersistentConsumerHandler) handleChatWs2Mysql(
|
||||
ctx context.Context,
|
||||
cMsg *sarama.ConsumerMessage,
|
||||
msgKey string,
|
||||
_ sarama.ConsumerGroupSession,
|
||||
) {
|
||||
msg := cMsg.Value
|
||||
var tag bool
|
||||
msgFromMQ := pbmsg.MsgDataToMQ{}
|
||||
err := proto.Unmarshal(msg, &msgFromMQ)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "msg_transfer Unmarshal msg err", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.ZDebug(ctx, "handleChatWs2Mysql", "msg", msgFromMQ.MsgData)
|
||||
// Control whether to store history messages (mysql)
|
||||
isPersist := utils.GetSwitchFromOptions(msgFromMQ.MsgData.Options, constant.IsPersistent)
|
||||
// Only process receiver data
|
||||
if isPersist {
|
||||
switch msgFromMQ.MsgData.SessionType {
|
||||
case constant.SingleChatType, constant.NotificationChatType:
|
||||
if msgKey == msgFromMQ.MsgData.RecvID {
|
||||
tag = true
|
||||
}
|
||||
case constant.GroupChatType:
|
||||
if msgKey == msgFromMQ.MsgData.SendID {
|
||||
tag = true
|
||||
}
|
||||
case constant.SuperGroupChatType:
|
||||
tag = true
|
||||
}
|
||||
if tag {
|
||||
log.ZInfo(ctx, "msg_transfer msg persisting", "msg", string(msg))
|
||||
if err = pc.chatLogDatabase.CreateChatLog(&msgFromMQ); err != nil {
|
||||
log.ZError(ctx, "Message insert failed", err, "msg", msgFromMQ.String())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func (PersistentConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
func (PersistentConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
|
||||
func (pc *PersistentConsumerHandler) ConsumeClaim(
|
||||
sess sarama.ConsumerGroupSession,
|
||||
claim sarama.ConsumerGroupClaim,
|
||||
) error {
|
||||
for msg := range claim.Messages() {
|
||||
ctx := pc.persistentConsumerGroup.GetContextFromMsg(msg)
|
||||
log.ZDebug(
|
||||
ctx,
|
||||
"kafka get info to mysql",
|
||||
"msgTopic",
|
||||
msg.Topic,
|
||||
"msgPartition",
|
||||
msg.Partition,
|
||||
"msg",
|
||||
string(msg.Value),
|
||||
"key",
|
||||
string(msg.Key),
|
||||
)
|
||||
if len(msg.Value) != 0 {
|
||||
pc.handleChatWs2Mysql(ctx, msg, string(msg.Key), sess)
|
||||
} else {
|
||||
log.ZError(ctx, "msg get from kafka but is nil", nil, "key", msg.Key)
|
||||
}
|
||||
sess.MarkMessage(msg, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
@@ -43,7 +44,7 @@ func callbackOfflinePush(
|
||||
req := &callbackstruct.CallbackBeforePushReq{
|
||||
UserStatusBatchCallbackReq: callbackstruct.UserStatusBatchCallbackReq{
|
||||
UserStatusBaseCallback: callbackstruct.UserStatusBaseCallback{
|
||||
CallbackCommand: callbackstruct.CallbackOfflinePushCommand,
|
||||
CallbackCommand: constant.CallbackOfflinePushCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
PlatformID: int(msg.SenderPlatformID),
|
||||
Platform: constant.PlatformIDToName(int(msg.SenderPlatformID)),
|
||||
@@ -61,6 +62,9 @@ func callbackOfflinePush(
|
||||
}
|
||||
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||
if err := http.CallBackPostReturn(ctx, url(), req, resp, config.Config.Callback.CallbackOfflinePush); err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if len(resp.UserIDs) != 0 {
|
||||
@@ -79,7 +83,7 @@ func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgDat
|
||||
req := callbackstruct.CallbackBeforePushReq{
|
||||
UserStatusBatchCallbackReq: callbackstruct.UserStatusBatchCallbackReq{
|
||||
UserStatusBaseCallback: callbackstruct.UserStatusBaseCallback{
|
||||
CallbackCommand: callbackstruct.CallbackOnlinePushCommand,
|
||||
CallbackCommand: constant.CallbackOnlinePushCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
PlatformID: int(msg.SenderPlatformID),
|
||||
Platform: constant.PlatformIDToName(int(msg.SenderPlatformID)),
|
||||
@@ -95,10 +99,7 @@ func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgDat
|
||||
Content: GetContent(msg),
|
||||
}
|
||||
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||
if err := http.CallBackPostReturn(ctx, url(), req, resp, config.Config.Callback.CallbackOnlinePush); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return http.CallBackPostReturn(ctx, url(), req, resp, config.Config.Callback.CallbackOnlinePush)
|
||||
}
|
||||
|
||||
func callbackBeforeSuperGroupOnlinePush(
|
||||
@@ -112,7 +113,7 @@ func callbackBeforeSuperGroupOnlinePush(
|
||||
}
|
||||
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
|
||||
UserStatusBaseCallback: callbackstruct.UserStatusBaseCallback{
|
||||
CallbackCommand: callbackstruct.CallbackSuperGroupOnlinePushCommand,
|
||||
CallbackCommand: constant.CallbackSuperGroupOnlinePushCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
PlatformID: int(msg.SenderPlatformID),
|
||||
Platform: constant.PlatformIDToName(int(msg.SenderPlatformID)),
|
||||
@@ -128,9 +129,11 @@ func callbackBeforeSuperGroupOnlinePush(
|
||||
}
|
||||
resp := &callbackstruct.CallbackBeforeSuperGroupOnlinePushResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackBeforeSuperGroupOnlinePush); err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
if len(resp.UserIDs) != 0 {
|
||||
*pushToUserIDs = resp.UserIDs
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ import (
|
||||
)
|
||||
|
||||
type Resp struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data any `json:"data"`
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
func (r *Resp) parseError() (err error) {
|
||||
|
||||
@@ -159,7 +159,7 @@ func (g *Client) singlePush(ctx context.Context, token, userID string, pushReq P
|
||||
return g.request(ctx, pushURL, pushReq, token, nil)
|
||||
}
|
||||
|
||||
func (g *Client) request(ctx context.Context, url string, input any, token string, output any) error {
|
||||
func (g *Client) request(ctx context.Context, url string, input interface{}, token string, output interface{}) error {
|
||||
header := map[string]string{"token": token}
|
||||
resp := &Resp{}
|
||||
resp.Data = output
|
||||
@@ -170,7 +170,7 @@ func (g *Client) postReturn(
|
||||
ctx context.Context,
|
||||
url string,
|
||||
header map[string]string,
|
||||
input any,
|
||||
input interface{},
|
||||
output RespI,
|
||||
timeout int,
|
||||
) error {
|
||||
|
||||
@@ -23,7 +23,7 @@ const (
|
||||
)
|
||||
|
||||
type Audience struct {
|
||||
Object any
|
||||
Object interface{}
|
||||
audience map[string][]string
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
package body
|
||||
|
||||
type Message struct {
|
||||
MsgContent string `json:"msg_content"`
|
||||
Title string `json:"title,omitempty"`
|
||||
ContentType string `json:"content_type,omitempty"`
|
||||
Extras map[string]any `json:"extras,omitempty"`
|
||||
MsgContent string `json:"msg_content"`
|
||||
Title string `json:"title,omitempty"`
|
||||
ContentType string `json:"content_type,omitempty"`
|
||||
Extras map[string]interface{} `json:"extras,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Message) SetMsgContent(c string) {
|
||||
@@ -33,9 +33,9 @@ func (m *Message) SetContentType(c string) {
|
||||
m.ContentType = c
|
||||
}
|
||||
|
||||
func (m *Message) SetExtras(key string, value any) {
|
||||
func (m *Message) SetExtras(key string, value interface{}) {
|
||||
if m.Extras == nil {
|
||||
m.Extras = make(map[string]any)
|
||||
m.Extras = make(map[string]interface{})
|
||||
}
|
||||
m.Extras[key] = value
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ const (
|
||||
)
|
||||
|
||||
type Platform struct {
|
||||
Os any
|
||||
Os interface{}
|
||||
osArry []string
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
package body
|
||||
|
||||
type PushObj struct {
|
||||
Platform any `json:"platform"`
|
||||
Audience any `json:"audience"`
|
||||
Notification any `json:"notification,omitempty"`
|
||||
Message any `json:"message,omitempty"`
|
||||
Options any `json:"options,omitempty"`
|
||||
Platform interface{} `json:"platform"`
|
||||
Audience interface{} `json:"audience"`
|
||||
Notification interface{} `json:"notification,omitempty"`
|
||||
Message interface{} `json:"message,omitempty"`
|
||||
Options interface{} `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
func (p *PushObj) SetPlatform(pf *Platform) {
|
||||
|
||||
@@ -69,11 +69,11 @@ func (j *JPush) Push(ctx context.Context, userIDs []string, title, content strin
|
||||
pushObj.SetNotification(&no)
|
||||
pushObj.SetMessage(&msg)
|
||||
pushObj.SetOptions(&opt)
|
||||
var resp any
|
||||
var resp interface{}
|
||||
return j.request(ctx, pushObj, resp, 5)
|
||||
}
|
||||
|
||||
func (j *JPush) request(ctx context.Context, po body.PushObj, resp any, timeout int) error {
|
||||
func (j *JPush) request(ctx context.Context, po body.PushObj, resp interface{}, timeout int) error {
|
||||
return http2.PostReturn(
|
||||
ctx,
|
||||
config.Config.Push.Jpns.PushUrl,
|
||||
|
||||
@@ -18,8 +18,6 @@ import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
@@ -80,14 +78,7 @@ func (r *pushServer) PushMsg(ctx context.Context, pbData *pbpush.PushMsgReq) (re
|
||||
case constant.SuperGroupChatType:
|
||||
err = r.pusher.Push2SuperGroup(ctx, pbData.MsgData.GroupID, pbData.MsgData)
|
||||
default:
|
||||
var pushUserIDList []string
|
||||
isSenderSync := utils.GetSwitchFromOptions(pbData.MsgData.Options, constant.IsSenderSync)
|
||||
if !isSenderSync {
|
||||
pushUserIDList = append(pushUserIDList, pbData.MsgData.RecvID)
|
||||
} else {
|
||||
pushUserIDList = append(pushUserIDList, pbData.MsgData.RecvID, pbData.MsgData.SendID)
|
||||
}
|
||||
err = r.pusher.Push2User(ctx, pushUserIDList, pbData.MsgData)
|
||||
err = r.pusher.Push2User(ctx, []string{pbData.MsgData.RecvID, pbData.MsgData.SendID}, pbData.MsgData)
|
||||
}
|
||||
if err != nil {
|
||||
if err != errNoOfflinePusher {
|
||||
|
||||
@@ -133,7 +133,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pusher) UnmarshalNotificationElem(bytes []byte, t any) error {
|
||||
func (p *Pusher) UnmarshalNotificationElem(bytes []byte, t interface{}) error {
|
||||
var notification sdkws.NotificationElem
|
||||
if err := json.Unmarshal(bytes, ¬ification); err != nil {
|
||||
return err
|
||||
|
||||
@@ -16,12 +16,6 @@ package conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
@@ -30,11 +24,13 @@ import (
|
||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||
@@ -47,24 +43,24 @@ type conversationServer struct {
|
||||
}
|
||||
|
||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&tablerelation.ConversationModel{}); err != nil {
|
||||
return err
|
||||
}
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mongo, err := unrelation.NewMongo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conversationDB := relation.NewConversationGorm(db)
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
pbconversation.RegisterConversationServer(server, &conversationServer{
|
||||
conversationNotificationSender: notification.NewConversationNotificationSender(&msgRpcClient),
|
||||
groupRpcClient: &groupRpcClient,
|
||||
conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewMongo(mongo.GetClient())),
|
||||
conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewGorm(db)),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@@ -149,7 +145,7 @@ func (c *conversationServer) SetConversations(ctx context.Context,
|
||||
conversation.ConversationType = req.Conversation.ConversationType
|
||||
conversation.UserID = req.Conversation.UserID
|
||||
conversation.GroupID = req.Conversation.GroupID
|
||||
m := make(map[string]any)
|
||||
m := make(map[string]interface{})
|
||||
if req.Conversation.RecvMsgOpt != nil {
|
||||
m["recv_msg_opt"] = req.Conversation.RecvMsgOpt.Value
|
||||
if req.Conversation.RecvMsgOpt.Value != conv.RecvMsgOpt {
|
||||
@@ -233,12 +229,11 @@ func (c *conversationServer) SetConversations(ctx context.Context,
|
||||
|
||||
// 获取超级大群开启免打扰的用户ID.
|
||||
func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req *pbconversation.GetRecvMsgNotNotifyUserIDsReq) (*pbconversation.GetRecvMsgNotNotifyUserIDsResp, error) {
|
||||
//userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//return &pbconversation.GetRecvMsgNotNotifyUserIDsResp{UserIDs: userIDs}, nil
|
||||
return nil, errors.New("deprecated")
|
||||
userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbconversation.GetRecvMsgNotNotifyUserIDsResp{UserIDs: userIDs}, nil
|
||||
}
|
||||
|
||||
// create conversation without notification for msg redis transfer.
|
||||
@@ -289,7 +284,7 @@ func (c *conversationServer) CreateGroupChatConversations(ctx context.Context, r
|
||||
|
||||
func (c *conversationServer) SetConversationMaxSeq(ctx context.Context, req *pbconversation.SetConversationMaxSeqReq) (*pbconversation.SetConversationMaxSeqResp, error) {
|
||||
if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, req.OwnerUserID, req.ConversationID,
|
||||
map[string]any{"max_seq": req.MaxSeq}); err != nil {
|
||||
map[string]interface{}{"max_seq": req.MaxSeq}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbconversation.SetConversationMaxSeqResp{}, nil
|
||||
|
||||
@@ -27,11 +27,19 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func (s *friendServer) GetPaginationBlacks(ctx context.Context, req *pbfriend.GetPaginationBlacksReq) (resp *pbfriend.GetPaginationBlacksResp, err error) {
|
||||
func (s *friendServer) GetPaginationBlacks(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetPaginationBlacksReq,
|
||||
) (resp *pbfriend.GetPaginationBlacksResp, err error) {
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
total, blacks, err := s.blackDatabase.FindOwnerBlacks(ctx, req.UserID, req.Pagination)
|
||||
var pageNumber, showNumber int32
|
||||
if req.Pagination != nil {
|
||||
pageNumber = req.Pagination.PageNumber
|
||||
showNumber = req.Pagination.ShowNumber
|
||||
}
|
||||
blacks, total, err := s.blackDatabase.FindOwnerBlacks(ctx, req.UserID, pageNumber, showNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -55,7 +63,10 @@ func (s *friendServer) IsBlack(ctx context.Context, req *pbfriend.IsBlackReq) (*
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *friendServer) RemoveBlack(ctx context.Context, req *pbfriend.RemoveBlackReq) (*pbfriend.RemoveBlackResp, error) {
|
||||
func (s *friendServer) RemoveBlack(
|
||||
ctx context.Context,
|
||||
req *pbfriend.RemoveBlackReq,
|
||||
) (*pbfriend.RemoveBlackResp, error) {
|
||||
if err := s.userRpcClient.Access(ctx, req.OwnerUserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -17,8 +17,10 @@ package friend
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
|
||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
@@ -30,162 +32,17 @@ func CallbackBeforeAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriend
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackBeforeAddFriendReq{
|
||||
CallbackCommand: cbapi.CallbackBeforeAddFriendCommand,
|
||||
CallbackCommand: constant.CallbackBeforeAddFriendCommand,
|
||||
FromUserID: req.FromUserID,
|
||||
ToUserID: req.ToUserID,
|
||||
ReqMsg: req.ReqMsg,
|
||||
Ex: req.Ex,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeAddFriendResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriend); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackBeforeSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) error {
|
||||
if !config.Config.Callback.CallbackBeforeSetFriendRemark.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackBeforeSetFriendRemarkReq{
|
||||
CallbackCommand: cbapi.CallbackBeforeSetFriendRemark,
|
||||
OwnerUserID: req.OwnerUserID,
|
||||
FriendUserID: req.FriendUserID,
|
||||
Remark: req.Remark,
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeSetFriendRemarkResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriend); err != nil {
|
||||
return err
|
||||
}
|
||||
utils.NotNilReplace(&req.Remark, &resp.Remark)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackAfterSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) error {
|
||||
if !config.Config.Callback.CallbackAfterSetFriendRemark.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackAfterSetFriendRemarkReq{
|
||||
CallbackCommand: cbapi.CallbackAfterSetFriendRemark,
|
||||
OwnerUserID: req.OwnerUserID,
|
||||
FriendUserID: req.FriendUserID,
|
||||
Remark: req.Remark,
|
||||
}
|
||||
resp := &cbapi.CallbackAfterSetFriendRemarkResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriend); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func CallbackBeforeAddBlack(ctx context.Context, req *pbfriend.AddBlackReq) error {
|
||||
if !config.Config.Callback.CallbackBeforeAddBlack.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackBeforeAddBlackReq{
|
||||
CallbackCommand: cbapi.CallbackBeforeAddBlackCommand,
|
||||
OwnerUserID: req.OwnerUserID,
|
||||
BlackUserID: req.BlackUserID,
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeAddBlackResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddBlack); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func CallbackAfterAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) error {
|
||||
if !config.Config.Callback.CallbackAfterAddFriend.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackAfterAddFriendReq{
|
||||
CallbackCommand: cbapi.CallbackAfterAddFriendCommand,
|
||||
FromUserID: req.FromUserID,
|
||||
ToUserID: req.ToUserID,
|
||||
ReqMsg: req.ReqMsg,
|
||||
}
|
||||
resp := &cbapi.CallbackAfterAddFriendResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterAddFriend); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func CallbackBeforeAddFriendAgree(ctx context.Context, req *pbfriend.RespondFriendApplyReq) error {
|
||||
if !config.Config.Callback.CallbackBeforeAddFriendAgree.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackBeforeAddFriendAgreeReq{
|
||||
CallbackCommand: cbapi.CallbackBeforeAddFriendAgreeCommand,
|
||||
FromUserID: req.FromUserID,
|
||||
ToUserID: req.ToUserID,
|
||||
HandleMsg: req.HandleMsg,
|
||||
HandleResult: req.HandleResult,
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeAddFriendAgreeResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriendAgree); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func CallbackAfterDeleteFriend(ctx context.Context, req *pbfriend.DeleteFriendReq) error {
|
||||
if !config.Config.Callback.CallbackAfterDeleteFriend.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackAfterDeleteFriendReq{
|
||||
CallbackCommand: cbapi.CallbackAfterDeleteFriendCommand,
|
||||
OwnerUserID: req.OwnerUserID,
|
||||
FriendUserID: req.FriendUserID,
|
||||
}
|
||||
resp := &cbapi.CallbackAfterDeleteFriendResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterDeleteFriend); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func CallbackBeforeImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) error {
|
||||
if !config.Config.Callback.CallbackBeforeImportFriends.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackBeforeImportFriendsReq{
|
||||
CallbackCommand: cbapi.CallbackBeforeImportFriendsCommand,
|
||||
OwnerUserID: req.OwnerUserID,
|
||||
FriendUserIDs: req.FriendUserIDs,
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeImportFriendsResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeImportFriends); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(resp.FriendUserIDs) != 0 {
|
||||
req.FriendUserIDs = resp.FriendUserIDs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func CallbackAfterImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) error {
|
||||
if !config.Config.Callback.CallbackAfterImportFriends.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackAfterImportFriendsReq{
|
||||
CallbackCommand: cbapi.CallbackAfterImportFriendsCommand,
|
||||
OwnerUserID: req.OwnerUserID,
|
||||
FriendUserIDs: req.FriendUserIDs,
|
||||
}
|
||||
resp := &cbapi.CallbackAfterImportFriendsResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterImportFriends); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackAfterRemoveBlack(ctx context.Context, req *pbfriend.RemoveBlackReq) error {
|
||||
if !config.Config.Callback.CallbackAfterRemoveBlack.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackAfterRemoveBlackReq{
|
||||
CallbackCommand: cbapi.CallbackAfterRemoveBlackCommand,
|
||||
OwnerUserID: req.OwnerUserID,
|
||||
BlackUserID: req.BlackUserID,
|
||||
}
|
||||
resp := &cbapi.CallbackAfterRemoveBlackResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterRemoveBlack); err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -17,8 +17,6 @@ package friend
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||
@@ -34,13 +32,13 @@ import (
|
||||
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
||||
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||
)
|
||||
|
||||
@@ -53,70 +51,50 @@ type friendServer struct {
|
||||
RegisterCenter registry.SvcDiscoveryRegistry
|
||||
}
|
||||
|
||||
func (s *friendServer) PinFriends(ctx context.Context, req *pbfriend.PinFriendsReq) (*pbfriend.PinFriendsResp, error) {
|
||||
return nil, errs.ErrInternalServer.Wrap("not implemented")
|
||||
}
|
||||
|
||||
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
// Initialize MongoDB
|
||||
mongo, err := unrelation.NewMongo()
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize Redis
|
||||
if err := db.AutoMigrate(&tablerelation.FriendModel{}, &tablerelation.FriendRequestModel{}, &tablerelation.BlackModel{}); err != nil {
|
||||
return err
|
||||
}
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
friendMongoDB, err := mgo.NewFriendMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
friendRequestMongoDB, err := mgo.NewFriendRequestMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
blackMongoDB, err := mgo.NewBlackMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize RPC clients
|
||||
blackDB := relation.NewBlackGorm(db)
|
||||
friendDB := relation.NewFriendGorm(db)
|
||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
|
||||
// Initialize notification sender
|
||||
notificationSender := notification.NewFriendNotificationSender(
|
||||
&msgRpcClient,
|
||||
notification.WithRpcFunc(userRpcClient.GetUsersInfo),
|
||||
)
|
||||
// Register Friend server with refactored MongoDB and Redis integrations
|
||||
pbfriend.RegisterFriendServer(server, &friendServer{
|
||||
friendDatabase: controller.NewFriendDatabase(
|
||||
friendMongoDB,
|
||||
friendRequestMongoDB,
|
||||
cache.NewFriendCacheRedis(rdb, friendMongoDB, cache.GetDefaultOpt()),
|
||||
tx.NewMongo(mongo.GetClient()),
|
||||
friendDB,
|
||||
relation.NewFriendRequestGorm(db),
|
||||
cache.NewFriendCacheRedis(rdb, friendDB, cache.GetDefaultOpt()),
|
||||
tx.NewGorm(db),
|
||||
),
|
||||
blackDatabase: controller.NewBlackDatabase(
|
||||
blackMongoDB,
|
||||
cache.NewBlackCacheRedis(rdb, blackMongoDB, cache.GetDefaultOpt()),
|
||||
blackDB,
|
||||
cache.NewBlackCacheRedis(rdb, blackDB, cache.GetDefaultOpt()),
|
||||
),
|
||||
userRpcClient: &userRpcClient,
|
||||
notificationSender: notificationSender,
|
||||
RegisterCenter: client,
|
||||
conversationRpcClient: rpcclient.NewConversationRpcClient(client),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) (resp *pbfriend.ApplyToAddFriendResp, err error) {
|
||||
func (s *friendServer) ApplyToAddFriend(
|
||||
ctx context.Context,
|
||||
req *pbfriend.ApplyToAddFriendReq,
|
||||
) (resp *pbfriend.ApplyToAddFriendResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.ApplyToAddFriendResp{}
|
||||
if err := authverify.CheckAccessV3(ctx, req.FromUserID); err != nil {
|
||||
@@ -125,7 +103,7 @@ func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.Apply
|
||||
if req.ToUserID == req.FromUserID {
|
||||
return nil, errs.ErrCanNotAddYourself.Wrap()
|
||||
}
|
||||
if err = CallbackBeforeAddFriend(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
||||
if err := CallbackBeforeAddFriend(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := s.userRpcClient.GetUsersInfoMap(ctx, []string{req.ToUserID, req.FromUserID}); err != nil {
|
||||
@@ -142,14 +120,14 @@ func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.Apply
|
||||
return nil, err
|
||||
}
|
||||
s.notificationSender.FriendApplicationAddNotification(ctx, req)
|
||||
if err = CallbackAfterAddFriend(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) (resp *pbfriend.ImportFriendResp, err error) {
|
||||
func (s *friendServer) ImportFriends(
|
||||
ctx context.Context,
|
||||
req *pbfriend.ImportFriendReq,
|
||||
) (resp *pbfriend.ImportFriendResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -163,10 +141,6 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFr
|
||||
if utils.Duplicate(req.FriendUserIDs) {
|
||||
return nil, errs.ErrArgs.Wrap("friend userID repeated")
|
||||
}
|
||||
if err := CallbackBeforeImportFriends(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.friendDatabase.BecomeFriends(ctx, req.OwnerUserID, req.FriendUserIDs, constant.BecomeFriendByImport); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -177,14 +151,14 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFr
|
||||
HandleResult: constant.FriendResponseAgree,
|
||||
})
|
||||
}
|
||||
if err := CallbackAfterImportFriends(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbfriend.ImportFriendResp{}, nil
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.RespondFriendApplyReq) (resp *pbfriend.RespondFriendApplyResp, err error) {
|
||||
func (s *friendServer) RespondFriendApply(
|
||||
ctx context.Context,
|
||||
req *pbfriend.RespondFriendApplyReq,
|
||||
) (resp *pbfriend.RespondFriendApplyResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.RespondFriendApplyResp{}
|
||||
if err := authverify.CheckAccessV3(ctx, req.ToUserID); err != nil {
|
||||
@@ -198,9 +172,6 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.Res
|
||||
HandleResult: req.HandleResult,
|
||||
}
|
||||
if req.HandleResult == constant.FriendResponseAgree {
|
||||
if err := CallbackBeforeAddFriendAgree(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
||||
return nil, err
|
||||
}
|
||||
err := s.friendDatabase.AgreeFriendRequest(ctx, &friendRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -220,7 +191,10 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.Res
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) DeleteFriend(ctx context.Context, req *pbfriend.DeleteFriendReq) (resp *pbfriend.DeleteFriendResp, err error) {
|
||||
func (s *friendServer) DeleteFriend(
|
||||
ctx context.Context,
|
||||
req *pbfriend.DeleteFriendReq,
|
||||
) (resp *pbfriend.DeleteFriendResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.DeleteFriendResp{}
|
||||
if err := s.userRpcClient.Access(ctx, req.OwnerUserID); err != nil {
|
||||
@@ -234,19 +208,15 @@ func (s *friendServer) DeleteFriend(ctx context.Context, req *pbfriend.DeleteFri
|
||||
return nil, err
|
||||
}
|
||||
s.notificationSender.FriendDeletedNotification(ctx, req)
|
||||
if err := CallbackAfterDeleteFriend(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) (resp *pbfriend.SetFriendRemarkResp, err error) {
|
||||
func (s *friendServer) SetFriendRemark(
|
||||
ctx context.Context,
|
||||
req *pbfriend.SetFriendRemarkReq,
|
||||
) (resp *pbfriend.SetFriendRemarkResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
|
||||
if err = CallbackBeforeSetFriendRemark(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
||||
return nil, err
|
||||
}
|
||||
resp = &pbfriend.SetFriendRemarkResp{}
|
||||
if err := s.userRpcClient.Access(ctx, req.OwnerUserID); err != nil {
|
||||
return nil, err
|
||||
@@ -258,15 +228,15 @@ func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFri
|
||||
if err := s.friendDatabase.UpdateRemark(ctx, req.OwnerUserID, req.FriendUserID, req.Remark); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := CallbackAfterSetFriendRemark(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
||||
return nil, err
|
||||
}
|
||||
s.notificationSender.FriendRemarkSetNotification(ctx, req.OwnerUserID, req.FriendUserID)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) GetDesignatedFriends(ctx context.Context, req *pbfriend.GetDesignatedFriendsReq) (resp *pbfriend.GetDesignatedFriendsResp, err error) {
|
||||
func (s *friendServer) GetDesignatedFriends(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetDesignatedFriendsReq,
|
||||
) (resp *pbfriend.GetDesignatedFriendsResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.GetDesignatedFriendsResp{}
|
||||
if utils.Duplicate(req.FriendUserIDs) {
|
||||
@@ -297,12 +267,15 @@ func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context,
|
||||
}
|
||||
|
||||
// ok 获取接收到的好友申请(即别人主动申请的).
|
||||
func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyToReq) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) {
|
||||
func (s *friendServer) GetPaginationFriendsApplyTo(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetPaginationFriendsApplyToReq,
|
||||
) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
total, friendRequests, err := s.friendDatabase.PageFriendRequestToMe(ctx, req.UserID, req.Pagination)
|
||||
friendRequests, total, err := s.friendDatabase.PageFriendRequestToMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -316,13 +289,16 @@ func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *pbf
|
||||
}
|
||||
|
||||
// ok 获取主动发出去的好友申请列表.
|
||||
func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyFromReq) (resp *pbfriend.GetPaginationFriendsApplyFromResp, err error) {
|
||||
func (s *friendServer) GetPaginationFriendsApplyFrom(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetPaginationFriendsApplyFromReq,
|
||||
) (resp *pbfriend.GetPaginationFriendsApplyFromResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.GetPaginationFriendsApplyFromResp{}
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
total, friendRequests, err := s.friendDatabase.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination)
|
||||
friendRequests, total, err := s.friendDatabase.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -335,7 +311,10 @@ func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *p
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) IsFriend(ctx context.Context, req *pbfriend.IsFriendReq) (resp *pbfriend.IsFriendResp, err error) {
|
||||
func (s *friendServer) IsFriend(
|
||||
ctx context.Context,
|
||||
req *pbfriend.IsFriendReq,
|
||||
) (resp *pbfriend.IsFriendResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.IsFriendResp{}
|
||||
resp.InUser1Friends, resp.InUser2Friends, err = s.friendDatabase.CheckIn(ctx, req.UserID1, req.UserID2)
|
||||
@@ -345,12 +324,15 @@ func (s *friendServer) IsFriend(ctx context.Context, req *pbfriend.IsFriendReq)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *friendServer) GetPaginationFriends(ctx context.Context, req *pbfriend.GetPaginationFriendsReq) (resp *pbfriend.GetPaginationFriendsResp, err error) {
|
||||
func (s *friendServer) GetPaginationFriends(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetPaginationFriendsReq,
|
||||
) (resp *pbfriend.GetPaginationFriendsResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
total, friends, err := s.friendDatabase.PageOwnerFriends(ctx, req.UserID, req.Pagination)
|
||||
friends, total, err := s.friendDatabase.PageOwnerFriends(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -363,7 +345,10 @@ func (s *friendServer) GetPaginationFriends(ctx context.Context, req *pbfriend.G
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *friendServer) GetFriendIDs(ctx context.Context, req *pbfriend.GetFriendIDsReq) (resp *pbfriend.GetFriendIDsResp, err error) {
|
||||
func (s *friendServer) GetFriendIDs(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetFriendIDsReq,
|
||||
) (resp *pbfriend.GetFriendIDsResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -26,7 +26,7 @@ func (s *groupServer) GetGroupInfoCache(
|
||||
ctx context.Context,
|
||||
req *pbgroup.GetGroupInfoCacheReq,
|
||||
) (resp *pbgroup.GetGroupInfoCacheResp, err error) {
|
||||
group, err := s.db.TakeGroup(ctx, req.GroupID)
|
||||
group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -38,7 +38,7 @@ func (s *groupServer) GetGroupMemberCache(
|
||||
ctx context.Context,
|
||||
req *pbgroup.GetGroupMemberCacheReq,
|
||||
) (resp *pbgroup.GetGroupMemberCacheResp, err error) {
|
||||
members, err := s.db.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID)
|
||||
members, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -18,16 +18,13 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/protocol/group"
|
||||
"github.com/OpenIMSDK/protocol/wrapperspb"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
pbgroup "github.com/OpenIMSDK/protocol/group"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
@@ -40,7 +37,7 @@ func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (
|
||||
return nil
|
||||
}
|
||||
cbReq := &callbackstruct.CallbackBeforeCreateGroupReq{
|
||||
CallbackCommand: callbackstruct.CallbackBeforeCreateGroupCommand,
|
||||
CallbackCommand: constant.CallbackBeforeCreateGroupCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
GroupInfo: req.GroupInfo,
|
||||
}
|
||||
@@ -61,7 +58,17 @@ func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (
|
||||
})
|
||||
}
|
||||
resp := &callbackstruct.CallbackBeforeCreateGroupResp{}
|
||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeCreateGroup); err != nil {
|
||||
err = http.CallBackPostReturn(
|
||||
ctx,
|
||||
config.Config.Callback.CallbackUrl,
|
||||
cbReq,
|
||||
resp,
|
||||
config.Config.Callback.CallbackBeforeCreateGroup,
|
||||
)
|
||||
if err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
utils.NotNilReplace(&req.GroupInfo.GroupID, resp.GroupID)
|
||||
@@ -79,37 +86,6 @@ func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackAfterCreateGroup(ctx context.Context, req *group.CreateGroupReq) (err error) {
|
||||
if !config.Config.Callback.CallbackAfterCreateGroup.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &callbackstruct.CallbackAfterCreateGroupReq{
|
||||
CallbackCommand: callbackstruct.CallbackAfterCreateGroupCommand,
|
||||
GroupInfo: req.GroupInfo,
|
||||
}
|
||||
cbReq.InitMemberList = append(cbReq.InitMemberList, &apistruct.GroupAddMemberInfo{
|
||||
UserID: req.OwnerUserID,
|
||||
RoleLevel: constant.GroupOwner,
|
||||
})
|
||||
for _, userID := range req.AdminUserIDs {
|
||||
cbReq.InitMemberList = append(cbReq.InitMemberList, &apistruct.GroupAddMemberInfo{
|
||||
UserID: userID,
|
||||
RoleLevel: constant.GroupAdmin,
|
||||
})
|
||||
}
|
||||
for _, userID := range req.MemberUserIDs {
|
||||
cbReq.InitMemberList = append(cbReq.InitMemberList, &apistruct.GroupAddMemberInfo{
|
||||
UserID: userID,
|
||||
RoleLevel: constant.GroupOrdinaryUsers,
|
||||
})
|
||||
}
|
||||
resp := &callbackstruct.CallbackAfterCreateGroupResp{}
|
||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterCreateGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackBeforeMemberJoinGroup(
|
||||
ctx context.Context,
|
||||
groupMember *relation.GroupMemberModel,
|
||||
@@ -119,7 +95,8 @@ func CallbackBeforeMemberJoinGroup(
|
||||
return nil
|
||||
}
|
||||
callbackReq := &callbackstruct.CallbackBeforeMemberJoinGroupReq{
|
||||
CallbackCommand: callbackstruct.CallbackBeforeMemberJoinGroupCommand,
|
||||
CallbackCommand: constant.CallbackBeforeMemberJoinGroupCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
GroupID: groupMember.GroupID,
|
||||
UserID: groupMember.UserID,
|
||||
Ex: groupMember.Ex,
|
||||
@@ -134,6 +111,9 @@ func CallbackBeforeMemberJoinGroup(
|
||||
config.Config.Callback.CallbackBeforeMemberJoinGroup,
|
||||
)
|
||||
if err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if resp.MuteEndTime != nil {
|
||||
@@ -151,7 +131,8 @@ func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMe
|
||||
return nil
|
||||
}
|
||||
callbackReq := callbackstruct.CallbackBeforeSetGroupMemberInfoReq{
|
||||
CallbackCommand: callbackstruct.CallbackBeforeSetGroupMemberInfoCommand,
|
||||
CallbackCommand: constant.CallbackBeforeSetGroupMemberInfoCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
GroupID: req.GroupID,
|
||||
UserID: req.UserID,
|
||||
}
|
||||
@@ -176,6 +157,9 @@ func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMe
|
||||
config.Config.Callback.CallbackBeforeSetGroupMemberInfo,
|
||||
)
|
||||
if err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if resp.FaceURL != nil {
|
||||
@@ -192,240 +176,3 @@ func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMe
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func CallbackAfterSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMemberInfo) (err error) {
|
||||
if !config.Config.Callback.CallbackBeforeSetGroupMemberInfo.Enable {
|
||||
return nil
|
||||
}
|
||||
callbackReq := callbackstruct.CallbackAfterSetGroupMemberInfoReq{
|
||||
CallbackCommand: callbackstruct.CallbackAfterSetGroupMemberInfoCommand,
|
||||
GroupID: req.GroupID,
|
||||
UserID: req.UserID,
|
||||
}
|
||||
if req.Nickname != nil {
|
||||
callbackReq.Nickname = &req.Nickname.Value
|
||||
}
|
||||
if req.FaceURL != nil {
|
||||
callbackReq.FaceURL = &req.FaceURL.Value
|
||||
}
|
||||
if req.RoleLevel != nil {
|
||||
callbackReq.RoleLevel = &req.RoleLevel.Value
|
||||
}
|
||||
if req.Ex != nil {
|
||||
callbackReq.Ex = &req.Ex.Value
|
||||
}
|
||||
resp := &callbackstruct.CallbackAfterSetGroupMemberInfoResp{}
|
||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterSetGroupMemberInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackQuitGroup(ctx context.Context, req *group.QuitGroupReq) (err error) {
|
||||
if !config.Config.Callback.CallbackQuitGroup.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &callbackstruct.CallbackQuitGroupReq{
|
||||
CallbackCommand: callbackstruct.CallbackQuitGroupCommand,
|
||||
GroupID: req.GroupID,
|
||||
UserID: req.UserID,
|
||||
}
|
||||
resp := &callbackstruct.CallbackQuitGroupResp{}
|
||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackQuitGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackKillGroupMember(ctx context.Context, req *pbgroup.KickGroupMemberReq) (err error) {
|
||||
if !config.Config.Callback.CallbackKillGroupMember.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &callbackstruct.CallbackKillGroupMemberReq{
|
||||
CallbackCommand: callbackstruct.CallbackKillGroupCommand,
|
||||
GroupID: req.GroupID,
|
||||
KickedUserIDs: req.KickedUserIDs,
|
||||
}
|
||||
resp := &callbackstruct.CallbackKillGroupMemberResp{}
|
||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackQuitGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackDismissGroup(ctx context.Context, req *callbackstruct.CallbackDisMissGroupReq) (err error) {
|
||||
if !config.Config.Callback.CallbackDismissGroup.Enable {
|
||||
return nil
|
||||
}
|
||||
req.CallbackCommand = callbackstruct.CallbackDisMissGroupCommand
|
||||
resp := &callbackstruct.CallbackDisMissGroupResp{}
|
||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackQuitGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackApplyJoinGroupBefore(ctx context.Context, req *callbackstruct.CallbackJoinGroupReq) (err error) {
|
||||
if !config.Config.Callback.CallbackBeforeJoinGroup.Enable {
|
||||
return nil
|
||||
}
|
||||
|
||||
req.CallbackCommand = callbackstruct.CallbackBeforeJoinGroupCommand
|
||||
|
||||
resp := &callbackstruct.CallbackJoinGroupResp{}
|
||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackBeforeJoinGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackTransferGroupOwnerAfter(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (err error) {
|
||||
if !config.Config.Callback.CallbackTransferGroupOwnerAfter.Enable {
|
||||
return nil
|
||||
}
|
||||
|
||||
cbReq := &callbackstruct.CallbackTransferGroupOwnerReq{
|
||||
CallbackCommand: callbackstruct.CallbackTransferGroupOwnerAfter,
|
||||
GroupID: req.GroupID,
|
||||
OldOwnerUserID: req.OldOwnerUserID,
|
||||
NewOwnerUserID: req.NewOwnerUserID,
|
||||
}
|
||||
|
||||
resp := &callbackstruct.CallbackTransferGroupOwnerResp{}
|
||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeJoinGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func CallbackBeforeInviteUserToGroup(ctx context.Context, req *group.InviteUserToGroupReq) (err error) {
|
||||
if !config.Config.Callback.CallbackBeforeInviteUserToGroup.Enable {
|
||||
return nil
|
||||
}
|
||||
|
||||
callbackReq := &callbackstruct.CallbackBeforeInviteUserToGroupReq{
|
||||
CallbackCommand: callbackstruct.CallbackBeforeInviteJoinGroupCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
GroupID: req.GroupID,
|
||||
Reason: req.Reason,
|
||||
InvitedUserIDs: req.InvitedUserIDs,
|
||||
}
|
||||
|
||||
resp := &callbackstruct.CallbackBeforeInviteUserToGroupResp{}
|
||||
err = http.CallBackPostReturn(
|
||||
ctx,
|
||||
config.Config.Callback.CallbackUrl,
|
||||
callbackReq,
|
||||
resp,
|
||||
config.Config.Callback.CallbackBeforeInviteUserToGroup,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(resp.RefusedMembersAccount) > 0 {
|
||||
// Handle the scenario where certain members are refused
|
||||
// You might want to update the req.Members list or handle it as per your business logic
|
||||
}
|
||||
utils.StructFieldNotNilReplace(req, resp)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackAfterJoinGroup(ctx context.Context, req *group.JoinGroupReq) error {
|
||||
if !config.Config.Callback.CallbackAfterJoinGroup.Enable {
|
||||
return nil
|
||||
}
|
||||
callbackReq := &callbackstruct.CallbackAfterJoinGroupReq{
|
||||
CallbackCommand: callbackstruct.CallbackAfterJoinGroupCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
GroupID: req.GroupID,
|
||||
ReqMessage: req.ReqMessage,
|
||||
JoinSource: req.JoinSource,
|
||||
InviterUserID: req.InviterUserID,
|
||||
}
|
||||
resp := &callbackstruct.CallbackAfterJoinGroupResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterJoinGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackBeforeSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq) error {
|
||||
if !config.Config.Callback.CallbackBeforeSetGroupInfo.Enable {
|
||||
return nil
|
||||
}
|
||||
callbackReq := &callbackstruct.CallbackBeforeSetGroupInfoReq{
|
||||
CallbackCommand: callbackstruct.CallbackBeforeSetGroupInfoCommand,
|
||||
GroupID: req.GroupInfoForSet.GroupID,
|
||||
Notification: req.GroupInfoForSet.Notification,
|
||||
Introduction: req.GroupInfoForSet.Introduction,
|
||||
FaceURL: req.GroupInfoForSet.FaceURL,
|
||||
GroupName: req.GroupInfoForSet.GroupName,
|
||||
}
|
||||
|
||||
if req.GroupInfoForSet.Ex != nil {
|
||||
callbackReq.Ex = req.GroupInfoForSet.Ex.Value
|
||||
}
|
||||
log.ZDebug(ctx, "debug CallbackBeforeSetGroupInfo", callbackReq.Ex)
|
||||
if req.GroupInfoForSet.NeedVerification != nil {
|
||||
callbackReq.NeedVerification = req.GroupInfoForSet.NeedVerification.Value
|
||||
}
|
||||
if req.GroupInfoForSet.LookMemberInfo != nil {
|
||||
callbackReq.LookMemberInfo = req.GroupInfoForSet.LookMemberInfo.Value
|
||||
}
|
||||
if req.GroupInfoForSet.ApplyMemberFriend != nil {
|
||||
callbackReq.ApplyMemberFriend = req.GroupInfoForSet.ApplyMemberFriend.Value
|
||||
}
|
||||
resp := &callbackstruct.CallbackBeforeSetGroupInfoResp{}
|
||||
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackBeforeSetGroupInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.Ex != nil {
|
||||
req.GroupInfoForSet.Ex = wrapperspb.String(*resp.Ex)
|
||||
}
|
||||
if resp.NeedVerification != nil {
|
||||
req.GroupInfoForSet.NeedVerification = wrapperspb.Int32(*resp.NeedVerification)
|
||||
}
|
||||
if resp.LookMemberInfo != nil {
|
||||
req.GroupInfoForSet.LookMemberInfo = wrapperspb.Int32(*resp.LookMemberInfo)
|
||||
}
|
||||
if resp.ApplyMemberFriend != nil {
|
||||
req.GroupInfoForSet.ApplyMemberFriend = wrapperspb.Int32(*resp.ApplyMemberFriend)
|
||||
}
|
||||
utils.StructFieldNotNilReplace(req, resp)
|
||||
return nil
|
||||
}
|
||||
func CallbackAfterSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq) error {
|
||||
if !config.Config.Callback.CallbackAfterSetGroupInfo.Enable {
|
||||
return nil
|
||||
}
|
||||
callbackReq := &callbackstruct.CallbackAfterSetGroupInfoReq{
|
||||
CallbackCommand: callbackstruct.CallbackAfterSetGroupInfoCommand,
|
||||
GroupID: req.GroupInfoForSet.GroupID,
|
||||
Notification: req.GroupInfoForSet.Notification,
|
||||
Introduction: req.GroupInfoForSet.Introduction,
|
||||
FaceURL: req.GroupInfoForSet.FaceURL,
|
||||
GroupName: req.GroupInfoForSet.GroupName,
|
||||
}
|
||||
if req.GroupInfoForSet.Ex != nil {
|
||||
callbackReq.Ex = &req.GroupInfoForSet.Ex.Value
|
||||
}
|
||||
if req.GroupInfoForSet.NeedVerification != nil {
|
||||
callbackReq.NeedVerification = &req.GroupInfoForSet.NeedVerification.Value
|
||||
}
|
||||
if req.GroupInfoForSet.LookMemberInfo != nil {
|
||||
callbackReq.LookMemberInfo = &req.GroupInfoForSet.LookMemberInfo.Value
|
||||
}
|
||||
if req.GroupInfoForSet.ApplyMemberFriend != nil {
|
||||
callbackReq.ApplyMemberFriend = &req.GroupInfoForSet.ApplyMemberFriend.Value
|
||||
}
|
||||
resp := &callbackstruct.CallbackAfterSetGroupInfoResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterSetGroupInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
utils.StructFieldNotNilReplace(req, resp)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSet) map[string]any {
|
||||
m := make(map[string]any)
|
||||
if group.GroupName != "" {
|
||||
m["group_name"] = group.GroupName
|
||||
m["name"] = group.GroupName
|
||||
}
|
||||
if group.Notification != "" {
|
||||
m["notification"] = group.Notification
|
||||
|
||||
@@ -17,9 +17,119 @@ package group
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func (s *groupServer) PopulateGroupMember(ctx context.Context, members ...*relationtb.GroupMemberModel) error {
|
||||
return s.Notification.PopulateGroupMember(ctx, members...)
|
||||
func (s *groupServer) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) {
|
||||
members, err := s.GroupDatabase.FindGroupMember(ctx, groupIDs, userIDs, roleLevels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
emptyUserIDs := make(map[string]struct{})
|
||||
for _, member := range members {
|
||||
if member.Nickname == "" || member.FaceURL == "" {
|
||||
emptyUserIDs[member.UserID] = struct{}{}
|
||||
}
|
||||
}
|
||||
if len(emptyUserIDs) > 0 {
|
||||
users, err := s.User.GetPublicUserInfoMap(ctx, utils.Keys(emptyUserIDs), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i, member := range members {
|
||||
user, ok := users[member.UserID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if member.Nickname == "" {
|
||||
members[i].Nickname = user.Nickname
|
||||
}
|
||||
if member.FaceURL == "" {
|
||||
members[i].FaceURL = user.FaceURL
|
||||
}
|
||||
}
|
||||
}
|
||||
return members, nil
|
||||
}
|
||||
|
||||
func (s *groupServer) TakeGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID string,
|
||||
) (*relationtb.GroupMemberModel, error) {
|
||||
member, err := s.GroupDatabase.TakeGroupMember(ctx, groupID, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if member.Nickname == "" || member.FaceURL == "" {
|
||||
user, err := s.User.GetPublicUserInfo(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if member.Nickname == "" {
|
||||
member.Nickname = user.Nickname
|
||||
}
|
||||
if member.FaceURL == "" {
|
||||
member.FaceURL = user.FaceURL
|
||||
}
|
||||
}
|
||||
return member, nil
|
||||
}
|
||||
|
||||
func (s *groupServer) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) {
|
||||
owner, err := s.GroupDatabase.TakeGroupOwner(ctx, groupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if owner.Nickname == "" || owner.FaceURL == "" {
|
||||
user, err := s.User.GetUserInfo(ctx, owner.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if owner.Nickname == "" {
|
||||
owner.Nickname = user.Nickname
|
||||
}
|
||||
if owner.FaceURL == "" {
|
||||
owner.FaceURL = user.FaceURL
|
||||
}
|
||||
}
|
||||
return owner, nil
|
||||
}
|
||||
|
||||
func (s *groupServer) PageGetGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupMemberModel, error) {
|
||||
total, members, err := s.GroupDatabase.PageGetGroupMember(ctx, groupID, pageNumber, showNumber)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
emptyUserIDs := make(map[string]struct{})
|
||||
for _, member := range members {
|
||||
if member.Nickname == "" || member.FaceURL == "" {
|
||||
emptyUserIDs[member.UserID] = struct{}{}
|
||||
}
|
||||
}
|
||||
if len(emptyUserIDs) > 0 {
|
||||
users, err := s.User.GetPublicUserInfoMap(ctx, utils.Keys(emptyUserIDs), true)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
for i, member := range members {
|
||||
user, ok := users[member.UserID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if member.Nickname == "" {
|
||||
members[i].Nickname = user.Nickname
|
||||
}
|
||||
if member.FaceURL == "" {
|
||||
members[i].FaceURL = user.FaceURL
|
||||
}
|
||||
}
|
||||
}
|
||||
return total, members, nil
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,16 +26,16 @@ func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCrea
|
||||
if req.Start > req.End {
|
||||
return nil, errs.ErrArgs.Wrap("start > end")
|
||||
}
|
||||
total, err := s.db.CountTotal(ctx, nil)
|
||||
total, err := s.GroupDatabase.CountTotal(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
start := time.UnixMilli(req.Start)
|
||||
before, err := s.db.CountTotal(ctx, &start)
|
||||
before, err := s.GroupDatabase.CountTotal(ctx, &start)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
count, err := s.db.CountRangeEverydayTotal(ctx, start, time.UnixMilli(req.End))
|
||||
count, err := s.GroupDatabase.CountRangeEverydayTotal(ctx, start, time.UnixMilli(req.End))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -16,15 +16,99 @@ package group
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
pbgroup "github.com/OpenIMSDK/protocol/group"
|
||||
sdkws "github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
)
|
||||
|
||||
func (s *groupServer) GetJoinedSuperGroupList(context.Context, *pbgroup.GetJoinedSuperGroupListReq) (*pbgroup.GetJoinedSuperGroupListResp, error) {
|
||||
return nil, errors.New("deprecated")
|
||||
func (s *groupServer) GetJoinedSuperGroupList(
|
||||
ctx context.Context,
|
||||
req *pbgroup.GetJoinedSuperGroupListReq,
|
||||
) (*pbgroup.GetJoinedSuperGroupListResp, error) {
|
||||
resp := &pbgroup.GetJoinedSuperGroupListResp{}
|
||||
groupIDs, err := s.GroupDatabase.FindJoinSuperGroup(ctx, req.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(groupIDs) == 0 {
|
||||
return resp, nil
|
||||
}
|
||||
owners, err := s.FindGroupMember(ctx, groupIDs, nil, []int32{constant.GroupOwner})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ownerMap := utils.SliceToMap(owners, func(e *relation.GroupMemberModel) string {
|
||||
return e.GroupID
|
||||
})
|
||||
if ids := utils.Single(groupIDs, utils.Keys(ownerMap)); len(ids) > 0 {
|
||||
return nil, errs.ErrData.Wrap(fmt.Sprintf("super group %s not owner", strings.Join(ids, ",")))
|
||||
}
|
||||
groups, err := s.GroupDatabase.FindGroup(ctx, groupIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupMap := utils.SliceToMap(groups, func(e *relation.GroupModel) string {
|
||||
return e.GroupID
|
||||
})
|
||||
if ids := utils.Single(groupIDs, utils.Keys(groupMap)); len(ids) > 0 {
|
||||
return nil, errs.ErrData.Wrap(fmt.Sprintf("super group info %s not found", strings.Join(ids, ",")))
|
||||
}
|
||||
superGroupMembers, err := s.GroupDatabase.FindSuperGroup(ctx, groupIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
superGroupMemberMap := utils.SliceToMapAny(
|
||||
superGroupMembers,
|
||||
func(e *unrelation.SuperGroupModel) (string, []string) {
|
||||
return e.GroupID, e.MemberIDs
|
||||
},
|
||||
)
|
||||
resp.Groups = utils.Slice(groupIDs, func(groupID string) *sdkws.GroupInfo {
|
||||
return convert.Db2PbGroupInfo(groupMap[groupID], ownerMap[groupID].UserID, uint32(len(superGroupMemberMap)))
|
||||
})
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *groupServer) GetSuperGroupsInfo(context.Context, *pbgroup.GetSuperGroupsInfoReq) (resp *pbgroup.GetSuperGroupsInfoResp, err error) {
|
||||
return nil, errors.New("deprecated")
|
||||
func (s *groupServer) GetSuperGroupsInfo(
|
||||
ctx context.Context,
|
||||
req *pbgroup.GetSuperGroupsInfoReq,
|
||||
) (resp *pbgroup.GetSuperGroupsInfoResp, err error) {
|
||||
resp = &pbgroup.GetSuperGroupsInfoResp{}
|
||||
if len(req.GroupIDs) == 0 {
|
||||
return nil, errs.ErrArgs.Wrap("groupIDs empty")
|
||||
}
|
||||
groups, err := s.GroupDatabase.FindGroup(ctx, req.GroupIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
superGroupMembers, err := s.GroupDatabase.FindSuperGroup(ctx, req.GroupIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
superGroupMemberMap := utils.SliceToMapAny(
|
||||
superGroupMembers,
|
||||
func(e *unrelation.SuperGroupModel) (string, []string) {
|
||||
return e.GroupID, e.MemberIDs
|
||||
},
|
||||
)
|
||||
owners, err := s.FindGroupMember(ctx, req.GroupIDs, nil, []int32{constant.GroupOwner})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ownerMap := utils.SliceToMap(owners, func(e *relation.GroupMemberModel) string {
|
||||
return e.GroupID
|
||||
})
|
||||
resp.GroupInfos = utils.Slice(groups, func(e *relation.GroupModel) *sdkws.GroupInfo {
|
||||
return convert.Db2PbGroupInfo(e, ownerMap[e.GroupID].UserID, uint32(len(superGroupMemberMap[e.GroupID])))
|
||||
})
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@ package msg
|
||||
import (
|
||||
"context"
|
||||
|
||||
utils2 "github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
@@ -26,8 +24,6 @@ import (
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
|
||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||
)
|
||||
|
||||
func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (resp *msg.GetConversationsHasReadAndMaxSeqResp, err error) {
|
||||
@@ -114,7 +110,6 @@ func (m *msgServer) MarkMsgsAsRead(
|
||||
if err = m.MsgDatabase.MarkSingleChatMsgsAsRead(ctx, req.UserID, req.ConversationID, req.Seqs); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
currentHasReadSeq, err := m.MsgDatabase.GetHasReadSeq(ctx, req.UserID, req.ConversationID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
return
|
||||
@@ -152,12 +147,7 @@ func (m *msgServer) MarkConversationAsRead(
|
||||
for i := hasReadSeq + 1; i <= req.HasReadSeq; i++ {
|
||||
seqs = append(seqs, i)
|
||||
}
|
||||
//avoid client missed call MarkConversationMessageAsRead by order
|
||||
for _, val := range req.Seqs {
|
||||
if !utils2.Contain(val, seqs...) {
|
||||
seqs = append(seqs, val)
|
||||
}
|
||||
}
|
||||
|
||||
if len(seqs) > 0 {
|
||||
log.ZDebug(ctx, "MarkConversationAsRead", "seqs", seqs, "conversationID", req.ConversationID)
|
||||
if err = m.MsgDatabase.MarkSingleChatMsgsAsRead(ctx, req.UserID, req.ConversationID, seqs); err != nil {
|
||||
@@ -175,7 +165,6 @@ func (m *msgServer) MarkConversationAsRead(
|
||||
m.conversationAndGetRecvID(conversation, req.UserID), seqs, hasReadSeq); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if conversation.ConversationType == constant.SuperGroupChatType ||
|
||||
conversation.ConversationType == constant.NotificationChatType {
|
||||
if req.HasReadSeq > hasReadSeq {
|
||||
@@ -192,16 +181,6 @@ func (m *msgServer) MarkConversationAsRead(
|
||||
|
||||
}
|
||||
|
||||
reqCall := &cbapi.CallbackGroupMsgReadReq{
|
||||
SendID: conversation.OwnerUserID,
|
||||
ReceiveID: req.UserID,
|
||||
UnreadMsgNum: req.HasReadSeq,
|
||||
ContentType: int64(conversation.ConversationType),
|
||||
}
|
||||
if err := CallbackGroupMsgRead(ctx, reqCall); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &msg.MarkConversationAsReadResp{}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@ import (
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
pbchat "github.com/OpenIMSDK/protocol/msg"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||
)
|
||||
@@ -74,11 +74,14 @@ func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) er
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackBeforeSendSingleMsgReq{
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackBeforeSendSingleMsgCommand),
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, constant.CallbackBeforeSendSingleMsgCommand),
|
||||
RecvID: msg.MsgData.RecvID,
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeSendSingleMsgResp{}
|
||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackBeforeSendSingleMsg); err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -89,26 +92,32 @@ func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) err
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackAfterSendSingleMsgReq{
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackAfterSendSingleMsgCommand),
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, constant.CallbackAfterSendSingleMsgCommand),
|
||||
RecvID: msg.MsgData.RecvID,
|
||||
}
|
||||
resp := &cbapi.CallbackAfterSendSingleMsgResp{}
|
||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendSingleMsg); err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
||||
if !config.Config.Callback.CallbackBeforeSendSingleMsg.Enable {
|
||||
if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable {
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackBeforeSendGroupMsgReq{
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackBeforeSendGroupMsgCommand),
|
||||
req := &cbapi.CallbackAfterSendGroupMsgReq{
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, constant.CallbackBeforeSendGroupMsgCommand),
|
||||
GroupID: msg.MsgData.GroupID,
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeSendGroupMsgResp{}
|
||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackBeforeSendGroupMsg); err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -119,11 +128,14 @@ func callbackAfterSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) erro
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackAfterSendGroupMsgReq{
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackAfterSendGroupMsgCommand),
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, constant.CallbackAfterSendGroupMsgCommand),
|
||||
GroupID: msg.MsgData.GroupID,
|
||||
}
|
||||
resp := &cbapi.CallbackAfterSendGroupMsgResp{}
|
||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendGroupMsg); err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -134,10 +146,13 @@ func callbackMsgModify(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackMsgModifyCommandReq{
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackMsgModifyCommand),
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, constant.CallbackMsgModifyCommand),
|
||||
}
|
||||
resp := &cbapi.CallbackMsgModifyCommandResp{}
|
||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackMsgModify); err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if resp.Content != nil {
|
||||
@@ -162,46 +177,3 @@ func callbackMsgModify(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
||||
log.ZDebug(ctx, "callbackMsgModify", "msg", msg.MsgData)
|
||||
return nil
|
||||
}
|
||||
func CallbackGroupMsgRead(ctx context.Context, req *cbapi.CallbackGroupMsgReadReq) error {
|
||||
if !config.Config.Callback.CallbackGroupMsgRead.Enable || req.ContentType != constant.Text {
|
||||
return nil
|
||||
}
|
||||
req.CallbackCommand = cbapi.CallbackGroupMsgReadCommand
|
||||
|
||||
resp := &cbapi.CallbackGroupMsgReadResp{}
|
||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackMsgModify); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackSingleMsgRead(ctx context.Context, req *cbapi.CallbackSingleMsgReadReq) error {
|
||||
if !config.Config.Callback.CallbackSingleMsgRead.Enable || req.ContentType != constant.Text {
|
||||
return nil
|
||||
}
|
||||
req.CallbackCommand = cbapi.CallbackSingleMsgRead
|
||||
|
||||
resp := &cbapi.CallbackSingleMsgReadResp{}
|
||||
|
||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackMsgModify); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func CallbackAfterRevokeMsg(ctx context.Context, req *pbchat.RevokeMsgReq) error {
|
||||
if !config.Config.Callback.CallbackAfterRevokeMsg.Enable {
|
||||
return nil
|
||||
}
|
||||
callbackReq := &cbapi.CallbackAfterRevokeMsgReq{
|
||||
CallbackCommand: cbapi.CallbackAfterRevokeMsgCommand,
|
||||
ConversationID: req.ConversationID,
|
||||
Seq: req.Seq,
|
||||
UserID: req.UserID,
|
||||
}
|
||||
resp := &cbapi.CallbackAfterRevokeMsgResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterRevokeMsg); err != nil {
|
||||
return err
|
||||
}
|
||||
utils.StructFieldNotNilReplace(req, resp)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
||||
if msgs[0].ContentType == constant.MsgRevokeNotification {
|
||||
return nil, errs.ErrMsgAlreadyRevoke.Wrap("msg already revoke")
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(msgs[0])
|
||||
log.ZInfo(ctx, "GetMsgBySeqs", "conversationID", req.ConversationID, "seq", req.Seq, "msg", string(data))
|
||||
var role int32
|
||||
@@ -129,8 +128,5 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
||||
if err := m.notificationSender.NotificationWithSesstionType(ctx, req.UserID, recvID, constant.MsgRevokeNotification, msgs[0].SessionType, &tips); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = CallbackAfterRevokeMsg(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &msg.RevokeMsgResp{}, nil
|
||||
}
|
||||
|
||||
@@ -42,8 +42,15 @@ func (m *msgServer) PullMessageBySeqs(
|
||||
log.ZError(ctx, "GetConversation error", err, "conversationID", seq.ConversationID)
|
||||
continue
|
||||
}
|
||||
minSeq, maxSeq, msgs, err := m.MsgDatabase.GetMsgBySeqsRange(ctx, req.UserID, seq.ConversationID,
|
||||
seq.Begin, seq.End, seq.Num, conversation.MaxSeq)
|
||||
minSeq, maxSeq, msgs, err := m.MsgDatabase.GetMsgBySeqsRange(
|
||||
ctx,
|
||||
req.UserID,
|
||||
seq.ConversationID,
|
||||
seq.Begin,
|
||||
seq.End,
|
||||
seq.Num,
|
||||
conversation.MaxSeq,
|
||||
)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "GetMsgBySeqsRange error", err, "conversationID", seq.ConversationID, "seq", seq)
|
||||
continue
|
||||
@@ -57,6 +64,7 @@ func (m *msgServer) PullMessageBySeqs(
|
||||
}
|
||||
if len(msgs) == 0 {
|
||||
log.ZWarn(ctx, "not have msgs", nil, "conversationID", seq.ConversationID, "seq", seq)
|
||||
|
||||
continue
|
||||
}
|
||||
resp.Msgs[seq.ConversationID] = &sdkws.PullMsgs{Msgs: msgs, IsEnd: isEnd}
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package msg
|
||||
|
||||
import (
|
||||
"github.com/redis/go-redis/v9"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
)
|
||||
@@ -44,7 +45,7 @@ func isMessageHasReadEnabled(msgData *sdkws.MsgData) bool {
|
||||
|
||||
func IsNotFound(err error) bool {
|
||||
switch utils.Unwrap(err) {
|
||||
case redis.Nil, mongo.ErrNoDocuments:
|
||||
case redis.Nil, gorm.ErrRecordNotFound:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
@@ -32,11 +32,11 @@ func genLogID() string {
|
||||
}
|
||||
|
||||
func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq) (*third.UploadLogsResp, error) {
|
||||
var DBlogs []*relationtb.LogModel
|
||||
var DBlogs []*relationtb.Log
|
||||
userID := ctx.Value(constant.OpUserID).(string)
|
||||
platform := constant.PlatformID2Name[int(req.Platform)]
|
||||
for _, fileURL := range req.FileURLs {
|
||||
log := relationtb.LogModel{
|
||||
log := relationtb.Log{
|
||||
Version: req.Version,
|
||||
SystemType: req.SystemType,
|
||||
Platform: platform,
|
||||
@@ -57,7 +57,7 @@ func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq)
|
||||
}
|
||||
}
|
||||
if log.LogID == "" {
|
||||
return nil, errs.ErrData.Wrap("LogModel id gen error")
|
||||
return nil, errs.ErrData.Wrap("Log id gen error")
|
||||
}
|
||||
DBlogs = append(DBlogs, &log)
|
||||
}
|
||||
@@ -92,8 +92,8 @@ func (t *thirdServer) DeleteLogs(ctx context.Context, req *third.DeleteLogsReq)
|
||||
return &third.DeleteLogsResp{}, nil
|
||||
}
|
||||
|
||||
func dbToPbLogInfos(logs []*relationtb.LogModel) []*third.LogInfo {
|
||||
db2pbForLogInfo := func(log *relationtb.LogModel) *third.LogInfo {
|
||||
func dbToPbLogInfos(logs []*relationtb.Log) []*third.LogInfo {
|
||||
db2pbForLogInfo := func(log *relationtb.Log) *third.LogInfo {
|
||||
return &third.LogInfo{
|
||||
Filename: log.FileName,
|
||||
UserID: log.UserID,
|
||||
@@ -120,7 +120,7 @@ func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq)
|
||||
if req.StartTime > req.EndTime {
|
||||
return nil, errs.ErrArgs.Wrap("startTime>endTime")
|
||||
}
|
||||
total, logs, err := t.thirdDatabase.SearchLogs(ctx, req.Keyword, time.UnixMilli(req.StartTime), time.UnixMilli(req.EndTime), req.Pagination)
|
||||
total, logs, err := t.thirdDatabase.SearchLogs(ctx, req.Keyword, time.UnixMilli(req.StartTime), time.UnixMilli(req.EndTime), req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -128,16 +128,18 @@ func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq)
|
||||
for _, log := range logs {
|
||||
userIDs = append(userIDs, log.UserID)
|
||||
}
|
||||
userMap, err := t.userRpcClient.GetUsersInfoMap(ctx, userIDs)
|
||||
users, err := t.thirdDatabase.FindUsers(ctx, userIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
IDtoName := make(map[string]string)
|
||||
for _, user := range users {
|
||||
IDtoName[user.UserID] = user.Nickname
|
||||
}
|
||||
for _, pbLog := range pbLogs {
|
||||
if user, ok := userMap[pbLog.UserID]; ok {
|
||||
pbLog.Nickname = user.Nickname
|
||||
}
|
||||
pbLog.Nickname = IDtoName[pbLog.UserID]
|
||||
}
|
||||
resp.LogsInfos = pbLogs
|
||||
resp.Total = uint32(total)
|
||||
resp.Total = total
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *third.In
|
||||
Key: haErr.Object.Key,
|
||||
Size: haErr.Object.Size,
|
||||
ContentType: req.ContentType,
|
||||
Group: req.Cause,
|
||||
Cause: req.Cause,
|
||||
CreateTime: time.Now(),
|
||||
}
|
||||
if err := t.s3dataBase.SetObject(ctx, obj); err != nil {
|
||||
@@ -143,7 +143,7 @@ func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.Co
|
||||
Key: result.Key,
|
||||
Size: result.Size,
|
||||
ContentType: req.ContentType,
|
||||
Group: req.Cause,
|
||||
Cause: req.Cause,
|
||||
CreateTime: time.Now(),
|
||||
}
|
||||
if err := t.s3dataBase.SetObject(ctx, obj); err != nil {
|
||||
|
||||
@@ -20,9 +20,6 @@ import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cos"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/minio"
|
||||
@@ -36,22 +33,13 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||
)
|
||||
|
||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
mongo, err := unrelation.NewMongo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logdb, err := mgo.NewLogMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s3db, err := mgo.NewS3Mongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apiURL := config.Config.Object.ApiURL
|
||||
if apiURL == "" {
|
||||
return fmt.Errorf("api url is empty")
|
||||
@@ -67,6 +55,13 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&relationtb.ObjectModel{}); err != nil {
|
||||
return err
|
||||
}
|
||||
// 根据配置文件策略选择 oss 方式
|
||||
enable := config.Config.Object.Enable
|
||||
var o s3.Interface
|
||||
@@ -83,11 +78,17 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//specialerror.AddErrHandler(func(err error) errs.CodeError {
|
||||
// if o.IsNotFound(err) {
|
||||
// return errs.ErrRecordNotFound
|
||||
// }
|
||||
// return nil
|
||||
//})
|
||||
third.RegisterThirdServer(server, &thirdServer{
|
||||
apiURL: apiURL,
|
||||
thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb), logdb),
|
||||
thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb), db),
|
||||
userRpcClient: rpcclient.NewUserRpcClient(client),
|
||||
s3dataBase: controller.NewS3Database(rdb, o, s3db),
|
||||
s3dataBase: controller.NewS3Database(rdb, o, relation.NewObjectInfo(db)),
|
||||
defaultExpire: time.Hour * 24 * 7,
|
||||
})
|
||||
return nil
|
||||
|
||||
@@ -17,7 +17,10 @@ package user
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
pbuser "github.com/OpenIMSDK/protocol/user"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||
@@ -30,13 +33,17 @@ func CallbackBeforeUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInf
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackBeforeUpdateUserInfoReq{
|
||||
CallbackCommand: cbapi.CallbackBeforeUpdateUserInfoCommand,
|
||||
CallbackCommand: constant.CallbackBeforeUpdateUserInfoCommand,
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
UserID: req.UserInfo.UserID,
|
||||
FaceURL: &req.UserInfo.FaceURL,
|
||||
Nickname: &req.UserInfo.Nickname,
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeUpdateUserInfoResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
||||
if err == errs.ErrCallbackContinue {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
utils.NotNilReplace(&req.UserInfo.FaceURL, resp.FaceURL)
|
||||
@@ -44,57 +51,3 @@ func CallbackBeforeUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInf
|
||||
utils.NotNilReplace(&req.UserInfo.Nickname, resp.Nickname)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackAfterUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) error {
|
||||
if !config.Config.Callback.CallbackAfterUpdateUserInfo.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackAfterUpdateUserInfoReq{
|
||||
CallbackCommand: cbapi.CallbackAfterUpdateUserInfoCommand,
|
||||
UserID: req.UserInfo.UserID,
|
||||
FaceURL: req.UserInfo.FaceURL,
|
||||
Nickname: req.UserInfo.Nickname,
|
||||
}
|
||||
resp := &cbapi.CallbackAfterUpdateUserInfoResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackBeforeUserRegister(ctx context.Context, req *pbuser.UserRegisterReq) error {
|
||||
if !config.Config.Callback.CallbackBeforeUserRegister.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackBeforeUserRegisterReq{
|
||||
CallbackCommand: cbapi.CallbackBeforeUserRegisterCommand,
|
||||
Secret: req.Secret,
|
||||
Users: req.Users,
|
||||
}
|
||||
|
||||
resp := &cbapi.CallbackBeforeUserRegisterResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(resp.Users) != 0 {
|
||||
req.Users = resp.Users
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackAfterUserRegister(ctx context.Context, req *pbuser.UserRegisterReq) error {
|
||||
if !config.Config.Callback.CallbackAfterUserRegister.Enable {
|
||||
return nil
|
||||
}
|
||||
cbReq := &cbapi.CallbackAfterUserRegisterReq{
|
||||
CallbackCommand: cbapi.CallbackAfterUserRegisterCommand,
|
||||
Secret: req.Secret,
|
||||
Users: req.Users,
|
||||
}
|
||||
|
||||
resp := &cbapi.CallbackAfterUserRegisterResp{}
|
||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterUpdateUserInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -20,14 +20,11 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
@@ -38,6 +35,7 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||
@@ -56,23 +54,11 @@ type userServer struct {
|
||||
RegisterCenter registry.SvcDiscoveryRegistry
|
||||
}
|
||||
|
||||
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
|
||||
return nil, errs.ErrInternalServer.Wrap("not implemented")
|
||||
}
|
||||
|
||||
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
|
||||
return nil, errs.ErrInternalServer.Wrap("not implemented")
|
||||
}
|
||||
|
||||
func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) {
|
||||
return nil, errs.ErrInternalServer.Wrap("not implemented")
|
||||
}
|
||||
|
||||
func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) {
|
||||
return nil, errs.ErrInternalServer.Wrap("not implemented")
|
||||
}
|
||||
|
||||
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -81,6 +67,9 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&tablerelation.UserModel{}); err != nil {
|
||||
return err
|
||||
}
|
||||
users := make([]*tablerelation.UserModel, 0)
|
||||
if len(config.Config.Manager.UserID) != len(config.Config.Manager.Nickname) {
|
||||
return errors.New("len(config.Config.Manager.AppManagerUid) != len(config.Config.Manager.Nickname)")
|
||||
@@ -88,13 +77,10 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
for k, v := range config.Config.Manager.UserID {
|
||||
users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.Config.Manager.Nickname[k], AppMangerLevel: constant.AppAdmin})
|
||||
}
|
||||
userDB, err := mgo.NewUserMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
userDB := relation.NewUserGorm(db)
|
||||
cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt())
|
||||
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase())
|
||||
database := controller.NewUserDatabase(userDB, cache, tx.NewMongo(mongo.GetClient()), userMongoDB)
|
||||
database := controller.NewUserDatabase(userDB, cache, tx.NewGorm(db), userMongoDB)
|
||||
friendRpcClient := rpcclient.NewFriendRpcClient(client)
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
@@ -132,8 +118,12 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
|
||||
if err := CallbackBeforeUpdateUserInfo(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := convert.UserPb2DBMap(req.UserInfo)
|
||||
if err := s.UpdateByMap(ctx, req.UserInfo.UserID, data); err != nil {
|
||||
user := convert.UserPb2DB(req.UserInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = s.Update(ctx, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID)
|
||||
@@ -149,9 +139,6 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
|
||||
for _, friendID := range friends {
|
||||
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
||||
}
|
||||
if err := CallbackAfterUpdateUserInfo(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
||||
log.ZError(ctx, "NotificationUserInfoUpdate", err, "userID", req.UserInfo.UserID)
|
||||
}
|
||||
@@ -163,7 +150,7 @@ func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Se
|
||||
if _, err := s.FindWithError(ctx, []string{req.UserID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[string]any, 1)
|
||||
m := make(map[string]interface{}, 1)
|
||||
m["global_recv_msg_opt"] = req.GlobalRecvMsgOpt
|
||||
if err := s.UpdateByMap(ctx, req.UserID, m); err != nil {
|
||||
return nil, err
|
||||
@@ -185,7 +172,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userIDs := make(map[string]any, 0)
|
||||
userIDs := make(map[string]interface{}, 0)
|
||||
for _, v := range users {
|
||||
userIDs[v.UserID] = nil
|
||||
}
|
||||
@@ -202,7 +189,12 @@ 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) {
|
||||
total, users, err := s.Page(ctx, req.Pagination)
|
||||
var pageNumber, showNumber int32
|
||||
if req.Pagination != nil {
|
||||
pageNumber = req.Pagination.PageNumber
|
||||
showNumber = req.Pagination.ShowNumber
|
||||
}
|
||||
users, total, err := s.Page(ctx, pageNumber, showNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -238,9 +230,6 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
|
||||
if exist {
|
||||
return nil, errs.ErrRegisteredAlready.Wrap("userID registered already")
|
||||
}
|
||||
if err := CallbackBeforeUserRegister(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
now := time.Now()
|
||||
users := make([]*tablerelation.UserModel, 0, len(req.Users))
|
||||
for _, user := range req.Users {
|
||||
@@ -257,10 +246,6 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
|
||||
if err := s.Create(ctx, users); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := CallbackAfterUserRegister(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -274,11 +259,11 @@ func (s *userServer) GetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Ge
|
||||
|
||||
// GetAllUserID Get user account by page.
|
||||
func (s *userServer) GetAllUserID(ctx context.Context, req *pbuser.GetAllUserIDReq) (resp *pbuser.GetAllUserIDResp, err error) {
|
||||
total, userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination)
|
||||
userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbuser.GetAllUserIDResp{Total: int32(total), UserIDs: userIDs}, nil
|
||||
return &pbuser.GetAllUserIDResp{UserIDs: userIDs}, nil
|
||||
}
|
||||
|
||||
// SubscribeOrCancelUsersStatus Subscribe online or cancel online users.
|
||||
|
||||
@@ -19,8 +19,6 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
@@ -93,11 +91,7 @@ func (c *MsgTool) ConversationsDestructMsgs() {
|
||||
}
|
||||
for i := 0; i < count; i++ {
|
||||
pageNumber := rand.Int63() % maxPage
|
||||
pagination := &sdkws.RequestPagination{
|
||||
PageNumber: int32(pageNumber),
|
||||
ShowNumber: batchNum,
|
||||
}
|
||||
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, pagination)
|
||||
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, int32(pageNumber), batchNum)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber)
|
||||
continue
|
||||
@@ -139,7 +133,7 @@ func (c *MsgTool) ConversationsDestructMsgs() {
|
||||
continue
|
||||
}
|
||||
if len(seqs) > 0 {
|
||||
if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]any{"latest_msg_destruct_time": now}); err != nil {
|
||||
if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]interface{}{"latest_msg_destruct_time": now}); err != nil {
|
||||
log.ZError(ctx, "updateUsersConversationFiled failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -19,11 +19,6 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
@@ -36,11 +31,13 @@ import (
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/OpenIMSDK/tools/mw"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||
@@ -75,45 +72,33 @@ func InitMsgTool() (*MsgTool, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
discov, err := kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
||||
/*
|
||||
discov, err := zookeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
|
||||
zookeeper.WithFreq(time.Hour), zookeeper.WithRoundRobin(), zookeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
|
||||
config.Config.Zookeeper.Password), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))*/
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
userDB, err := mgo.NewUserMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userDB := relation.NewUserGorm(db)
|
||||
msgDatabase := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase())
|
||||
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase())
|
||||
ctxTx := tx.NewMongo(mongo.GetClient())
|
||||
userDatabase := controller.NewUserDatabase(
|
||||
userDB,
|
||||
cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt()),
|
||||
ctxTx,
|
||||
cache.NewUserCacheRedis(rdb, relation.NewUserGorm(db), cache.GetDefaultOpt()),
|
||||
tx.NewGorm(db),
|
||||
userMongoDB,
|
||||
)
|
||||
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupDatabase := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, ctxTx, nil)
|
||||
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), nil)
|
||||
conversationDatabase := controller.NewConversationDatabase(
|
||||
conversationDB,
|
||||
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB),
|
||||
ctxTx,
|
||||
relation.NewConversationGorm(db),
|
||||
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)),
|
||||
tx.NewGorm(db),
|
||||
)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(discov)
|
||||
msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient))
|
||||
@@ -159,11 +144,7 @@ func (c *MsgTool) AllConversationClearMsgAndFixSeq() {
|
||||
}
|
||||
for i := 0; i < count; i++ {
|
||||
pageNumber := rand.Int63() % maxPage
|
||||
pagination := &sdkws.RequestPagination{
|
||||
PageNumber: int32(pageNumber),
|
||||
ShowNumber: batchNum,
|
||||
}
|
||||
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, pagination)
|
||||
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, int32(pageNumber), batchNum)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber)
|
||||
continue
|
||||
|
||||
@@ -32,7 +32,7 @@ func (c *MsgTool) convertTools() {
|
||||
for _, conversationID := range conversationIDs {
|
||||
conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationIDByConversationID(conversationID))
|
||||
}
|
||||
_, userIDs, err := c.userDatabase.GetAllUserID(ctx, nil)
|
||||
userIDs, err := c.userDatabase.GetAllUserID(ctx, 0, 0)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "get all user ids failed", err)
|
||||
return
|
||||
|
||||
@@ -36,7 +36,7 @@ type SendMsg struct {
|
||||
SenderPlatformID int32 `json:"senderPlatformID"`
|
||||
|
||||
// Content is the actual content of the message, required and excluded from Swagger documentation.
|
||||
Content map[string]any `json:"content" binding:"required" swaggerignore:"true"`
|
||||
Content map[string]interface{} `json:"content" binding:"required" swaggerignore:"true"`
|
||||
|
||||
// ContentType is an integer that represents the type of the content.
|
||||
ContentType int32 `json:"contentType" binding:"required"`
|
||||
|
||||
@@ -16,56 +16,56 @@ package apistruct
|
||||
|
||||
type PictureBaseInfo struct {
|
||||
UUID string `mapstructure:"uuid"`
|
||||
Type string `mapstructure:"type" validate:"required"`
|
||||
Type string `mapstructure:"type"`
|
||||
Size int64 `mapstructure:"size"`
|
||||
Width int32 `mapstructure:"width" validate:"required"`
|
||||
Height int32 `mapstructure:"height" validate:"required"`
|
||||
Url string `mapstructure:"url" validate:"required"`
|
||||
Width int32 `mapstructure:"width"`
|
||||
Height int32 `mapstructure:"height"`
|
||||
Url string `mapstructure:"url"`
|
||||
}
|
||||
|
||||
type PictureElem struct {
|
||||
SourcePath string `mapstructure:"sourcePath"`
|
||||
SourcePicture PictureBaseInfo `mapstructure:"sourcePicture" validate:"required"`
|
||||
BigPicture PictureBaseInfo `mapstructure:"bigPicture" validate:"required"`
|
||||
SnapshotPicture PictureBaseInfo `mapstructure:"snapshotPicture" validate:"required"`
|
||||
SourcePicture PictureBaseInfo `mapstructure:"sourcePicture"`
|
||||
BigPicture PictureBaseInfo `mapstructure:"bigPicture"`
|
||||
SnapshotPicture PictureBaseInfo `mapstructure:"snapshotPicture"`
|
||||
}
|
||||
type SoundElem struct {
|
||||
UUID string `mapstructure:"uuid"`
|
||||
SoundPath string `mapstructure:"soundPath"`
|
||||
SourceURL string `mapstructure:"sourceUrl" validate:"required"`
|
||||
SourceURL string `mapstructure:"sourceUrl"`
|
||||
DataSize int64 `mapstructure:"dataSize"`
|
||||
Duration int64 `mapstructure:"duration" validate:"required,min=1"`
|
||||
Duration int64 `mapstructure:"duration"`
|
||||
}
|
||||
type VideoElem struct {
|
||||
VideoPath string `mapstructure:"videoPath"`
|
||||
VideoUUID string `mapstructure:"videoUUID"`
|
||||
VideoURL string `mapstructure:"videoUrl" validate:"required"`
|
||||
VideoType string `mapstructure:"videoType" validate:"required"`
|
||||
VideoSize int64 `mapstructure:"videoSize" validate:"required"`
|
||||
Duration int64 `mapstructure:"duration" validate:"required"`
|
||||
VideoURL string `mapstructure:"videoUrl"`
|
||||
VideoType string `mapstructure:"videoType"`
|
||||
VideoSize int64 `mapstructure:"videoSize"`
|
||||
Duration int64 `mapstructure:"duration"`
|
||||
SnapshotPath string `mapstructure:"snapshotPath"`
|
||||
SnapshotUUID string `mapstructure:"snapshotUUID"`
|
||||
SnapshotSize int64 `mapstructure:"snapshotSize"`
|
||||
SnapshotURL string `mapstructure:"snapshotUrl" validate:"required"`
|
||||
SnapshotWidth int32 `mapstructure:"snapshotWidth" validate:"required"`
|
||||
SnapshotHeight int32 `mapstructure:"snapshotHeight" validate:"required"`
|
||||
SnapshotURL string `mapstructure:"snapshotUrl"`
|
||||
SnapshotWidth int32 `mapstructure:"snapshotWidth"`
|
||||
SnapshotHeight int32 `mapstructure:"snapshotHeight"`
|
||||
}
|
||||
type FileElem struct {
|
||||
FilePath string `mapstructure:"filePath"`
|
||||
UUID string `mapstructure:"uuid"`
|
||||
SourceURL string `mapstructure:"sourceUrl" validate:"required"`
|
||||
FileName string `mapstructure:"fileName" validate:"required"`
|
||||
FileSize int64 `mapstructure:"fileSize" validate:"required"`
|
||||
SourceURL string `mapstructure:"sourceUrl"`
|
||||
FileName string `mapstructure:"fileName"`
|
||||
FileSize int64 `mapstructure:"fileSize"`
|
||||
}
|
||||
type AtElem struct {
|
||||
Text string `mapstructure:"text"`
|
||||
AtUserList []string `mapstructure:"atUserList" validate:"required,max=1000"`
|
||||
AtUserList []string `mapstructure:"atUserList"`
|
||||
IsAtSelf bool `mapstructure:"isAtSelf"`
|
||||
}
|
||||
type LocationElem struct {
|
||||
Description string `mapstructure:"description"`
|
||||
Longitude float64 `mapstructure:"longitude" validate:"required"`
|
||||
Latitude float64 `mapstructure:"latitude" validate:"required"`
|
||||
Longitude float64 `mapstructure:"longitude"`
|
||||
Latitude float64 `mapstructure:"latitude"`
|
||||
}
|
||||
type CustomElem struct {
|
||||
Data string `mapstructure:"data" validate:"required"`
|
||||
@@ -80,19 +80,18 @@ type TextElem struct {
|
||||
type RevokeElem struct {
|
||||
RevokeMsgClientID string `mapstructure:"revokeMsgClientID" validate:"required"`
|
||||
}
|
||||
|
||||
type OANotificationElem struct {
|
||||
NotificationName string `mapstructure:"notificationName" json:"notificationName" validate:"required"`
|
||||
NotificationFaceURL string `mapstructure:"notificationFaceURL" json:"notificationFaceURL"`
|
||||
NotificationType int32 `mapstructure:"notificationType" json:"notificationType" validate:"required"`
|
||||
Text string `mapstructure:"text" json:"text" validate:"required"`
|
||||
Url string `mapstructure:"url" json:"url"`
|
||||
MixType int32 `mapstructure:"mixType" json:"mixType" validate:"required"`
|
||||
PictureElem *PictureElem `mapstructure:"pictureElem" json:"pictureElem"`
|
||||
SoundElem *SoundElem `mapstructure:"soundElem" json:"soundElem"`
|
||||
VideoElem *VideoElem `mapstructure:"videoElem" json:"videoElem"`
|
||||
FileElem *FileElem `mapstructure:"fileElem" json:"fileElem"`
|
||||
Ex string `mapstructure:"ex" json:"ex"`
|
||||
NotificationName string `mapstructure:"notificationName" json:"notificationName" validate:"required"`
|
||||
NotificationFaceURL string `mapstructure:"notificationFaceURL" json:"notificationFaceURL"`
|
||||
NotificationType int32 `mapstructure:"notificationType" json:"notificationType" validate:"required"`
|
||||
Text string `mapstructure:"text" json:"text" validate:"required"`
|
||||
Url string `mapstructure:"url" json:"url"`
|
||||
MixType int32 `mapstructure:"mixType" json:"mixType"`
|
||||
PictureElem PictureElem `mapstructure:"pictureElem" json:"pictureElem"`
|
||||
SoundElem SoundElem `mapstructure:"soundElem" json:"soundElem"`
|
||||
VideoElem VideoElem `mapstructure:"videoElem" json:"videoElem"`
|
||||
FileElem FileElem `mapstructure:"fileElem" json:"fileElem"`
|
||||
Ex string `mapstructure:"ex" json:"ex"`
|
||||
}
|
||||
type MessageRevoked struct {
|
||||
RevokerID string `mapstructure:"revokerID" json:"revokerID" validate:"required"`
|
||||
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
)
|
||||
|
||||
func Secret() jwt.Keyfunc {
|
||||
return func(token *jwt.Token) (any, error) {
|
||||
return func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(config.Config.Secret), nil
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func CheckAdmin(ctx context.Context) error {
|
||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx)))
|
||||
}
|
||||
|
||||
func ParseRedisInterfaceToken(redisToken any) (*tokenverify.Claims, error) {
|
||||
func ParseRedisInterfaceToken(redisToken interface{}) (*tokenverify.Claims, error) {
|
||||
return tokenverify.GetClaimFromToken(string(redisToken.([]uint8)), Secret())
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,8 @@
|
||||
|
||||
package callbackstruct
|
||||
|
||||
import "github.com/OpenIMSDK/tools/errs"
|
||||
|
||||
const (
|
||||
Next = 1
|
||||
import (
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
)
|
||||
|
||||
type CommonCallbackReq struct {
|
||||
@@ -53,15 +51,14 @@ type CallbackResp interface {
|
||||
}
|
||||
|
||||
type CommonCallbackResp struct {
|
||||
ActionCode int32 `json:"actionCode"`
|
||||
ActionCode int `json:"actionCode"`
|
||||
ErrCode int32 `json:"errCode"`
|
||||
ErrMsg string `json:"errMsg"`
|
||||
ErrDlt string `json:"errDlt"`
|
||||
NextCode int32 `json:"nextCode"`
|
||||
}
|
||||
|
||||
func (c CommonCallbackResp) Parse() error {
|
||||
if c.ActionCode != errs.NoError || c.NextCode == Next {
|
||||
if c.ActionCode != errs.NoError || c.ErrCode != errs.NoError {
|
||||
return errs.NewCodeError(int(c.ErrCode), c.ErrMsg).WithDetail(c.ErrDlt)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package callbackstruct
|
||||
|
||||
const CallbackBeforeInviteJoinGroupCommand = "callbackBeforeInviteJoinGroupCommand"
|
||||
const CallbackAfterJoinGroupCommand = "callbackAfterJoinGroupCommand"
|
||||
const CallbackAfterSetGroupInfoCommand = "callbackAfterSetGroupInfoCommand"
|
||||
const CallbackBeforeSetGroupInfoCommand = "callbackBeforeSetGroupInfoCommand"
|
||||
|
||||
const CallbackAfterRevokeMsgCommand = "callbackBeforeAfterMsgCommand"
|
||||
const CallbackBeforeAddBlackCommand = "callbackBeforeAddBlackCommand"
|
||||
const CallbackAfterAddFriendCommand = "callbackAfterAddFriendCommand"
|
||||
const CallbackBeforeAddFriendAgreeCommand = "callbackBeforeAddFriendAgreeCommand"
|
||||
|
||||
const CallbackAfterDeleteFriendCommand = "callbackAfterDeleteFriendCommand"
|
||||
const CallbackBeforeImportFriendsCommand = "callbackBeforeImportFriendsCommand"
|
||||
const CallbackAfterImportFriendsCommand = "callbackAfterImportFriendsCommand"
|
||||
const CallbackAfterRemoveBlackCommand = "callbackAfterRemoveBlackCommand"
|
||||
|
||||
const (
|
||||
CallbackQuitGroupCommand = "callbackQuitGroupCommand"
|
||||
CallbackKillGroupCommand = "callbackKillGroupCommand"
|
||||
CallbackDisMissGroupCommand = "callbackDisMissGroupCommand"
|
||||
CallbackBeforeJoinGroupCommand = "callbackBeforeJoinGroupCommand"
|
||||
CallbackGroupMsgReadCommand = "callbackGroupMsgReadCommand"
|
||||
CallbackMsgModifyCommand = "callbackMsgModifyCommand"
|
||||
CallbackAfterUpdateUserInfoCommand = "callbackAfterUpdateUserInfoCommand"
|
||||
CallbackBeforeUserRegisterCommand = "callbackBeforeUserRegisterCommand"
|
||||
CallbackAfterUserRegisterCommand = "callbackAfterUserRegisterCommand"
|
||||
CallbackTransferGroupOwnerAfter = "callbackTransferGroupOwnerAfter"
|
||||
CallbackBeforeSetFriendRemark = "callbackBeforeSetFriendRemark"
|
||||
CallbackAfterSetFriendRemark = "callbackAfterSetFriendRemark"
|
||||
CallbackSingleMsgRead = "callbackSingleMsgRead"
|
||||
CallbackBeforeSendSingleMsgCommand = "callbackBeforeSendSingleMsgCommand"
|
||||
CallbackAfterSendSingleMsgCommand = "callbackAfterSendSingleMsgCommand"
|
||||
CallbackBeforeSendGroupMsgCommand = "callbackBeforeSendGroupMsgCommand"
|
||||
CallbackAfterSendGroupMsgCommand = "callbackAfterSendGroupMsgCommand"
|
||||
CallbackUserOnlineCommand = "callbackUserOnlineCommand"
|
||||
CallbackUserOfflineCommand = "callbackUserOfflineCommand"
|
||||
CallbackUserKickOffCommand = "callbackUserKickOffCommand"
|
||||
CallbackOfflinePushCommand = "callbackOfflinePushCommand"
|
||||
CallbackOnlinePushCommand = "callbackOnlinePushCommand"
|
||||
CallbackSuperGroupOnlinePushCommand = "callbackSuperGroupOnlinePushCommand"
|
||||
CallbackBeforeAddFriendCommand = "callbackBeforeAddFriendCommand"
|
||||
CallbackBeforeUpdateUserInfoCommand = "callbackBeforeUpdateUserInfoCommand"
|
||||
CallbackBeforeCreateGroupCommand = "callbackBeforeCreateGroupCommand"
|
||||
CallbackAfterCreateGroupCommand = "callbackAfterCreateGroupCommand"
|
||||
CallbackBeforeMemberJoinGroupCommand = "callbackBeforeMemberJoinGroupCommand"
|
||||
CallbackBeforeSetGroupMemberInfoCommand = "callbackBeforeSetGroupMemberInfoCommand"
|
||||
CallbackAfterSetGroupMemberInfoCommand = "callbackAfterSetGroupMemberInfoCommand"
|
||||
)
|
||||
@@ -19,109 +19,9 @@ type CallbackBeforeAddFriendReq struct {
|
||||
FromUserID string `json:"fromUserID" `
|
||||
ToUserID string `json:"toUserID"`
|
||||
ReqMsg string `json:"reqMsg"`
|
||||
Ex string `json:"ex"`
|
||||
OperationID string `json:"operationID"`
|
||||
}
|
||||
|
||||
type CallbackBeforeAddFriendResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallBackAddFriendReplyBeforeReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
FromUserID string `json:"fromUserID" `
|
||||
ToUserID string `json:"toUserID"`
|
||||
}
|
||||
|
||||
type CallBackAddFriendReplyBeforeResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackBeforeSetFriendRemarkReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OwnerUserID string `json:"ownerUserID"`
|
||||
FriendUserID string `json:"friendUserID"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type CallbackBeforeSetFriendRemarkResp struct {
|
||||
CommonCallbackResp
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type CallbackAfterSetFriendRemarkReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OwnerUserID string `json:"ownerUserID"`
|
||||
FriendUserID string `json:"friendUserID"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type CallbackAfterSetFriendRemarkResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
type CallbackAfterAddFriendReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
FromUserID string `json:"fromUserID" `
|
||||
ToUserID string `json:"toUserID"`
|
||||
ReqMsg string `json:"reqMsg"`
|
||||
}
|
||||
|
||||
type CallbackAfterAddFriendResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
type CallbackBeforeAddBlackReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OwnerUserID string `json:"ownerUserID" `
|
||||
BlackUserID string `json:"blackUserID"`
|
||||
}
|
||||
|
||||
type CallbackBeforeAddBlackResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackBeforeAddFriendAgreeReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
FromUserID string `json:"fromUserID" `
|
||||
ToUserID string `json:"blackUserID"`
|
||||
HandleResult int32 `json:"HandleResult"`
|
||||
HandleMsg string `json:"HandleMsg"`
|
||||
}
|
||||
|
||||
type CallbackBeforeAddFriendAgreeResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackAfterDeleteFriendReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OwnerUserID string `json:"ownerUserID" `
|
||||
FriendUserID string `json:"friendUserID"`
|
||||
}
|
||||
type CallbackAfterDeleteFriendResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackBeforeImportFriendsReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OwnerUserID string `json:"ownerUserID" `
|
||||
FriendUserIDs []string `json:"friendUserIDs"`
|
||||
}
|
||||
type CallbackBeforeImportFriendsResp struct {
|
||||
CommonCallbackResp
|
||||
FriendUserIDs []string `json:"friendUserIDs"`
|
||||
}
|
||||
type CallbackAfterImportFriendsReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OwnerUserID string `json:"ownerUserID" `
|
||||
FriendUserIDs []string `json:"friendUserIDs"`
|
||||
}
|
||||
type CallbackAfterImportFriendsResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackAfterRemoveBlackReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OwnerUserID string `json:"ownerUserID"`
|
||||
BlackUserID string `json:"blackUserID"`
|
||||
}
|
||||
type CallbackAfterRemoveBlackResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
@@ -50,18 +50,9 @@ type CallbackBeforeCreateGroupResp struct {
|
||||
ApplyMemberFriend *int32 `json:"applyMemberFriend"`
|
||||
}
|
||||
|
||||
type CallbackAfterCreateGroupReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
*common.GroupInfo
|
||||
InitMemberList []*apistruct.GroupAddMemberInfo `json:"initMemberList"`
|
||||
}
|
||||
|
||||
type CallbackAfterCreateGroupResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackBeforeMemberJoinGroupReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OperationID string `json:"operationID"`
|
||||
GroupID string `json:"groupID"`
|
||||
UserID string `json:"userID"`
|
||||
Ex string `json:"ex"`
|
||||
@@ -79,6 +70,7 @@ type CallbackBeforeMemberJoinGroupResp struct {
|
||||
|
||||
type CallbackBeforeSetGroupMemberInfoReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OperationID string `json:"operationID"`
|
||||
GroupID string `json:"groupID"`
|
||||
UserID string `json:"userID"`
|
||||
Nickname *string `json:"nickName"`
|
||||
@@ -94,142 +86,3 @@ type CallbackBeforeSetGroupMemberInfoResp struct {
|
||||
FaceURL *string `json:"faceURL"`
|
||||
RoleLevel *int32 `json:"roleLevel"`
|
||||
}
|
||||
|
||||
type CallbackAfterSetGroupMemberInfoReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
GroupID string `json:"groupID"`
|
||||
UserID string `json:"userID"`
|
||||
Nickname *string `json:"nickName"`
|
||||
FaceURL *string `json:"faceURL"`
|
||||
RoleLevel *int32 `json:"roleLevel"`
|
||||
Ex *string `json:"ex"`
|
||||
}
|
||||
|
||||
type CallbackAfterSetGroupMemberInfoResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackQuitGroupReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
GroupID string `json:"groupID"`
|
||||
UserID string `json:"userID"`
|
||||
}
|
||||
|
||||
type CallbackQuitGroupResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackKillGroupMemberReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
GroupID string `json:"groupID"`
|
||||
KickedUserIDs []string `json:"kickedUserIDs"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
type CallbackKillGroupMemberResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackDisMissGroupReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
GroupID string `json:"groupID"`
|
||||
OwnerID string `json:"ownerID"`
|
||||
GroupType string `json:"groupType"`
|
||||
MembersID []string `json:"membersID"`
|
||||
}
|
||||
|
||||
type CallbackDisMissGroupResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackJoinGroupReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
GroupID string `json:"groupID"`
|
||||
GroupType string `json:"groupType"`
|
||||
ApplyID string `json:"applyID"`
|
||||
ReqMessage string `json:"reqMessage"`
|
||||
}
|
||||
|
||||
type CallbackJoinGroupResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackTransferGroupOwnerReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
GroupID string `json:"groupID"`
|
||||
OldOwnerUserID string `json:"oldOwnerUserID"`
|
||||
NewOwnerUserID string `json:"newOwnerUserID"`
|
||||
}
|
||||
|
||||
type CallbackTransferGroupOwnerResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackBeforeInviteUserToGroupReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OperationID string `json:"operationID"`
|
||||
GroupID string `json:"groupID"`
|
||||
Reason string `json:"reason"`
|
||||
InvitedUserIDs []string `json:"invitedUserIDs"`
|
||||
}
|
||||
type CallbackBeforeInviteUserToGroupResp struct {
|
||||
CommonCallbackResp
|
||||
RefusedMembersAccount []string `json:"refusedMembersAccount,omitempty"` // Optional field to list members whose invitation is refused.
|
||||
}
|
||||
|
||||
type CallbackAfterJoinGroupReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OperationID string `json:"operationID"`
|
||||
GroupID string `json:"groupID"`
|
||||
ReqMessage string `json:"reqMessage"`
|
||||
JoinSource int32 `json:"joinSource"`
|
||||
InviterUserID string `json:"inviterUserID"`
|
||||
}
|
||||
type CallbackAfterJoinGroupResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackBeforeSetGroupInfoReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OperationID string `json:"operationID"`
|
||||
GroupID string `json:"groupID"`
|
||||
GroupName string `json:"groupName"`
|
||||
Notification string `json:"notification"`
|
||||
Introduction string `json:"introduction"`
|
||||
FaceURL string `json:"faceURL"`
|
||||
Ex string `json:"ex"`
|
||||
NeedVerification int32 `json:"needVerification"`
|
||||
LookMemberInfo int32 `json:"lookMemberInfo"`
|
||||
ApplyMemberFriend int32 `json:"applyMemberFriend"`
|
||||
}
|
||||
|
||||
type CallbackBeforeSetGroupInfoResp struct {
|
||||
CommonCallbackResp
|
||||
GroupID string ` json:"groupID"`
|
||||
GroupName string `json:"groupName"`
|
||||
Notification string `json:"notification"`
|
||||
Introduction string `json:"introduction"`
|
||||
FaceURL string `json:"faceURL"`
|
||||
Ex *string `json:"ex"`
|
||||
NeedVerification *int32 `json:"needVerification"`
|
||||
LookMemberInfo *int32 `json:"lookMemberInfo"`
|
||||
ApplyMemberFriend *int32 `json:"applyMemberFriend"`
|
||||
}
|
||||
|
||||
type CallbackAfterSetGroupInfoReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OperationID string `json:"operationID"`
|
||||
GroupID string `json:"groupID"`
|
||||
GroupName string `json:"groupName"`
|
||||
Notification string `json:"notification"`
|
||||
Introduction string `json:"introduction"`
|
||||
FaceURL string `json:"faceURL"`
|
||||
Ex *string `json:"ex"`
|
||||
NeedVerification *int32 `json:"needVerification"`
|
||||
LookMemberInfo *int32 `json:"lookMemberInfo"`
|
||||
ApplyMemberFriend *int32 `json:"applyMemberFriend"`
|
||||
}
|
||||
|
||||
type CallbackAfterSetGroupInfoResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
@@ -79,26 +79,3 @@ type CallbackMsgModifyCommandResp struct {
|
||||
AttachedInfo *string `json:"attachedInfo"`
|
||||
Ex *string `json:"ex"`
|
||||
}
|
||||
|
||||
type CallbackGroupMsgReadReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
SendID string `json:"sendID"`
|
||||
ReceiveID string `json:"receiveID"`
|
||||
UnreadMsgNum int64 `json:"unreadMsgNum"`
|
||||
ContentType int64 `json:"contentType"`
|
||||
}
|
||||
|
||||
type CallbackGroupMsgReadResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackSingleMsgReadReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
SendID string `json:"sendID"`
|
||||
ReceiveID string `json:"receiveID"`
|
||||
ContentType int64 `json:"contentType"`
|
||||
}
|
||||
|
||||
type CallbackSingleMsgReadResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package callbackstruct
|
||||
|
||||
type CallbackAfterRevokeMsgReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
ConversationID string `json:"conversationID"`
|
||||
Seq int64 `json:"seq"`
|
||||
UserID string `json:"userID"`
|
||||
}
|
||||
type CallbackAfterRevokeMsgResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
@@ -14,10 +14,9 @@
|
||||
|
||||
package callbackstruct
|
||||
|
||||
import "github.com/OpenIMSDK/protocol/sdkws"
|
||||
|
||||
type CallbackBeforeUpdateUserInfoReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OperationID string `json:"operationID"`
|
||||
UserID string `json:"userID"`
|
||||
Nickname *string `json:"nickName"`
|
||||
FaceURL *string `json:"faceURL"`
|
||||
@@ -29,35 +28,3 @@ type CallbackBeforeUpdateUserInfoResp struct {
|
||||
FaceURL *string `json:"faceURL"`
|
||||
Ex *string `json:"ex"`
|
||||
}
|
||||
|
||||
type CallbackAfterUpdateUserInfoReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
UserID string `json:"userID"`
|
||||
Nickname string `json:"nickName"`
|
||||
FaceURL string `json:"faceURL"`
|
||||
Ex string `json:"ex"`
|
||||
}
|
||||
type CallbackAfterUpdateUserInfoResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
type CallbackBeforeUserRegisterReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
Secret string `json:"secret"`
|
||||
Users []*sdkws.UserInfo `json:"users"`
|
||||
}
|
||||
|
||||
type CallbackBeforeUserRegisterResp struct {
|
||||
CommonCallbackResp
|
||||
Users []*sdkws.UserInfo `json:"users"`
|
||||
}
|
||||
|
||||
type CallbackAfterUserRegisterReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
Secret string `json:"secret"`
|
||||
Users []*sdkws.UserInfo `json:"users"`
|
||||
}
|
||||
|
||||
type CallbackAfterUserRegisterResp struct {
|
||||
CommonCallbackResp
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@ package cmd
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/internal/msggateway"
|
||||
v3config "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/internal/msggateway"
|
||||
v3config "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
)
|
||||
|
||||
type MsgGatewayCmd struct {
|
||||
@@ -60,19 +60,14 @@ func (m *MsgGatewayCmd) Exec() error {
|
||||
m.addRunE()
|
||||
return m.Execute()
|
||||
}
|
||||
|
||||
func (m *MsgGatewayCmd) GetPortFromConfig(portType string) int {
|
||||
switch portType {
|
||||
case constant.FlagWsPort:
|
||||
if portType == constant.FlagWsPort {
|
||||
return v3config.Config.LongConnSvr.OpenImWsPort[0]
|
||||
|
||||
case constant.FlagPort:
|
||||
} else if portType == constant.FlagPort {
|
||||
return v3config.Config.LongConnSvr.OpenImMessageGatewayPort[0]
|
||||
|
||||
case constant.FlagPrometheusPort:
|
||||
} else if portType == constant.FlagPrometheusPort {
|
||||
return v3config.Config.Prometheus.MessageGatewayPrometheusPort[0]
|
||||
|
||||
default:
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,13 +46,15 @@ func (a *RpcCmd) Exec() error {
|
||||
return a.Execute()
|
||||
}
|
||||
|
||||
func (a *RpcCmd) StartSvr(name string, rpcFn func(discov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) error {
|
||||
func (a *RpcCmd) StartSvr(
|
||||
name string,
|
||||
rpcFn func(discov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error,
|
||||
) error {
|
||||
if a.GetPortFlag() == 0 {
|
||||
return errors.New("port is required")
|
||||
}
|
||||
return startrpc.Start(a.GetPortFlag(), name, a.GetPrometheusPortFlag(), rpcFn)
|
||||
}
|
||||
|
||||
func (a *RpcCmd) GetPortFromConfig(portType string) int {
|
||||
switch a.Name {
|
||||
case RpcPushServer:
|
||||
|
||||
@@ -45,18 +45,6 @@ type POfflinePush struct {
|
||||
Ext string `yaml:"ext"`
|
||||
}
|
||||
|
||||
type MYSQL struct {
|
||||
Address []string `yaml:"address"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
Database string `yaml:"database"`
|
||||
MaxOpenConn int `yaml:"maxOpenConn"`
|
||||
MaxIdleConn int `yaml:"maxIdleConn"`
|
||||
MaxLifeTime int `yaml:"maxLifeTime"`
|
||||
LogLevel int `yaml:"logLevel"`
|
||||
SlowThreshold int `yaml:"slowThreshold"`
|
||||
}
|
||||
|
||||
type configStruct struct {
|
||||
Envs struct {
|
||||
Discovery string `yaml:"discovery"`
|
||||
@@ -68,7 +56,17 @@ type configStruct struct {
|
||||
Password string `yaml:"password"`
|
||||
} `yaml:"zookeeper"`
|
||||
|
||||
Mysql *MYSQL `yaml:"mysql"`
|
||||
Mysql struct {
|
||||
Address []string `yaml:"address"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
Database string `yaml:"database"`
|
||||
MaxOpenConn int `yaml:"maxOpenConn"`
|
||||
MaxIdleConn int `yaml:"maxIdleConn"`
|
||||
MaxLifeTime int `yaml:"maxLifeTime"`
|
||||
LogLevel int `yaml:"logLevel"`
|
||||
SlowThreshold int `yaml:"slowThreshold"`
|
||||
} `yaml:"mysql"`
|
||||
|
||||
Mongo struct {
|
||||
Uri string `yaml:"uri"`
|
||||
@@ -155,15 +153,6 @@ type configStruct struct {
|
||||
SessionToken string `yaml:"sessionToken"`
|
||||
PublicRead bool `yaml:"publicRead"`
|
||||
} `yaml:"oss"`
|
||||
Kodo struct {
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
Bucket string `yaml:"bucket"`
|
||||
BucketURL string `yaml:"bucketURL"`
|
||||
AccessKeyID string `yaml:"accessKeyID"`
|
||||
AccessKeySecret string `yaml:"accessKeySecret"`
|
||||
SessionToken string `yaml:"sessionToken"`
|
||||
PublicRead bool `yaml:"publicRead"`
|
||||
} `yaml:"kodo"`
|
||||
} `yaml:"object"`
|
||||
|
||||
RpcPort struct {
|
||||
@@ -265,8 +254,6 @@ type configStruct struct {
|
||||
CallbackBeforeSendGroupMsg CallBackConfig `yaml:"beforeSendGroupMsg"`
|
||||
CallbackAfterSendGroupMsg CallBackConfig `yaml:"afterSendGroupMsg"`
|
||||
CallbackMsgModify CallBackConfig `yaml:"msgModify"`
|
||||
CallbackSingleMsgRead CallBackConfig `yaml:"singleMsgRead"`
|
||||
CallbackGroupMsgRead CallBackConfig `yaml:"groupMsgRead"`
|
||||
CallbackUserOnline CallBackConfig `yaml:"userOnline"`
|
||||
CallbackUserOffline CallBackConfig `yaml:"userOffline"`
|
||||
CallbackUserKickOff CallBackConfig `yaml:"userKickOff"`
|
||||
@@ -274,35 +261,10 @@ type configStruct struct {
|
||||
CallbackOnlinePush CallBackConfig `yaml:"onlinePush"`
|
||||
CallbackBeforeSuperGroupOnlinePush CallBackConfig `yaml:"superGroupOnlinePush"`
|
||||
CallbackBeforeAddFriend CallBackConfig `yaml:"beforeAddFriend"`
|
||||
CallbackBeforeSetFriendRemark CallBackConfig `yaml:"callbackBeforeSetFriendRemark"`
|
||||
CallbackAfterSetFriendRemark CallBackConfig `yaml:"callbackAfterSetFriendRemark"`
|
||||
CallbackBeforeUpdateUserInfo CallBackConfig `yaml:"beforeUpdateUserInfo"`
|
||||
CallbackBeforeUserRegister CallBackConfig `yaml:"beforeUserRegister"`
|
||||
CallbackAfterUpdateUserInfo CallBackConfig `yaml:"updateUserInfo"`
|
||||
CallbackAfterUserRegister CallBackConfig `yaml:"afterUserRegister"`
|
||||
CallbackBeforeCreateGroup CallBackConfig `yaml:"beforeCreateGroup"`
|
||||
CallbackAfterCreateGroup CallBackConfig `yaml:"afterCreateGroup"`
|
||||
CallbackBeforeMemberJoinGroup CallBackConfig `yaml:"beforeMemberJoinGroup"`
|
||||
CallbackBeforeSetGroupMemberInfo CallBackConfig `yaml:"beforeSetGroupMemberInfo"`
|
||||
CallbackAfterSetGroupMemberInfo CallBackConfig `yaml:"afterSetGroupMemberInfo"`
|
||||
CallbackQuitGroup CallBackConfig `yaml:"quitGroup"`
|
||||
CallbackKillGroupMember CallBackConfig `yaml:"killGroupMember"`
|
||||
CallbackDismissGroup CallBackConfig `yaml:"dismissGroup"`
|
||||
CallbackBeforeJoinGroup CallBackConfig `yaml:"joinGroup"`
|
||||
CallbackTransferGroupOwnerAfter CallBackConfig `yaml:"transferGroupOwner"`
|
||||
CallbackBeforeInviteUserToGroup CallBackConfig `yaml:"beforeInviteUserToGroup"`
|
||||
CallbackAfterJoinGroup CallBackConfig `yaml:"joinGroupAfter"`
|
||||
CallbackAfterSetGroupInfo CallBackConfig `yaml:"setGroupInfoAfter"`
|
||||
CallbackBeforeSetGroupInfo CallBackConfig `yaml:"setGroupInfoBefore"`
|
||||
CallbackAfterRevokeMsg CallBackConfig `yaml:"revokeMsgAfter"`
|
||||
CallbackBeforeAddBlack CallBackConfig `yaml:"addBlackBefore"`
|
||||
CallbackAfterAddFriend CallBackConfig `yaml:"addFriendAfter"`
|
||||
CallbackBeforeAddFriendAgree CallBackConfig `yaml:"addFriendAgreeBefore"`
|
||||
|
||||
CallbackAfterDeleteFriend CallBackConfig `yaml:"deleteFriendAfter"`
|
||||
CallbackBeforeImportFriends CallBackConfig `yaml:"importFriendsBefore"`
|
||||
CallbackAfterImportFriends CallBackConfig `yaml:"importFriendsAfter"`
|
||||
CallbackAfterRemoveBlack CallBackConfig `yaml:"removeBlackAfter"`
|
||||
} `yaml:"callback"`
|
||||
|
||||
Prometheus struct {
|
||||
|
||||
@@ -35,7 +35,7 @@ const (
|
||||
DefaultFolderPath = "../config/"
|
||||
)
|
||||
|
||||
// return absolude path join ../config/, this is k8s container config path.
|
||||
// return absolude path join ../config/, this is k8s container config path
|
||||
func GetDefaultConfigPath() string {
|
||||
b, err := filepath.Abs(os.Args[0])
|
||||
if err != nil {
|
||||
@@ -45,7 +45,7 @@ func GetDefaultConfigPath() string {
|
||||
return filepath.Join(filepath.Dir(b), "../config/")
|
||||
}
|
||||
|
||||
// getProjectRoot returns the absolute path of the project root directory.
|
||||
// getProjectRoot returns the absolute path of the project root directory
|
||||
func GetProjectRoot() string {
|
||||
b, _ := filepath.Abs(os.Args[0])
|
||||
|
||||
@@ -71,7 +71,7 @@ func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options {
|
||||
return opts
|
||||
}
|
||||
|
||||
func initConfig(config any, configName, configFolderPath string) error {
|
||||
func initConfig(config interface{}, configName, configFolderPath string) error {
|
||||
configFolderPath = filepath.Join(configFolderPath, configName)
|
||||
_, err := os.Stat(configFolderPath)
|
||||
if err != nil {
|
||||
|
||||
@@ -76,7 +76,7 @@ func TestGetOptionsByNotification(t *testing.T) {
|
||||
|
||||
func Test_initConfig(t *testing.T) {
|
||||
type args struct {
|
||||
config any
|
||||
config interface{}
|
||||
configName string
|
||||
configFolderPath string
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ package convert
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
@@ -32,22 +31,23 @@ func FriendPb2DB(friend *sdkws.FriendInfo) *relation.FriendModel {
|
||||
return dbFriend
|
||||
}
|
||||
|
||||
func FriendDB2Pb(ctx context.Context, friendDB *relation.FriendModel,
|
||||
func FriendDB2Pb(
|
||||
ctx context.Context,
|
||||
friendDB *relation.FriendModel,
|
||||
getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error),
|
||||
) (*sdkws.FriendInfo, error) {
|
||||
pbfriend := &sdkws.FriendInfo{FriendUser: &sdkws.UserInfo{}}
|
||||
utils.CopyStructFields(pbfriend, friendDB)
|
||||
users, err := getUsers(ctx, []string{friendDB.FriendUserID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user, ok := users[friendDB.FriendUserID]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user not found: %s", friendDB.FriendUserID)
|
||||
}
|
||||
|
||||
return &sdkws.FriendInfo{
|
||||
FriendUser: user,
|
||||
CreateTime: friendDB.CreateTime.Unix(),
|
||||
}, nil
|
||||
pbfriend.FriendUser.UserID = users[friendDB.FriendUserID].UserID
|
||||
pbfriend.FriendUser.Nickname = users[friendDB.FriendUserID].Nickname
|
||||
pbfriend.FriendUser.FaceURL = users[friendDB.FriendUserID].FaceURL
|
||||
pbfriend.FriendUser.Ex = users[friendDB.FriendUserID].Ex
|
||||
pbfriend.CreateTime = friendDB.CreateTime.Unix()
|
||||
return pbfriend, nil
|
||||
}
|
||||
|
||||
func FriendsDB2Pb(
|
||||
@@ -118,37 +118,3 @@ func FriendRequestDB2Pb(
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// FriendPb2DBMap converts a FriendInfo protobuf object to a map suitable for database operations.
|
||||
// It only includes non-zero or non-empty fields in the map.
|
||||
func FriendPb2DBMap(friend *sdkws.FriendInfo) map[string]any {
|
||||
if friend == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
val := make(map[string]any)
|
||||
|
||||
// Assuming FriendInfo has similar fields to those in FriendModel.
|
||||
// Add or remove fields based on your actual FriendInfo and FriendModel structures.
|
||||
if friend.FriendUser != nil {
|
||||
if friend.FriendUser.UserID != "" {
|
||||
val["friend_user_id"] = friend.FriendUser.UserID
|
||||
}
|
||||
if friend.FriendUser.Nickname != "" {
|
||||
val["nickname"] = friend.FriendUser.Nickname
|
||||
}
|
||||
if friend.FriendUser.FaceURL != "" {
|
||||
val["face_url"] = friend.FriendUser.FaceURL
|
||||
}
|
||||
if friend.FriendUser.Ex != "" {
|
||||
val["ex"] = friend.FriendUser.Ex
|
||||
}
|
||||
}
|
||||
if friend.CreateTime != 0 {
|
||||
val["create_time"] = friend.CreateTime // You might need to convert this to a proper time format.
|
||||
}
|
||||
|
||||
// Include other fields from FriendInfo as needed, similar to the above pattern.
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
@@ -22,53 +22,29 @@ import (
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func UsersDB2Pb(users []*relationtb.UserModel) []*sdkws.UserInfo {
|
||||
result := make([]*sdkws.UserInfo, 0, len(users))
|
||||
func UsersDB2Pb(users []*relationtb.UserModel) (result []*sdkws.UserInfo) {
|
||||
for _, user := range users {
|
||||
userPb := &sdkws.UserInfo{
|
||||
UserID: user.UserID,
|
||||
Nickname: user.Nickname,
|
||||
FaceURL: user.FaceURL,
|
||||
Ex: user.Ex,
|
||||
CreateTime: user.CreateTime.UnixMilli(),
|
||||
AppMangerLevel: user.AppMangerLevel,
|
||||
GlobalRecvMsgOpt: user.GlobalRecvMsgOpt,
|
||||
}
|
||||
result = append(result, userPb)
|
||||
var userPb sdkws.UserInfo
|
||||
userPb.UserID = user.UserID
|
||||
userPb.Nickname = user.Nickname
|
||||
userPb.FaceURL = user.FaceURL
|
||||
userPb.Ex = user.Ex
|
||||
userPb.CreateTime = user.CreateTime.UnixMilli()
|
||||
userPb.AppMangerLevel = user.AppMangerLevel
|
||||
userPb.GlobalRecvMsgOpt = user.GlobalRecvMsgOpt
|
||||
result = append(result, &userPb)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func UserPb2DB(user *sdkws.UserInfo) *relationtb.UserModel {
|
||||
return &relationtb.UserModel{
|
||||
UserID: user.UserID,
|
||||
Nickname: user.Nickname,
|
||||
FaceURL: user.FaceURL,
|
||||
Ex: user.Ex,
|
||||
CreateTime: time.UnixMilli(user.CreateTime),
|
||||
AppMangerLevel: user.AppMangerLevel,
|
||||
GlobalRecvMsgOpt: user.GlobalRecvMsgOpt,
|
||||
}
|
||||
}
|
||||
|
||||
func UserPb2DBMap(user *sdkws.UserInfo) map[string]any {
|
||||
if user == nil {
|
||||
return nil
|
||||
}
|
||||
val := make(map[string]any)
|
||||
fields := map[string]any{
|
||||
"nickname": user.Nickname,
|
||||
"face_url": user.FaceURL,
|
||||
"ex": user.Ex,
|
||||
"app_manager_level": user.AppMangerLevel,
|
||||
"global_recv_msg_opt": user.GlobalRecvMsgOpt,
|
||||
}
|
||||
for key, value := range fields {
|
||||
if v, ok := value.(string); ok && v != "" {
|
||||
val[key] = v
|
||||
} else if v, ok := value.(int32); ok && v != 0 {
|
||||
val[key] = v
|
||||
}
|
||||
}
|
||||
return val
|
||||
var userDB relationtb.UserModel
|
||||
userDB.UserID = user.UserID
|
||||
userDB.Nickname = user.Nickname
|
||||
userDB.FaceURL = user.FaceURL
|
||||
userDB.Ex = user.Ex
|
||||
userDB.CreateTime = time.UnixMilli(user.CreateTime)
|
||||
userDB.AppMangerLevel = user.AppMangerLevel
|
||||
userDB.GlobalRecvMsgOpt = user.GlobalRecvMsgOpt
|
||||
return &userDB
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package convert
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func TestUsersDB2Pb(t *testing.T) {
|
||||
type args struct {
|
||||
users []*relationtb.UserModel
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantResult []*sdkws.UserInfo
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotResult := UsersDB2Pb(tt.args.users); !reflect.DeepEqual(gotResult, tt.wantResult) {
|
||||
t.Errorf("UsersDB2Pb() = %v, want %v", gotResult, tt.wantResult)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserPb2DB(t *testing.T) {
|
||||
type args struct {
|
||||
user *sdkws.UserInfo
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *relationtb.UserModel
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := UserPb2DB(tt.args.user); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("UserPb2DB() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserPb2DBMap(t *testing.T) {
|
||||
user := &sdkws.UserInfo{
|
||||
Nickname: "TestUser",
|
||||
FaceURL: "http://openim.io/logo.jpg",
|
||||
Ex: "Extra Data",
|
||||
AppMangerLevel: 1,
|
||||
GlobalRecvMsgOpt: 2,
|
||||
}
|
||||
|
||||
expected := map[string]any{
|
||||
"nickname": "TestUser",
|
||||
"face_url": "http://openim.io/logo.jpg",
|
||||
"ex": "Extra Data",
|
||||
"app_manager_level": int32(1),
|
||||
"global_recv_msg_opt": int32(2),
|
||||
}
|
||||
|
||||
result := UserPb2DBMap(user)
|
||||
if !reflect.DeepEqual(result, expected) {
|
||||
t.Errorf("UserPb2DBMap returned unexpected map. Got %v, want %v", result, expected)
|
||||
}
|
||||
}
|
||||
69
pkg/common/db/cache/conversation.go
vendored
69
pkg/common/db/cache/conversation.go
vendored
@@ -26,6 +26,7 @@ import (
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
@@ -66,10 +67,10 @@ type ConversationCache interface {
|
||||
GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error)
|
||||
DelUserRecvMsgOpt(ownerUserID, conversationID string) ConversationCache
|
||||
// get one super group recv msg but do not notification userID list
|
||||
//GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error)
|
||||
GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error)
|
||||
DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) ConversationCache
|
||||
// get one super group recv msg but do not notification userID list hash
|
||||
//GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error)
|
||||
GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error)
|
||||
DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache
|
||||
|
||||
//GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error)
|
||||
@@ -100,20 +101,20 @@ type ConversationRedisCache struct {
|
||||
expireTime time.Duration
|
||||
}
|
||||
|
||||
//func NewNewConversationRedis(
|
||||
// rdb redis.UniversalClient,
|
||||
// conversationDB *relation.ConversationGorm,
|
||||
// options rockscache.Options,
|
||||
//) ConversationCache {
|
||||
// rcClient := rockscache.NewClient(rdb, options)
|
||||
//
|
||||
// return &ConversationRedisCache{
|
||||
// rcClient: rcClient,
|
||||
// metaCache: NewMetaCacheRedis(rcClient),
|
||||
// conversationDB: conversationDB,
|
||||
// expireTime: conversationExpireTime,
|
||||
// }
|
||||
//}
|
||||
func NewNewConversationRedis(
|
||||
rdb redis.UniversalClient,
|
||||
conversationDB *relation.ConversationGorm,
|
||||
options rockscache.Options,
|
||||
) ConversationCache {
|
||||
rcClient := rockscache.NewClient(rdb, options)
|
||||
|
||||
return &ConversationRedisCache{
|
||||
rcClient: rcClient,
|
||||
metaCache: NewMetaCacheRedis(rcClient),
|
||||
conversationDB: conversationDB,
|
||||
expireTime: conversationExpireTime,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) NewCache() ConversationCache {
|
||||
return &ConversationRedisCache{
|
||||
@@ -281,11 +282,11 @@ func (c *ConversationRedisCache) GetUserRecvMsgOpt(ctx context.Context, ownerUse
|
||||
})
|
||||
}
|
||||
|
||||
//func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) {
|
||||
// return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsKey(groupID), c.expireTime, func(ctx context.Context) (userIDs []string, err error) {
|
||||
// return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
// })
|
||||
//}
|
||||
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) {
|
||||
return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsKey(groupID), c.expireTime, func(ctx context.Context) (userIDs []string, err error) {
|
||||
return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache {
|
||||
keys := make([]string, 0, len(ownerUserIDs))
|
||||
@@ -312,19 +313,19 @@ func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDs(groupID st
|
||||
return cache
|
||||
}
|
||||
|
||||
//func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) {
|
||||
// return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID), c.expireTime, func(ctx context.Context) (hash uint64, err error) {
|
||||
// userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// utils.Sort(userIDs, true)
|
||||
// bi := big.NewInt(0)
|
||||
// bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
|
||||
// return bi.Uint64(), nil
|
||||
// },
|
||||
// )
|
||||
//}
|
||||
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) {
|
||||
return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID), c.expireTime, func(ctx context.Context) (hash uint64, err error) {
|
||||
userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
utils.Sort(userIDs, true)
|
||||
bi := big.NewInt(0)
|
||||
bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
|
||||
return bi.Uint64(), nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache {
|
||||
cache := c.NewCache()
|
||||
|
||||
24
pkg/common/db/cache/friend.go
vendored
24
pkg/common/db/cache/friend.go
vendored
@@ -33,20 +33,19 @@ const (
|
||||
friendKey = "FRIEND_INFO:"
|
||||
)
|
||||
|
||||
// FriendCache is an interface for caching friend-related data.
|
||||
// args fn will exec when no data in msgCache.
|
||||
type FriendCache interface {
|
||||
metaCache
|
||||
NewCache() FriendCache
|
||||
GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error)
|
||||
// Called when friendID list changed
|
||||
// call when friendID List changed
|
||||
DelFriendIDs(ownerUserID ...string) FriendCache
|
||||
// Get single friendInfo from the cache
|
||||
// get single friendInfo from msgCache
|
||||
GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error)
|
||||
// Delete friend when friend info changed
|
||||
// del friend when friend info changed
|
||||
DelFriend(ownerUserID, friendUserID string) FriendCache
|
||||
}
|
||||
|
||||
// FriendCacheRedis is an implementation of the FriendCache interface using Redis.
|
||||
type FriendCacheRedis struct {
|
||||
metaCache
|
||||
friendDB relationtb.FriendModelInterface
|
||||
@@ -54,7 +53,6 @@ type FriendCacheRedis struct {
|
||||
rcClient *rockscache.Client
|
||||
}
|
||||
|
||||
// NewFriendCacheRedis creates a new instance of FriendCacheRedis.
|
||||
func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendModelInterface,
|
||||
options rockscache.Options) FriendCache {
|
||||
rcClient := rockscache.NewClient(rdb, options)
|
||||
@@ -66,7 +64,6 @@ func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendMo
|
||||
}
|
||||
}
|
||||
|
||||
// NewCache creates a new instance of FriendCacheRedis with the same configuration.
|
||||
func (f *FriendCacheRedis) NewCache() FriendCache {
|
||||
return &FriendCacheRedis{
|
||||
rcClient: f.rcClient,
|
||||
@@ -76,29 +73,24 @@ func (f *FriendCacheRedis) NewCache() FriendCache {
|
||||
}
|
||||
}
|
||||
|
||||
// getFriendIDsKey returns the key for storing friend IDs in the cache.
|
||||
func (f *FriendCacheRedis) getFriendIDsKey(ownerUserID string) string {
|
||||
return friendIDsKey + ownerUserID
|
||||
}
|
||||
|
||||
// getTwoWayFriendsIDsKey returns the key for storing two-way friend IDs in the cache.
|
||||
func (f *FriendCacheRedis) getTwoWayFriendsIDsKey(ownerUserID string) string {
|
||||
return TwoWayFriendsIDsKey + ownerUserID
|
||||
}
|
||||
|
||||
// getFriendKey returns the key for storing friend info in the cache.
|
||||
func (f *FriendCacheRedis) getFriendKey(ownerUserID, friendUserID string) string {
|
||||
return friendKey + ownerUserID + "-" + friendUserID
|
||||
}
|
||||
|
||||
// GetFriendIDs retrieves friend IDs from the cache or the database if not found.
|
||||
func (f *FriendCacheRedis) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) {
|
||||
return getCache(ctx, f.rcClient, f.getFriendIDsKey(ownerUserID), f.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return f.friendDB.FindFriendUserIDs(ctx, ownerUserID)
|
||||
})
|
||||
}
|
||||
|
||||
// DelFriendIDs deletes friend IDs from the cache.
|
||||
func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) FriendCache {
|
||||
newGroupCache := f.NewCache()
|
||||
keys := make([]string, 0, len(ownerUserIDs))
|
||||
@@ -110,7 +102,7 @@ func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) FriendCache {
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
// GetTwoWayFriendIDs retrieves two-way friend IDs from the cache.
|
||||
// todo.
|
||||
func (f *FriendCacheRedis) GetTwoWayFriendIDs(ctx context.Context, ownerUserID string) (twoWayFriendIDs []string, err error) {
|
||||
friendIDs, err := f.GetFriendIDs(ctx, ownerUserID)
|
||||
if err != nil {
|
||||
@@ -129,7 +121,6 @@ func (f *FriendCacheRedis) GetTwoWayFriendIDs(ctx context.Context, ownerUserID s
|
||||
return twoWayFriendIDs, nil
|
||||
}
|
||||
|
||||
// DelTwoWayFriendIDs deletes two-way friend IDs from the cache.
|
||||
func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, ownerUserID string) FriendCache {
|
||||
newFriendCache := f.NewCache()
|
||||
newFriendCache.AddKeys(f.getTwoWayFriendsIDsKey(ownerUserID))
|
||||
@@ -137,15 +128,14 @@ func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, ownerUserID s
|
||||
return newFriendCache
|
||||
}
|
||||
|
||||
// GetFriend retrieves friend info from the cache or the database if not found.
|
||||
func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error) {
|
||||
func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID,
|
||||
friendUserID string) (friend *relationtb.FriendModel, err error) {
|
||||
return getCache(ctx, f.rcClient, f.getFriendKey(ownerUserID,
|
||||
friendUserID), f.expireTime, func(ctx context.Context) (*relationtb.FriendModel, error) {
|
||||
return f.friendDB.Take(ctx, ownerUserID, friendUserID)
|
||||
})
|
||||
}
|
||||
|
||||
// DelFriend deletes friend info from the cache.
|
||||
func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string) FriendCache {
|
||||
newFriendCache := f.NewCache()
|
||||
newFriendCache.AddKeys(f.getFriendKey(ownerUserID, friendUserID))
|
||||
|
||||
295
pkg/common/db/cache/group.go
vendored
295
pkg/common/db/cache/group.go
vendored
@@ -16,13 +16,8 @@ package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
|
||||
"github.com/dtm-labs/rockscache"
|
||||
@@ -31,24 +26,21 @@ import (
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
)
|
||||
|
||||
const (
|
||||
groupExpireTime = time.Second * 60 * 60 * 12
|
||||
groupInfoKey = "GROUP_INFO:"
|
||||
groupMemberIDsKey = "GROUP_MEMBER_IDS:"
|
||||
groupMembersHashKey = "GROUP_MEMBERS_HASH2:"
|
||||
groupMemberInfoKey = "GROUP_MEMBER_INFO:"
|
||||
//groupOwnerInfoKey = "GROUP_OWNER_INFO:".
|
||||
joinedGroupsKey = "JOIN_GROUPS_KEY:"
|
||||
groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
|
||||
groupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:"
|
||||
groupExpireTime = time.Second * 60 * 60 * 12
|
||||
groupInfoKey = "GROUP_INFO:"
|
||||
groupMemberIDsKey = "GROUP_MEMBER_IDS:"
|
||||
groupMembersHashKey = "GROUP_MEMBERS_HASH2:"
|
||||
groupMemberInfoKey = "GROUP_MEMBER_INFO:"
|
||||
joinedSuperGroupsKey = "JOIN_SUPER_GROUPS:"
|
||||
SuperGroupMemberIDsKey = "SUPER_GROUP_MEMBER_IDS:"
|
||||
joinedGroupsKey = "JOIN_GROUPS_KEY:"
|
||||
groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
|
||||
)
|
||||
|
||||
type GroupHash interface {
|
||||
GetGroupHash(ctx context.Context, groupID string) (uint64, error)
|
||||
}
|
||||
|
||||
type GroupCache interface {
|
||||
metaCache
|
||||
NewCache() GroupCache
|
||||
@@ -56,6 +48,11 @@ type GroupCache interface {
|
||||
GetGroupInfo(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error)
|
||||
DelGroupsInfo(groupIDs ...string) GroupCache
|
||||
|
||||
GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error)
|
||||
DelJoinedSuperGroupIDs(userIDs ...string) GroupCache
|
||||
GetSuperGroupMemberIDs(ctx context.Context, groupIDs ...string) (models []*unrelationtb.SuperGroupModel, err error)
|
||||
DelSuperGroupMemberIDs(groupIDs ...string) GroupCache
|
||||
|
||||
GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error)
|
||||
GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error)
|
||||
DelGroupMembersHash(groupID string) GroupCache
|
||||
@@ -72,16 +69,9 @@ type GroupCache interface {
|
||||
GetGroupMembersInfo(ctx context.Context, groupID string, userID []string) (groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
GetGroupMembersPage(ctx context.Context, groupID string, userID []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error)
|
||||
|
||||
GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error)
|
||||
GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error)
|
||||
GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error)
|
||||
DelGroupRoleLevel(groupID string, roleLevel []int32) GroupCache
|
||||
DelGroupAllRoleLevel(groupID string) GroupCache
|
||||
DelGroupMembersInfo(groupID string, userID ...string) GroupCache
|
||||
GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error)
|
||||
GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error)
|
||||
|
||||
GetGroupMemberNum(ctx context.Context, groupID string) (memberNum int64, err error)
|
||||
DelGroupsMemberNum(groupID ...string) GroupCache
|
||||
}
|
||||
@@ -91,9 +81,10 @@ type GroupCacheRedis struct {
|
||||
groupDB relationtb.GroupModelInterface
|
||||
groupMemberDB relationtb.GroupMemberModelInterface
|
||||
groupRequestDB relationtb.GroupRequestModelInterface
|
||||
mongoDB unrelationtb.SuperGroupModelInterface
|
||||
expireTime time.Duration
|
||||
rcClient *rockscache.Client
|
||||
groupHash GroupHash
|
||||
hashCode func(ctx context.Context, groupID string) (uint64, error)
|
||||
}
|
||||
|
||||
func NewGroupCacheRedis(
|
||||
@@ -101,7 +92,8 @@ func NewGroupCacheRedis(
|
||||
groupDB relationtb.GroupModelInterface,
|
||||
groupMemberDB relationtb.GroupMemberModelInterface,
|
||||
groupRequestDB relationtb.GroupRequestModelInterface,
|
||||
hashCode GroupHash,
|
||||
mongoClient unrelationtb.SuperGroupModelInterface,
|
||||
hashCode func(ctx context.Context, groupID string) (uint64, error),
|
||||
opts rockscache.Options,
|
||||
) GroupCache {
|
||||
rcClient := rockscache.NewClient(rdb, opts)
|
||||
@@ -109,7 +101,8 @@ func NewGroupCacheRedis(
|
||||
return &GroupCacheRedis{
|
||||
rcClient: rcClient, expireTime: groupExpireTime,
|
||||
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
|
||||
groupHash: hashCode,
|
||||
mongoDB: mongoClient,
|
||||
hashCode: hashCode,
|
||||
metaCache: NewMetaCacheRedis(rcClient),
|
||||
}
|
||||
}
|
||||
@@ -121,6 +114,7 @@ func (g *GroupCacheRedis) NewCache() GroupCache {
|
||||
groupDB: g.groupDB,
|
||||
groupMemberDB: g.groupMemberDB,
|
||||
groupRequestDB: g.groupRequestDB,
|
||||
mongoDB: g.mongoDB,
|
||||
metaCache: NewMetaCacheRedis(g.rcClient, g.metaCache.GetPreDelKeys()...),
|
||||
}
|
||||
}
|
||||
@@ -129,10 +123,18 @@ func (g *GroupCacheRedis) getGroupInfoKey(groupID string) string {
|
||||
return groupInfoKey + groupID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getJoinedSuperGroupsIDKey(userID string) string {
|
||||
return joinedSuperGroupsKey + userID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getJoinedGroupsKey(userID string) string {
|
||||
return joinedGroupsKey + userID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getSuperGroupMemberIDsKey(groupID string) string {
|
||||
return SuperGroupMemberIDsKey + groupID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getGroupMembersHashKey(groupID string) string {
|
||||
return groupMembersHashKey + groupID
|
||||
}
|
||||
@@ -149,10 +151,6 @@ func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string {
|
||||
return groupMemberNumKey + groupID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getGroupRoleLevelMemberIDsKey(groupID string, roleLevel int32) string {
|
||||
return groupRoleLevelMemberIDsKey + groupID + "-" + strconv.Itoa(int(roleLevel))
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupIndex(group *relationtb.GroupModel, keys []string) (int, error) {
|
||||
key := g.getGroupInfoKey(group.GroupID)
|
||||
for i, _key := range keys {
|
||||
@@ -175,7 +173,15 @@ func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationtb.GroupMembe
|
||||
return 0, errIndex
|
||||
}
|
||||
|
||||
// / groupInfo.
|
||||
func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) {
|
||||
//var keys []string
|
||||
//for _, group := range groupIDs {
|
||||
// keys = append(keys, g.getGroupInfoKey(group))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupIndex, func(ctx context.Context) ([]*relationtb.GroupModel, error) {
|
||||
// return g.groupDB.Find(ctx, groupIDs)
|
||||
//})
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string {
|
||||
return g.getGroupInfoKey(groupID)
|
||||
}, func(ctx context.Context, groupID string) (*relationtb.GroupModel, error) {
|
||||
@@ -200,44 +206,123 @@ func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) GroupCache {
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelGroupsOwner(groupIDs ...string) GroupCache {
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(groupIDs))
|
||||
for _, groupID := range groupIDs {
|
||||
keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, constant.GroupOwner))
|
||||
}
|
||||
newGroupCache.AddKeys(keys...)
|
||||
|
||||
return newGroupCache
|
||||
func (g *GroupCacheRedis) GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error) {
|
||||
return getCache(ctx, g.rcClient, g.getJoinedSuperGroupsIDKey(userID), g.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
userGroup, err := g.mongoDB.GetSuperGroupByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userGroup.GroupIDs, nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelGroupRoleLevel(groupID string, roleLevels []int32) GroupCache {
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(roleLevels))
|
||||
for _, roleLevel := range roleLevels {
|
||||
keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, roleLevel))
|
||||
}
|
||||
newGroupCache.AddKeys(keys...)
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelGroupAllRoleLevel(groupID string) GroupCache {
|
||||
return g.DelGroupRoleLevel(groupID, []int32{constant.GroupOwner, constant.GroupAdmin, constant.GroupOrdinaryUsers})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
|
||||
if g.groupHash == nil {
|
||||
return 0, errs.ErrInternalServer.Wrap("group hash is nil")
|
||||
}
|
||||
return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) {
|
||||
return g.groupHash.GetGroupHash(ctx, groupID)
|
||||
func (g *GroupCacheRedis) GetSuperGroupMemberIDs(ctx context.Context, groupIDs ...string) (models []*unrelationtb.SuperGroupModel, err error) {
|
||||
//var keys []string
|
||||
//for _, group := range groupIDs {
|
||||
// keys = append(keys, g.getSuperGroupMemberIDsKey(group))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, func(model *unrelationtb.SuperGroupModel, keys []string) (int, error) {
|
||||
// for i, key := range keys {
|
||||
// if g.getSuperGroupMemberIDsKey(model.GroupID) == key {
|
||||
// return i, nil
|
||||
// }
|
||||
// }
|
||||
// return 0, errIndex
|
||||
//},
|
||||
// func(ctx context.Context) ([]*unrelationtb.SuperGroupModel, error) {
|
||||
// return g.mongoDB.FindSuperGroup(ctx, groupIDs)
|
||||
// })
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string {
|
||||
return g.getSuperGroupMemberIDsKey(groupID)
|
||||
}, func(ctx context.Context, groupID string) (*unrelationtb.SuperGroupModel, error) {
|
||||
return g.mongoDB.TakeSuperGroup(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) {
|
||||
if g.groupHash == nil {
|
||||
return nil, errs.ErrInternalServer.Wrap("group hash is nil")
|
||||
// userJoinSuperGroup.
|
||||
func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(userIDs ...string) GroupCache {
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(userIDs))
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, g.getJoinedSuperGroupsIDKey(userID))
|
||||
}
|
||||
newGroupCache.AddKeys(keys...)
|
||||
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache {
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(groupIDs))
|
||||
for _, groupID := range groupIDs {
|
||||
keys = append(keys, g.getSuperGroupMemberIDsKey(groupID))
|
||||
}
|
||||
newGroupCache.AddKeys(keys...)
|
||||
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
// groupMembersHash.
|
||||
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
|
||||
return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) {
|
||||
return g.hashCode(ctx, groupID)
|
||||
})
|
||||
|
||||
//return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime,
|
||||
// func(ctx context.Context) (uint64, error) {
|
||||
// userIDs, err := g.GetGroupMemberIDs(ctx, groupID)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "userIDs", userIDs)
|
||||
// var members []*relationtb.GroupMemberModel
|
||||
// if len(userIDs) > 0 {
|
||||
// members, err = g.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// utils.Sort(userIDs, true)
|
||||
// }
|
||||
// memberMap := make(map[string]*relationtb.GroupMemberModel)
|
||||
// for i, member := range members {
|
||||
// memberMap[member.UserID] = members[i]
|
||||
// }
|
||||
// data := make([]string, 0, len(members)*11)
|
||||
// for _, userID := range userIDs {
|
||||
// member, ok := memberMap[userID]
|
||||
// if !ok {
|
||||
// continue
|
||||
// }
|
||||
// data = append(data,
|
||||
// member.GroupID,
|
||||
// member.UserID,
|
||||
// member.Nickname,
|
||||
// member.FaceURL,
|
||||
// strconv.Itoa(int(member.RoleLevel)),
|
||||
// strconv.FormatInt(member.JoinTime.UnixMilli(), 10),
|
||||
// strconv.Itoa(int(member.JoinSource)),
|
||||
// member.InviterUserID,
|
||||
// member.OperatorUserID,
|
||||
// strconv.FormatInt(member.MuteEndTime.UnixMilli(), 10),
|
||||
// member.Ex,
|
||||
// )
|
||||
// }
|
||||
// log.ZInfo(ctx, "hash data info", "userIDs.len", len(userIDs), "hash.data.len", len(data))
|
||||
// log.ZInfo(ctx, "json hash data", "groupID", groupID, "data", data)
|
||||
// val, err := json.Marshal(data)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// sum := md5.Sum(val)
|
||||
// code := binary.BigEndian.Uint64(sum[:])
|
||||
// log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "hashCode", code, "num", len(members))
|
||||
// return code, nil
|
||||
// },
|
||||
//)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) {
|
||||
res := make(map[string]*relationtb.GroupSimpleUserID)
|
||||
for _, groupID := range groupIDs {
|
||||
hash, err := g.GetGroupMembersHash(ctx, groupID)
|
||||
@@ -262,6 +347,7 @@ func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) GroupCache {
|
||||
return cache
|
||||
}
|
||||
|
||||
// groupMemberIDs.
|
||||
func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) {
|
||||
return getCache(ctx, g.rcClient, g.getGroupMemberIDsKey(groupID), g.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return g.groupMemberDB.FindMemberUserID(ctx, groupID)
|
||||
@@ -312,6 +398,13 @@ func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userI
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) {
|
||||
//var keys []string
|
||||
//for _, userID := range userIDs {
|
||||
// keys = append(keys, g.getGroupMemberInfoKey(groupID, userID))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) {
|
||||
// return g.groupMemberDB.Find(ctx, []string{groupID}, userIDs, nil)
|
||||
//})
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, userIDs, func(userID string) string {
|
||||
return g.getGroupMemberInfoKey(groupID, userID)
|
||||
}, func(ctx context.Context, userID string) (*relationtb.GroupMemberModel, error) {
|
||||
@@ -353,6 +446,13 @@ func (g *GroupCacheRedis) GetAllGroupMemberInfo(ctx context.Context, groupID str
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//var keys []string
|
||||
//for _, groupMemberID := range groupMemberIDs {
|
||||
// keys = append(keys, g.getGroupMemberInfoKey(groupID, groupMemberID))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) {
|
||||
// return g.groupMemberDB.Find(ctx, []string{groupID}, groupMemberIDs, nil)
|
||||
//})
|
||||
return g.GetGroupMembersInfo(ctx, groupID, groupMemberIDs)
|
||||
}
|
||||
|
||||
@@ -383,68 +483,3 @@ func (g *GroupCacheRedis) DelGroupsMemberNum(groupID ...string) GroupCache {
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) {
|
||||
members, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(members) == 0 {
|
||||
return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("group %s owner not found", groupID))
|
||||
}
|
||||
return members[0], nil
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) {
|
||||
members := make([]*relationtb.GroupMemberModel, 0, len(groupIDs))
|
||||
for _, groupID := range groupIDs {
|
||||
items, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(items) > 0 {
|
||||
members = append(members, items[0])
|
||||
}
|
||||
}
|
||||
return members, nil
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) {
|
||||
return getCache(ctx, g.rcClient, g.getGroupRoleLevelMemberIDsKey(groupID, roleLevel), g.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return g.groupMemberDB.FindRoleLevelUserIDs(ctx, groupID, roleLevel)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error) {
|
||||
userIDs, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return g.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) {
|
||||
var userIDs []string
|
||||
for _, roleLevel := range roleLevels {
|
||||
ids, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userIDs = append(userIDs, ids...)
|
||||
}
|
||||
return g.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (_ []*relationtb.GroupMemberModel, err error) {
|
||||
if len(groupIDs) == 0 {
|
||||
groupIDs, err = g.GetJoinedGroupIDs(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string {
|
||||
return g.getGroupMemberInfoKey(groupID, userID)
|
||||
}, func(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.Take(ctx, groupID, userID)
|
||||
})
|
||||
}
|
||||
|
||||
24
pkg/common/db/cache/init_redis.go
vendored
24
pkg/common/db/cache/init_redis.go
vendored
@@ -18,8 +18,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
@@ -45,9 +43,6 @@ func NewRedis() (redis.UniversalClient, error) {
|
||||
return redisClient, nil
|
||||
}
|
||||
|
||||
// Read configuration from environment variables
|
||||
overrideConfigFromEnv()
|
||||
|
||||
if len(config.Config.Redis.Address) == 0 {
|
||||
return nil, errors.New("redis address is empty")
|
||||
}
|
||||
@@ -65,9 +60,9 @@ func NewRedis() (redis.UniversalClient, error) {
|
||||
rdb = redis.NewClient(&redis.Options{
|
||||
Addr: config.Config.Redis.Address[0],
|
||||
Username: config.Config.Redis.Username,
|
||||
Password: config.Config.Redis.Password,
|
||||
DB: 0, // use default DB
|
||||
PoolSize: 100, // connection pool size
|
||||
Password: config.Config.Redis.Password, // no password set
|
||||
DB: 0, // use default DB
|
||||
PoolSize: 100, // connection pool size
|
||||
MaxRetries: maxRetry,
|
||||
})
|
||||
}
|
||||
@@ -83,16 +78,3 @@ func NewRedis() (redis.UniversalClient, error) {
|
||||
redisClient = rdb
|
||||
return rdb, err
|
||||
}
|
||||
|
||||
// overrideConfigFromEnv overrides configuration fields with environment variables if present.
|
||||
func overrideConfigFromEnv() {
|
||||
if envAddr := os.Getenv("REDIS_ADDRESS"); envAddr != "" {
|
||||
config.Config.Redis.Address = strings.Split(envAddr, ",") // Assuming addresses are comma-separated
|
||||
}
|
||||
if envUser := os.Getenv("REDIS_USERNAME"); envUser != "" {
|
||||
config.Config.Redis.Username = envUser
|
||||
}
|
||||
if envPass := os.Getenv("REDIS_PASSWORD"); envPass != "" {
|
||||
config.Config.Redis.Password = envPass
|
||||
}
|
||||
}
|
||||
|
||||
7
pkg/common/db/cache/meta_cache.go
vendored
7
pkg/common/db/cache/meta_cache.go
vendored
@@ -38,7 +38,7 @@ const (
|
||||
var errIndex = errors.New("err index")
|
||||
|
||||
type metaCache interface {
|
||||
ExecDel(ctx context.Context, distinct ...bool) error
|
||||
ExecDel(ctx context.Context) error
|
||||
// delete key rapid
|
||||
DelKey(ctx context.Context, key string) error
|
||||
AddKeys(keys ...string)
|
||||
@@ -57,10 +57,7 @@ type metaCacheRedis struct {
|
||||
retryInterval time.Duration
|
||||
}
|
||||
|
||||
func (m *metaCacheRedis) ExecDel(ctx context.Context, distinct ...bool) error {
|
||||
if len(distinct) > 0 && distinct[0] {
|
||||
m.keys = utils.Distinct(m.keys)
|
||||
}
|
||||
func (m *metaCacheRedis) ExecDel(ctx context.Context) error {
|
||||
if len(m.keys) > 0 {
|
||||
log.ZDebug(ctx, "delete cache", "keys", m.keys)
|
||||
for _, key := range m.keys {
|
||||
|
||||
2
pkg/common/db/cache/msg.go
vendored
2
pkg/common/db/cache/msg.go
vendored
@@ -287,7 +287,7 @@ func (c *msgCache) GetTokensWithoutError(ctx context.Context, userID string, pla
|
||||
|
||||
func (c *msgCache) SetTokenMapByUidPid(ctx context.Context, userID string, platform int, m map[string]int) error {
|
||||
key := uidPidToken + userID + ":" + constant.PlatformIDToName(platform)
|
||||
mm := make(map[string]any)
|
||||
mm := make(map[string]interface{})
|
||||
for k, v := range m {
|
||||
mm[k] = v
|
||||
}
|
||||
|
||||
18
pkg/common/db/cache/s3.go
vendored
18
pkg/common/db/cache/s3.go
vendored
@@ -14,8 +14,8 @@ import (
|
||||
|
||||
type ObjectCache interface {
|
||||
metaCache
|
||||
GetName(ctx context.Context, engine string, name string) (*relationtb.ObjectModel, error)
|
||||
DelObjectName(engine string, names ...string) ObjectCache
|
||||
GetName(ctx context.Context, name string) (*relationtb.ObjectModel, error)
|
||||
DelObjectName(names ...string) ObjectCache
|
||||
}
|
||||
|
||||
func NewObjectCacheRedis(rdb redis.UniversalClient, objDB relationtb.ObjectInfoModelInterface) ObjectCache {
|
||||
@@ -44,23 +44,23 @@ func (g *objectCacheRedis) NewCache() ObjectCache {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *objectCacheRedis) DelObjectName(engine string, names ...string) ObjectCache {
|
||||
func (g *objectCacheRedis) DelObjectName(names ...string) ObjectCache {
|
||||
objectCache := g.NewCache()
|
||||
keys := make([]string, 0, len(names))
|
||||
for _, name := range names {
|
||||
keys = append(keys, g.getObjectKey(name, engine))
|
||||
keys = append(keys, g.getObjectKey(name))
|
||||
}
|
||||
objectCache.AddKeys(keys...)
|
||||
return objectCache
|
||||
}
|
||||
|
||||
func (g *objectCacheRedis) getObjectKey(engine string, name string) string {
|
||||
return "OBJECT:" + engine + ":" + name
|
||||
func (g *objectCacheRedis) getObjectKey(name string) string {
|
||||
return "OBJECT:" + name
|
||||
}
|
||||
|
||||
func (g *objectCacheRedis) GetName(ctx context.Context, engine string, name string) (*relationtb.ObjectModel, error) {
|
||||
return getCache(ctx, g.rcClient, g.getObjectKey(name, engine), g.expireTime, func(ctx context.Context) (*relationtb.ObjectModel, error) {
|
||||
return g.objDB.Take(ctx, engine, name)
|
||||
func (g *objectCacheRedis) GetName(ctx context.Context, name string) (*relationtb.ObjectModel, error) {
|
||||
return getCache(ctx, g.rcClient, g.getObjectKey(name), g.expireTime, func(ctx context.Context) (*relationtb.ObjectModel, error) {
|
||||
return g.objDB.Take(ctx, name)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
42
pkg/common/db/cache/user.go
vendored
42
pkg/common/db/cache/user.go
vendored
@@ -22,8 +22,6 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
@@ -33,6 +31,8 @@ import (
|
||||
|
||||
"github.com/dtm-labs/rockscache"
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -59,8 +59,7 @@ type UserCache interface {
|
||||
|
||||
type UserCacheRedis struct {
|
||||
metaCache
|
||||
rdb redis.UniversalClient
|
||||
//userDB relationtb.UserModelInterface
|
||||
rdb redis.UniversalClient
|
||||
userDB relationtb.UserModelInterface
|
||||
expireTime time.Duration
|
||||
rcClient *rockscache.Client
|
||||
@@ -101,13 +100,39 @@ func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string {
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.UserModel, err error) {
|
||||
return getCache(ctx, u.rcClient, u.getUserInfoKey(userID), u.expireTime, func(ctx context.Context) (*relationtb.UserModel, error) {
|
||||
return u.userDB.Take(ctx, userID)
|
||||
},
|
||||
return getCache(
|
||||
ctx,
|
||||
u.rcClient,
|
||||
u.getUserInfoKey(userID),
|
||||
u.expireTime,
|
||||
func(ctx context.Context) (*relationtb.UserModel, error) {
|
||||
return u.userDB.Take(ctx, userID)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.UserModel, error) {
|
||||
//var keys []string
|
||||
//for _, userID := range userIDs {
|
||||
// keys = append(keys, u.getUserInfoKey(userID))
|
||||
//}
|
||||
//return batchGetCache(
|
||||
// ctx,
|
||||
// u.rcClient,
|
||||
// keys,
|
||||
// u.expireTime,
|
||||
// func(user *relationtb.UserModel, keys []string) (int, error) {
|
||||
// for i, key := range keys {
|
||||
// if key == u.getUserInfoKey(user.UserID) {
|
||||
// return i, nil
|
||||
// }
|
||||
// }
|
||||
// return 0, errIndex
|
||||
// },
|
||||
// func(ctx context.Context) ([]*relationtb.UserModel, error) {
|
||||
// return u.userDB.Find(ctx, userIDs)
|
||||
// },
|
||||
//)
|
||||
return batchGetCache2(ctx, u.rcClient, u.expireTime, userIDs, func(userID string) string {
|
||||
return u.getUserInfoKey(userID)
|
||||
}, func(ctx context.Context, userID string) (*relationtb.UserModel, error) {
|
||||
@@ -189,7 +214,8 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, statu
|
||||
UserIDNum := crc32.ChecksumIEEE([]byte(userID))
|
||||
modKey := strconv.Itoa(int(UserIDNum % statusMod))
|
||||
key := olineStatusKey + modKey
|
||||
log.ZDebug(ctx, "SetUserStatus args", "userID", userID, "status", status, "platformID", platformID, "modKey", modKey, "key", key)
|
||||
log.ZDebug(ctx, "SetUserStatus args", "userID", userID, "status", status,
|
||||
"platformID", platformID, "modKey", modKey, "key", key)
|
||||
isNewKey, err := u.rdb.Exists(ctx, key).Result()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user