Compare commits
151 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 67ba395907 | |||
| 51ad54b039 | |||
| d0bd1f9923 | |||
| a60bce5cf7 | |||
| bb7f359829 | |||
| 79fdcc8159 | |||
| a01e7eaafb | |||
| 4c9b03ae4f | |||
| 6745b40094 | |||
| 5131fc1041 | |||
| 0aea79fd88 | |||
| ef446aa3d7 | |||
| c1761f6446 | |||
| 7b29663a4c | |||
| ff9b258229 | |||
| 38d4babf30 | |||
| 7f4de7fda7 | |||
| 859063ddba | |||
| ae0d16b06a | |||
| d3364e374f | |||
| f0ad869d29 | |||
| 84c7cc1801 | |||
| b02d65bf9a | |||
| 90659a30b6 | |||
| 3599d4b7ef | |||
| cf8bba036f | |||
| 0f05ff52a3 | |||
| ef399caa4d | |||
| b818259100 | |||
| 7e8b975e22 | |||
| 888351493a | |||
| 0953f616f0 | |||
| 5742932df5 | |||
| 1f25f7dc78 | |||
| 7994b377f7 | |||
| 45a0266b20 | |||
| a38dfb9a1d | |||
| 391e3ea10c | |||
| 8b365ae49f | |||
| e2efd7abdd | |||
| c3e721f145 | |||
| 958afd6115 | |||
| 0f2d9308e8 | |||
| 4f1dacabfa | |||
| 0c11880326 | |||
| b0d940945f | |||
| 36bb68e1e6 | |||
| d5996217a2 | |||
| 6f9f7c767c | |||
| 2bc8390e9f | |||
| 507f31ae79 | |||
| 292ce95abf | |||
| a7a880787b | |||
| dd5f2d0476 | |||
| ab91f24fd1 | |||
| 84c60cd6b6 | |||
| 31611f5657 | |||
| e3280e8c65 | |||
| c7bca82675 | |||
| fd894c3d83 | |||
| 405776d321 | |||
| c47e073db8 | |||
| 30c0decaeb | |||
| f73b653d0e | |||
| 97e558eb92 | |||
| 714d5036df | |||
| ca543df323 | |||
| 5424129163 | |||
| d111769a93 | |||
| c534b84dd2 | |||
| 202b1dfdae | |||
| 2518985e43 | |||
| 90de0b730d | |||
| 92d8c65aa0 | |||
| 12e0afb4e3 | |||
| f4c464003c | |||
| 0dcdcbed4b | |||
| 5aab77d7af | |||
| 542fbec18e | |||
| fbbaacc27a | |||
| 186e83754b | |||
| 2d035f0029 | |||
| d9e4899da5 | |||
| fabdd4b313 | |||
| e13f7ebfe3 | |||
| b34f667a5f | |||
| ec0b9c54e1 | |||
| 995e68dcae | |||
| 5dd59a51d9 | |||
| 3640499340 | |||
| 7327f11794 | |||
| 810b1ccbb3 | |||
| 4423986176 | |||
| 666cd1e8a8 | |||
| 4bc35abf04 | |||
| f1c83e9d05 | |||
| 24ce8e3a2e | |||
| ebd4877158 | |||
| 802c0a5d0c | |||
| d36b7744de | |||
| 4b62802566 | |||
| 44c537c295 | |||
| f556139b49 | |||
| 0a2f20281e | |||
| 0414671efd | |||
| fd2b384253 | |||
| de5d006344 | |||
| e59bf2bfe8 | |||
| 7000755e15 | |||
| b3899f559c | |||
| 03906a89cd | |||
| 51e747119c | |||
| 5353e5fa66 | |||
| 57ce0bd29d | |||
| c5d66914fa | |||
| 50a63adf5e | |||
| 71393da390 | |||
| 825622fd99 | |||
| 415d40f8c5 | |||
| bde3d98d0f | |||
| d37796a58f | |||
| 4fcea57df0 | |||
| 1d98a9959c | |||
| 3ecd33aded | |||
| 5615e47d99 | |||
| 04a97ac154 | |||
| 598938c13c | |||
| d97c44ef99 | |||
| e706620f12 | |||
| bd518365ea | |||
| 73effdf644 | |||
| c8971de833 | |||
| b26a979378 | |||
| 3836bf19d6 | |||
| f2f2448fe2 | |||
| 969a9d8782 | |||
| 6f64b0a236 | |||
| 4d04c76cd7 | |||
| 7a448b35d4 | |||
| 594b16374b | |||
| 39275c0110 | |||
| 4ad81c363c | |||
| 10b56142d5 | |||
| 5ee54c9c2a | |||
| 0b75c52a6e | |||
| 375105997f | |||
| 4e9179f309 | |||
| 863e925b30 | |||
| 8cb05d50c9 | |||
| 5d34e3f081 | |||
| d8fd4bfcf1 |
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
# Ignore files and directories starting with a dot
|
<!-- # Ignore files and directories starting with a dot
|
||||||
|
|
||||||
# Ignore specific files
|
# Ignore specific files
|
||||||
.dockerignore
|
.dockerignore
|
||||||
@@ -15,7 +15,7 @@ CHANGELOG/
|
|||||||
# LICENSE
|
# LICENSE
|
||||||
|
|
||||||
# Ignore testing and linting configuration
|
# Ignore testing and linting configuration
|
||||||
.golangci.yml
|
scripts/golangci.yml
|
||||||
|
|
||||||
# Ignore deployment-related files
|
# Ignore deployment-related files
|
||||||
docker-compose.yaml
|
docker-compose.yaml
|
||||||
@@ -28,4 +28,4 @@ assets/
|
|||||||
components/
|
components/
|
||||||
|
|
||||||
# Ignore tools and scripts
|
# Ignore tools and scripts
|
||||||
.github/
|
.github/ -->
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
USER=root
|
USER=root
|
||||||
PASSWORD=openIM123
|
PASSWORD=openIM123
|
||||||
MINIO_ENDPOINT=http://127.0.0.1:10005
|
MINIO_ENDPOINT=http://127.0.0.1:10005
|
||||||
API_URL=http://127.0.0.1:10002/object/
|
API_URL=http://127.0.0.1:10002
|
||||||
DATA_DIR=./
|
DATA_DIR=./
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
name-template: 'v$RESOLVED_VERSION 🌈'
|
||||||
|
tag-template: 'v$RESOLVED_VERSION'
|
||||||
|
categories:
|
||||||
|
- title: '🚀 Features'
|
||||||
|
labels:
|
||||||
|
- 'feature'
|
||||||
|
- 'enhancement'
|
||||||
|
- title: '🐛 Bug Fixes'
|
||||||
|
labels:
|
||||||
|
- 'kind/fix'
|
||||||
|
- 'kind/feature'
|
||||||
|
- 'enhancement'
|
||||||
|
- 'kind/documentation'
|
||||||
|
- 'good first issue'
|
||||||
|
- title: '🧰 Maintenance'
|
||||||
|
label: 'chore'
|
||||||
|
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||||
|
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
||||||
|
version-resolver:
|
||||||
|
major:
|
||||||
|
labels:
|
||||||
|
- 'major'
|
||||||
|
minor:
|
||||||
|
labels:
|
||||||
|
- 'minor'
|
||||||
|
patch:
|
||||||
|
labels:
|
||||||
|
- 'patch'
|
||||||
|
default: patch
|
||||||
|
template: |
|
||||||
|
## Changes $PREVIOUS_TAG
|
||||||
|
|
||||||
|
$CHANGES
|
||||||
|
|
||||||
|
## Contributors to this $REPOSITORY release
|
||||||
|
|
||||||
|
$CONTRIBUTORS
|
||||||
@@ -75,6 +75,17 @@ OpenIMSDK/OpenKF:
|
|||||||
dest: .github/.codecov.yml
|
dest: .github/.codecov.yml
|
||||||
replace: false
|
replace: false
|
||||||
|
|
||||||
|
openim-sigs/openim-docker:
|
||||||
|
- source: ./config
|
||||||
|
dest: ./openim-server/config
|
||||||
|
replace: true
|
||||||
|
- source: ./docs
|
||||||
|
dest: ./openim-server/docs
|
||||||
|
replace: true
|
||||||
|
- source: ./scripts
|
||||||
|
dest: ./openim-server/scripts
|
||||||
|
replace: true
|
||||||
|
|
||||||
group:
|
group:
|
||||||
# first group:common to all warehouses
|
# first group:common to all warehouses
|
||||||
# TODO: add the required warehouse here
|
# TODO: add the required warehouse here
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-api/Dockerfile
|
file: ./build/images/openim-api/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta1.outputs.tags }}
|
tags: ${{ steps.meta1.outputs.tags }}
|
||||||
@@ -113,7 +113,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-cmdutils/Dockerfile
|
file: ./build/images/openim-cmdutils/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta2.outputs.tags }}
|
tags: ${{ steps.meta2.outputs.tags }}
|
||||||
@@ -131,7 +131,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-crontask/Dockerfile
|
file: ./build/images/openim-crontask/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta3.outputs.tags }}
|
tags: ${{ steps.meta3.outputs.tags }}
|
||||||
@@ -149,7 +149,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-msggateway/Dockerfile
|
file: ./build/images/openim-msggateway/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta4.outputs.tags }}
|
tags: ${{ steps.meta4.outputs.tags }}
|
||||||
@@ -167,7 +167,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-msgtransfer/Dockerfile
|
file: ./build/images/openim-msgtransfer/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta5.outputs.tags }}
|
tags: ${{ steps.meta5.outputs.tags }}
|
||||||
@@ -185,7 +185,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-push/Dockerfile
|
file: ./build/images/openim-push/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta6.outputs.tags }}
|
tags: ${{ steps.meta6.outputs.tags }}
|
||||||
@@ -203,7 +203,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-rpc-auth/Dockerfile
|
file: ./build/images/openim-rpc-auth/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta7.outputs.tags }}
|
tags: ${{ steps.meta7.outputs.tags }}
|
||||||
@@ -221,7 +221,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-rpc-conversation/Dockerfile
|
file: ./build/images/openim-rpc-conversation/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta8.outputs.tags }}
|
tags: ${{ steps.meta8.outputs.tags }}
|
||||||
@@ -239,7 +239,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-rpc-friend/Dockerfile
|
file: ./build/images/openim-rpc-friend/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta9.outputs.tags }}
|
tags: ${{ steps.meta9.outputs.tags }}
|
||||||
@@ -257,7 +257,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-rpc-group/Dockerfile
|
file: ./build/images/openim-rpc-group/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta10.outputs.tags }}
|
tags: ${{ steps.meta10.outputs.tags }}
|
||||||
@@ -275,7 +275,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-rpc-msg/Dockerfile
|
file: ./build/images/openim-rpc-msg/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta11.outputs.tags }}
|
tags: ${{ steps.meta11.outputs.tags }}
|
||||||
@@ -293,7 +293,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-rpc-third/Dockerfile
|
file: ./build/images/openim-rpc-third/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta12.outputs.tags }}
|
tags: ${{ steps.meta12.outputs.tags }}
|
||||||
@@ -311,7 +311,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./build/docker/openim-rpc-user/Dockerfile
|
file: ./build/images/openim-rpc-user/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta13.outputs.tags }}
|
tags: ${{ steps.meta13.outputs.tags }}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
#
|
#
|
||||||
# Note: by default the `.golangci.yml` file should be at the root of the repository.
|
# Note: by default the `.golangci.yml` file should be at the root of the repository.
|
||||||
# The location of the configuration file can be changed by using `--config=`
|
# The location of the configuration file can be changed by using `--config=`
|
||||||
# args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0
|
args: --timeout=30m --config=/scripts/golangci.yml # --issues-exit-code=0
|
||||||
|
|
||||||
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
||||||
# only-new-issues: true
|
# only-new-issues: true
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
name: first-interaction
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check_for_first_interaction:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/first-interaction@main
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||||
|
issue-message: |
|
||||||
|
Hello! Thank you for filing an issue.
|
||||||
|
|
||||||
|
If this is a bug report, please include relevant logs to help us debug the problem.
|
||||||
|
|
||||||
|
[Join slack 🤖](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to connect and communicate with our developers.
|
||||||
|
pr-message: |
|
||||||
|
Hello! Thank you for your contribution.
|
||||||
|
|
||||||
|
If you are fixing a bug, please reference the issue number in the description.
|
||||||
|
|
||||||
|
If you are implementing a feature request, please check with the maintainers that the feature will be accepted first.
|
||||||
|
|
||||||
|
[Join slack 🤖](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to connect and communicate with our developers.
|
||||||
@@ -36,124 +36,99 @@ env:
|
|||||||
GO_VERSION: "1.19"
|
GO_VERSION: "1.19"
|
||||||
GOLANGCI_VERSION: "v1.50.1"
|
GOLANGCI_VERSION: "v1.50.1"
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
openim:
|
openim:
|
||||||
name: Test with go ${{ matrix.go_version }} on ${{ matrix.os }}
|
name: Test with go ${{ matrix.go_version }} on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
permissions:
|
permissions:
|
||||||
# Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository.
|
|
||||||
contents: write
|
contents: write
|
||||||
environment:
|
environment:
|
||||||
name: openim
|
name: openim
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go_version: ["1.18","1.19","1.20"]
|
go_version: ["1.18","1.19","1.20","1.21"]
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Setup
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Set up Go ${{ matrix.go_version }}
|
- name: Set up Go ${{ matrix.go_version }}
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go_version }}
|
go-version: ${{ matrix.go_version }}
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Install Task
|
- name: Install Task
|
||||||
uses: arduino/setup-task@v1
|
uses: arduino/setup-task@v1
|
||||||
with:
|
with:
|
||||||
version: 2.x
|
version: 2.x
|
||||||
|
|
||||||
- name: Run go modules tidy
|
- name: Module Operations
|
||||||
run: |
|
run: |
|
||||||
sudo make tidy
|
sudo make tidy
|
||||||
sudo make tools.verify.go-gitlint
|
sudo make tools.verify.go-gitlint
|
||||||
echo "Run go modules tidy successfully"
|
|
||||||
|
|
||||||
- name: Run go format
|
- name: Format Code
|
||||||
run: |
|
run: sudo make format
|
||||||
sudo make format
|
|
||||||
echo "Run go format successfully"
|
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Generate all necessary files, such as error code files
|
- name: Generate Files
|
||||||
run: |
|
run: make gen
|
||||||
make generate
|
|
||||||
echo "Generate all necessary files successfully"
|
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Run unit test and get test coverage
|
- name: Build Source
|
||||||
run: |
|
run: sudo make build
|
||||||
make cover
|
|
||||||
echo "Run unit test and get test coverage successfully"
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Build source code for host platform
|
- name: Cleanup Build
|
||||||
run: |
|
run: sudo make clean
|
||||||
sudo make build
|
|
||||||
echo "Build source code for host platform successfully"
|
|
||||||
|
|
||||||
- name: OpenIM verify copyright
|
- name: Push Changes to Main
|
||||||
run: |
|
|
||||||
sudo make verify-copyright
|
|
||||||
sudo make add-copyright
|
|
||||||
echo "OpenIM verify successfully"
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Clean all build
|
|
||||||
run: |
|
|
||||||
sudo make clean
|
|
||||||
echo "Clean all build successfully"
|
|
||||||
|
|
||||||
- name: push OpenIM
|
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
with:
|
with:
|
||||||
commit_message: "cicd: robot automated Change"
|
commit_message: "cicd: robot automated Change"
|
||||||
# commit_options: '--no-verify --signoff'
|
|
||||||
branch: main
|
|
||||||
# create_branch: true
|
|
||||||
# # Optional commit user and author settings
|
|
||||||
# commit_user_name: kubbot # defaults to "github-actions[bot]"
|
|
||||||
# commit_user_email: 3293172751ysy@gmail.com # defaults to "41898282+github-actions[bot]@users.noreply.github.com"
|
|
||||||
# commit_author: Kubbot # defaults to author of the commit that triggered the run
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Commit Changes
|
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4
|
|
||||||
with:
|
|
||||||
commit_message: "chore(fmt): robot automated format and lint Change"
|
|
||||||
commit_options: '--no-verify --signoff'
|
|
||||||
branch: main
|
branch: main
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Set Current Directory
|
- name: Set Current Directory
|
||||||
id: set_directory
|
id: set_directory
|
||||||
run: |
|
run: echo "::set-output name=directory::$(pwd)"
|
||||||
echo "::set-output name=directory::$(pwd)"
|
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Collect Test Coverage File
|
- name: Collect and Display Test Coverage
|
||||||
id: collect_coverage
|
id: collect_coverage
|
||||||
run: |
|
run: |
|
||||||
cd ${{ steps.set_directory.outputs.directory }}
|
cd ${{ steps.set_directory.outputs.directory }}
|
||||||
make cover
|
make cover
|
||||||
echo "::set-output name=coverage_file::./_output/tmp/coverage.out"
|
echo "::set-output name=coverage_file::./_output/tmp/coverage.out"
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Display Test Coverage
|
|
||||||
run: |
|
|
||||||
echo "Test Coverage:"
|
echo "Test Coverage:"
|
||||||
cat ${{ steps.collect_coverage.outputs.coverage_file }}
|
cat ${{ steps.collect_coverage.outputs.coverage_file }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
openim-start:
|
openim-start:
|
||||||
name: Teat OpenIM make install start on ${{ matrix.os }}
|
name: Test OpenIM install/start on ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
environment:
|
||||||
|
name: openim
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go_version: ["1.21"]
|
||||||
|
os: ["ubuntu-latest"]
|
||||||
|
steps:
|
||||||
|
- name: Checkout and Install OpenIM
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Install Task
|
||||||
|
uses: arduino/setup-task@v1
|
||||||
|
with:
|
||||||
|
version: 2.x
|
||||||
|
- name: Run OpenIM make install start
|
||||||
|
run: |
|
||||||
|
sudo make install
|
||||||
|
|
||||||
|
execute-scripts:
|
||||||
|
name: Execute OpenIM script on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
environment:
|
environment:
|
||||||
name: openim
|
name: openim
|
||||||
@@ -162,15 +137,35 @@ jobs:
|
|||||||
go_version: ["1.20"]
|
go_version: ["1.20"]
|
||||||
os: ["ubuntu-latest"]
|
os: ["ubuntu-latest"]
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Set up Go ${{ matrix.go_version }}
|
- name: Set up Go ${{ matrix.go_version }}
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go_version }}
|
go-version: ${{ matrix.go_version }}
|
||||||
id: go
|
id: go
|
||||||
|
- name: Install Task
|
||||||
- name: Check out code into the Go module directory
|
uses: arduino/setup-task@v1
|
||||||
uses: actions/checkout@v3
|
with:
|
||||||
|
version: 2.x
|
||||||
- name: Run OpenIM make install start
|
- name: Docker Operations
|
||||||
run: |
|
run: |
|
||||||
sudo make install
|
curl -o docker-compose.yaml https://gist.githubusercontent.com/cubxxw/b1d5cbd2edfa23fee911118aa3e8249e/raw/openim-server.sh
|
||||||
|
sudo docker compose up -d
|
||||||
|
sudo sleep 60
|
||||||
|
|
||||||
|
- name: Module Operations
|
||||||
|
run: |
|
||||||
|
sudo make tidy
|
||||||
|
sudo make tools.verify.go-gitlint
|
||||||
|
|
||||||
|
- name: Build, Start and Check Services
|
||||||
|
run: |
|
||||||
|
make build
|
||||||
|
make start
|
||||||
|
make check
|
||||||
|
|
||||||
|
- name: Print OpenIM Logs
|
||||||
|
run: sudo cat ./_output/logs/* 2>/dev/null
|
||||||
|
continue-on-error: true
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
name: Release Drafter
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
# branches to consider in the event; optional, defaults to all
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
# pull_request event is required only for autolabeler
|
||||||
|
pull_request:
|
||||||
|
# Only following types are handled by the action, but one can default to all as well
|
||||||
|
types: [opened, reopened, synchronize]
|
||||||
|
# pull_request_target event is required for autolabeler to support PRs from forks
|
||||||
|
# pull_request_target:
|
||||||
|
# types: [opened, reopened, synchronize]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update_release_draft:
|
||||||
|
permissions:
|
||||||
|
# write permission is required to create a github release
|
||||||
|
contents: write
|
||||||
|
# write permission is required for autolabeler
|
||||||
|
# otherwise, read permission is required at least
|
||||||
|
pull-requests: write
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# (Optional) GitHub Enterprise requires GHE_HOST variable set
|
||||||
|
#- name: Set GHE_HOST
|
||||||
|
# run: |
|
||||||
|
# echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# Drafts your next Release notes as Pull Requests are merged into "master"
|
||||||
|
- uses: release-drafter/release-drafter@v5
|
||||||
|
# (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
|
||||||
|
# with:
|
||||||
|
# config-name: my-config.yml
|
||||||
|
# disable-autolabeler: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.REDBOT_GITHUB_TOKEN }}
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
name: OpenIM Server Release
|
name: OpenIM Server Release Workflow
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -43,9 +43,12 @@ jobs:
|
|||||||
# either 'goreleaser' (default) or 'goreleaser-pro':
|
# either 'goreleaser' (default) or 'goreleaser-pro':
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
version: latest
|
version: latest
|
||||||
args: release --clean
|
workdir: .
|
||||||
|
args: release -f ./build/goreleaser.yaml --rm-dist --clean --release-footer-tmpl=scripts/template/footer.md.tmpl --release-header-tmpl=scripts/template/head.md.tmpl
|
||||||
env:
|
env:
|
||||||
|
USERNAME: ${{ github.repository_owner }}
|
||||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||||
|
FURY_TOKEN: ${{ secrets.FURY_TOKEN }}
|
||||||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
|
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
|
||||||
# distribution:
|
# distribution:
|
||||||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||||
|
|||||||
@@ -1,86 +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.
|
|
||||||
|
|
||||||
name: OpenIM Start Execute Scripts
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths-ignore:
|
|
||||||
- "docs/**"
|
|
||||||
- "README.md"
|
|
||||||
- "README_zh-CN.md"
|
|
||||||
- "CONTRIBUTING.md"
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths-ignore:
|
|
||||||
- "README.md"
|
|
||||||
- "README_zh-CN.md"
|
|
||||||
- "CONTRIBUTING.md"
|
|
||||||
- "docs/**"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
execute-scripts:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Start Docker Compose
|
|
||||||
run: |
|
|
||||||
sudo docker compose stop
|
|
||||||
sudo sleep 30
|
|
||||||
sudo docker compose up -d
|
|
||||||
sudo sleep 60
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Stop all services
|
|
||||||
run: |
|
|
||||||
sudo chmod +x ./scripts/stop_all.sh
|
|
||||||
sudo ./scripts/stop_all.sh
|
|
||||||
sudo cat logs/openIM.log 2>/dev/null
|
|
||||||
shell: bash
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Build all services
|
|
||||||
run: |
|
|
||||||
sudo chmod +x ./scripts/build_all_service.sh
|
|
||||||
sudo ./scripts/build_all_service.sh
|
|
||||||
sudo cat logs/openIM.log 2>/dev/null
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Start all services
|
|
||||||
run: |
|
|
||||||
sudo chmod +x ./scripts/start_all.sh
|
|
||||||
sudo ./scripts/start_all.sh
|
|
||||||
sudo cat logs/openIM.log 2>/dev/null
|
|
||||||
continue-on-error: true
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Check all services
|
|
||||||
run: |
|
|
||||||
sudo chmod +x ./scripts/check_all.sh
|
|
||||||
sudo ./scripts/check_all.sh
|
|
||||||
sudo cat logs/openIM.log 2>/dev/null
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Print openIM.log
|
|
||||||
run: |
|
|
||||||
sudo cat logs/* 2>/dev/null
|
|
||||||
sudo cat logs/* 2>/dev/null >> "$GITHUB_OUTPUT"
|
|
||||||
shell: bash
|
|
||||||
continue-on-error: true
|
|
||||||
@@ -6,6 +6,10 @@
|
|||||||
name: Synchronize kubecub public code to other repositories
|
name: Synchronize kubecub public code to other repositories
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
paths:
|
||||||
|
- scripts/*
|
||||||
|
- docs/*
|
||||||
|
- config/*
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|||||||
+9
-2
@@ -30,6 +30,12 @@ bin/
|
|||||||
output/
|
output/
|
||||||
_output/
|
_output/
|
||||||
|
|
||||||
|
### OpenIM Config ###
|
||||||
|
config/config.yaml
|
||||||
|
./config/config.yaml
|
||||||
|
.env
|
||||||
|
./.env
|
||||||
|
|
||||||
### OpenIM deploy ###
|
### OpenIM deploy ###
|
||||||
deploy/openim_demo
|
deploy/openim_demo
|
||||||
deploy/openim-api
|
deploy/openim-api
|
||||||
@@ -153,10 +159,11 @@ flycheck_*.el
|
|||||||
*.out
|
*.out
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
# Dependency directories (remove the comment below to include it)
|
||||||
# vendor/
|
vendor/
|
||||||
|
|
||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
# go.work
|
||||||
|
go.work.sum
|
||||||
|
|
||||||
### JetBrains ###
|
### JetBrains ###
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# Version logging for OpenIM
|
||||||
|
|
||||||
|
<!-- BEGIN MUNGE: GENERATED_TOC -->
|
||||||
|
|
||||||
|
- [Version logging for OpenIM](#version-logging-for-openim)
|
||||||
|
- [Unreleased](#unreleased)
|
||||||
|
- [v3.1.2-beta.3 - 2023-08-09](#v312-beta3---2023-08-09)
|
||||||
|
- [v3.1.2-beta.2 - 2023-08-09](#v312-beta2---2023-08-09)
|
||||||
|
- [v3.1.2-beta.1 - 2023-08-09](#v312-beta1---2023-08-09)
|
||||||
|
- [v3.1.2-beta.0 - 2023-08-08](#v312-beta0---2023-08-08)
|
||||||
|
- [v3.1.2.beta.0 - 2023-08-08](#v312beta0---2023-08-08)
|
||||||
|
- [v3.1.1-beta.4 - 2023-08-07](#v311-beta4---2023-08-07)
|
||||||
|
- [v3.1.1-beta.3 - 2023-08-05](#v311-beta3---2023-08-05)
|
||||||
|
- [v3.1.1-beta.2 - 2023-08-04](#v311-beta2---2023-08-04)
|
||||||
|
- [v3.1.1-beta.1 - 2023-08-04](#v311-beta1---2023-08-04)
|
||||||
|
- [v3.1.1-alpha.3 - 2023-08-03](#v311-alpha3---2023-08-03)
|
||||||
|
- [v3.1.1-alpha.2 - 2023-08-03](#v311-alpha2---2023-08-03)
|
||||||
|
- [v3.1.1-alpha.1 - 2023-08-02](#v311-alpha1---2023-08-02)
|
||||||
|
- [v3.1.0 - 2023-07-28](#v310---2023-07-28)
|
||||||
|
- [Reverts](#reverts)
|
||||||
|
- [Pull Requests](#pull-requests)
|
||||||
|
|
||||||
|
|
||||||
|
<!-- END MUNGE: GENERATED_TOC -->
|
||||||
|
|
||||||
|
<a name="unreleased"></a>
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
|
||||||
|
<a name="v3.1.2-beta.3"></a>
|
||||||
|
## [v3.1.2-beta.3] - 2023-08-09
|
||||||
|
|
||||||
|
<a name="v3.1.2-beta.2"></a>
|
||||||
|
## [v3.1.2-beta.2] - 2023-08-09
|
||||||
|
|
||||||
|
<a name="v3.1.2-beta.1"></a>
|
||||||
|
## [v3.1.2-beta.1] - 2023-08-09
|
||||||
|
|
||||||
|
<a name="v3.1.2-beta.0"></a>
|
||||||
|
## [v3.1.2-beta.0] - 2023-08-08
|
||||||
|
|
||||||
|
<a name="v3.1.2.beta.0"></a>
|
||||||
|
## [v3.1.2.beta.0] - 2023-08-08
|
||||||
|
|
||||||
|
<a name="v3.1.1-beta.4"></a>
|
||||||
|
## [v3.1.1-beta.4] - 2023-08-07
|
||||||
|
|
||||||
|
<a name="v3.1.1-beta.3"></a>
|
||||||
|
## [v3.1.1-beta.3] - 2023-08-05
|
||||||
|
|
||||||
|
<a name="v3.1.1-beta.2"></a>
|
||||||
|
## [v3.1.1-beta.2] - 2023-08-04
|
||||||
|
|
||||||
|
<a name="v3.1.1-beta.1"></a>
|
||||||
|
## [v3.1.1-beta.1] - 2023-08-04
|
||||||
|
|
||||||
|
<a name="v3.1.1-alpha.3"></a>
|
||||||
|
## [v3.1.1-alpha.3] - 2023-08-03
|
||||||
|
|
||||||
|
<a name="v3.1.1-alpha.2"></a>
|
||||||
|
## [v3.1.1-alpha.2] - 2023-08-03
|
||||||
|
|
||||||
|
<a name="v3.1.1-alpha.1"></a>
|
||||||
|
## [v3.1.1-alpha.1] - 2023-08-02
|
||||||
|
|
||||||
|
<a name="v3.1.0"></a>
|
||||||
|
## v3.1.0 - 2023-07-28
|
||||||
|
### Reverts
|
||||||
|
- update etcd to v3.5.2 ([#206](https://github.com/OpenIMSDK/Open-IM-Server/issues/206))
|
||||||
|
|
||||||
|
### Pull Requests
|
||||||
|
- Merge branch 'tuoyun'
|
||||||
|
|
||||||
|
|
||||||
|
[Unreleased]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2-beta.3...HEAD
|
||||||
|
[v3.1.2-beta.3]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2-beta.2...v3.1.2-beta.3
|
||||||
|
[v3.1.2-beta.2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2-beta.1...v3.1.2-beta.2
|
||||||
|
[v3.1.2-beta.1]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2-beta.0...v3.1.2-beta.1
|
||||||
|
[v3.1.2-beta.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2.beta.0...v3.1.2-beta.0
|
||||||
|
[v3.1.2.beta.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-beta.4...v3.1.2.beta.0
|
||||||
|
[v3.1.1-beta.4]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-beta.3...v3.1.1-beta.4
|
||||||
|
[v3.1.1-beta.3]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-beta.2...v3.1.1-beta.3
|
||||||
|
[v3.1.1-beta.2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-beta.1...v3.1.1-beta.2
|
||||||
|
[v3.1.1-beta.1]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-alpha.3...v3.1.1-beta.1
|
||||||
|
[v3.1.1-alpha.3]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-alpha.2...v3.1.1-alpha.3
|
||||||
|
[v3.1.1-alpha.2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-alpha.1...v3.1.1-alpha.2
|
||||||
|
[v3.1.1-alpha.1]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.0...v3.1.1-alpha.1
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
- [Changelog](#changelog)
|
- [Changelog](#changelog)
|
||||||
- [OpenIM versioning policy](#openim-versioning-policy)
|
- [OpenIM versioning policy](#openim-versioning-policy)
|
||||||
- [command](#command)
|
- [command](#command)
|
||||||
|
- [install](#install)
|
||||||
|
- [User](#user)
|
||||||
- [create next tag](#create-next-tag)
|
- [create next tag](#create-next-tag)
|
||||||
- [Release version logs](#release-version-logs)
|
- [Release version logs](#release-version-logs)
|
||||||
- [Introduction](#introduction)
|
- [Introduction](#introduction)
|
||||||
@@ -22,10 +24,68 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
## command
|
## command
|
||||||
|
|
||||||
|
To use git-chglog you need to configure:
|
||||||
|
|
||||||
|
1. CHANGELOG templates
|
||||||
|
2. git-chglog configuration
|
||||||
|
|
||||||
|
### install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ go get github.com/git-chglog/git-chglog/cmd/git-chglog
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## User
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git-chglog --init
|
||||||
|
```
|
||||||
|
|
||||||
|
**Options**
|
||||||
|
|
||||||
|
- What is the URL of your repository?: https://github.com/OpenIMSDK/Open-IM-Server
|
||||||
|
- What is your favorite style?: github
|
||||||
|
- Choose the format of your favorite commit message: <type>(<scope>): <subject> -- feat(core): Add new feature
|
||||||
|
- What is your favorite template style?: standard
|
||||||
|
- Do you include Merge Commit in CHANGELOG?: n
|
||||||
|
- Do you include Revert Commit in CHANGELOG?: y
|
||||||
|
- In which directory do you output configuration files and templates?: .chglog
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git-chglog --tag-filter-pattern 'v2.0.*' -o CHANGELOG-2.0.md
|
git-chglog --tag-filter-pattern 'v2.0.*' -o CHANGELOG-2.0.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Other uses:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git-chglog
|
||||||
|
|
||||||
|
If <tag query> is not specified, it corresponds to all tags.
|
||||||
|
This is the simplest example.
|
||||||
|
|
||||||
|
$ git-chglog 1.0.0..2.0.0
|
||||||
|
|
||||||
|
The above is a command to generate CHANGELOG including commit of 1.0.0 to 2.0.0.
|
||||||
|
|
||||||
|
$ git-chglog 1.0.0
|
||||||
|
|
||||||
|
The above is a command to generate CHANGELOG including commit of only 1.0.0.
|
||||||
|
|
||||||
|
$ git-chglog $(git describe --tags $(git rev-list --tags --max-count=1))
|
||||||
|
|
||||||
|
The above is a command to generate CHANGELOG with the commit included in the latest tag.
|
||||||
|
|
||||||
|
$ git-chglog --output CHANGELOG.md
|
||||||
|
|
||||||
|
The above is a command to output to CHANGELOG.md instead of standard output.
|
||||||
|
|
||||||
|
$ git-chglog --config custom/dir/config.yml
|
||||||
|
|
||||||
|
The above is a command that uses a configuration file placed other than ".chglog/config.yml".
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## create next tag
|
## create next tag
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -51,6 +111,7 @@ git tag 2.0.0
|
|||||||
+ [OpenIM CHANGELOG-V2.3](CHANGELOG-2.3.md)
|
+ [OpenIM CHANGELOG-V2.3](CHANGELOG-2.3.md)
|
||||||
+ [OpenIM CHANGELOG-V2.9](CHANGELOG-2.9.md)
|
+ [OpenIM CHANGELOG-V2.9](CHANGELOG-2.9.md)
|
||||||
+ [OpenIM CHANGELOG-V3.0](CHANGELOG-3.0.md)
|
+ [OpenIM CHANGELOG-V3.0](CHANGELOG-3.0.md)
|
||||||
|
+ [OpenIM CHANGELOG-V3.1](CHANGELOG-3.1.md)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ So, you want to hack on Open-IM-Server? Yay!
|
|||||||
|
|
||||||
First of all, thank you for considering contributing to our project! We appreciate your time and effort, and we value any contribution, whether it's reporting a bug, suggesting a new feature, or submitting a pull request.
|
First of all, thank you for considering contributing to our project! We appreciate your time and effort, and we value any contribution, whether it's reporting a bug, suggesting a new feature, or submitting a pull request.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> Use `make demo` start contributing fast.
|
||||||
|
|
||||||
This document provides guidelines and best practices to help you contribute effectively.
|
This document provides guidelines and best practices to help you contribute effectively.
|
||||||
|
|
||||||
## 📇Topics
|
## 📇Topics
|
||||||
|
|||||||
+7
-9
@@ -10,24 +10,22 @@ ENV GOPROXY=$GOPROXY
|
|||||||
# Set up the working directory
|
# Set up the working directory
|
||||||
WORKDIR /openim/openim-server
|
WORKDIR /openim/openim-server
|
||||||
|
|
||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum go.work ./
|
||||||
RUN go mod download
|
#RUN go mod download
|
||||||
|
|
||||||
# Copy all files to the container
|
# Copy all files to the container
|
||||||
ADD . .
|
ADD . .
|
||||||
|
|
||||||
RUN /bin/sh -c "make clean"
|
RUN make clean
|
||||||
RUN /bin/sh -c "make build"
|
RUN make build
|
||||||
|
|
||||||
FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
FROM ghcr.io/openim-sigs/openim-ubuntu-image:latest
|
||||||
|
|
||||||
WORKDIR ${SERVER_WORKDIR}
|
WORKDIR ${SERVER_WORKDIR}
|
||||||
|
|
||||||
# Copy scripts and binary files to the production image
|
# 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 ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts
|
||||||
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
|
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
|
||||||
COPY --from=builder ${SERVER_WORKDIR}/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
|
||||||
|
|
||||||
VOLUME ["/openim/openim-server/logs","/openim/openim-server/config","/openim/openim-server/scripts"]
|
CMD ["/openim/openim-server/scripts/docker-start-all.sh"]
|
||||||
|
|
||||||
CMD ["bash","-c","${OPENIM_SERVER_CMDDIR}/docker_start_all.sh"]
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
|
|
||||||
## all: Run tidy, gen, add-copyright, format, lint, cover, build ✨
|
## all: Run tidy, gen, add-copyright, format, lint, cover, build ✨
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: tidy gen add-copyright format lint cover build
|
all: tidy gen add-copyright lint cover restart
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Build set
|
# Build set
|
||||||
|
|
||||||
ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-Server
|
ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-Server
|
||||||
# TODO: This is version control for the future
|
# TODO: This is version control for the future https://github.com/OpenIMSDK/Open-IM-Server/issues/574
|
||||||
VERSION_PACKAGE=github.com/OpenIMSDK/Open-IM-Server/pkg/version
|
VERSION_PACKAGE=github.com/OpenIMSDK/Open-IM-Server/pkg/version
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -53,16 +53,45 @@ export USAGE_OPTIONS
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Targets
|
# Targets
|
||||||
|
|
||||||
|
## init: Initialize openim server project ✨
|
||||||
|
.PHONY: init
|
||||||
|
init:
|
||||||
|
@$(MAKE) gen.init
|
||||||
|
|
||||||
|
## demo: Run demo get started with Makefiles quickly ✨
|
||||||
|
.PHONY: demo
|
||||||
|
demo:
|
||||||
|
@$(MAKE) go.demo
|
||||||
|
|
||||||
## build: Build binaries by default ✨
|
## build: Build binaries by default ✨
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build:
|
||||||
@$(MAKE) go.build
|
@$(MAKE) go.build
|
||||||
|
|
||||||
|
## start: Start openim ✨
|
||||||
|
.PHONY: start
|
||||||
|
start:
|
||||||
|
@$(MAKE) go.start
|
||||||
|
|
||||||
|
## stop: Stop openim ✨
|
||||||
|
.PHONY: stop
|
||||||
|
stop:
|
||||||
|
@$(MAKE) go.stop
|
||||||
|
|
||||||
|
## restart: Restart openim ✨
|
||||||
|
.PHONY: restart
|
||||||
|
restart: clean stop build start
|
||||||
|
|
||||||
## multiarch: Build binaries for multiple platforms. See option PLATFORMS. ✨
|
## multiarch: Build binaries for multiple platforms. See option PLATFORMS. ✨
|
||||||
.PHONY: multiarch
|
.PHONY: multiarch
|
||||||
multiarch:
|
multiarch:
|
||||||
@$(MAKE) go.build.multiarch
|
@$(MAKE) go.build.multiarch
|
||||||
|
|
||||||
|
## verify: execute all verity scripts. ✨
|
||||||
|
.PHONY: verify
|
||||||
|
verify:
|
||||||
|
@$(MAKE) go.verify
|
||||||
|
|
||||||
## install: Install deployment openim ✨
|
## install: Install deployment openim ✨
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install:
|
install:
|
||||||
|
|||||||
+211
-119
@@ -1,16 +1,19 @@
|
|||||||
<h1 align="center" style="border-bottom: none">
|
<p align="center">
|
||||||
<b>
|
<a href="https://www.openim.online">
|
||||||
<a href="https://doc.rentsoft.cn/">Open IM Server</a><br>
|
<img src="./assets/logo-gif/openim-logo.gif" width="60%" height="30%"/>
|
||||||
</b>
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 align="center" style="border-bottom: none">
|
||||||
⭐️ Open source Instant Messaging Server ⭐️ <br>
|
⭐️ Open source Instant Messaging Server ⭐️ <br>
|
||||||
</h1>
|
<h3>
|
||||||
|
|
||||||
|
|
||||||
<p align=center>
|
<p align=center>
|
||||||
<a href="https://goreportcard.com/report/github.com/OpenIMSDK/Open-IM-Server"><img src="https://goreportcard.com/badge/github.com/OpenIMSDK/Open-IM-Server" alt="A+"></a>
|
<a href="https://goreportcard.com/report/github.com/OpenIMSDK/Open-IM-Server"><img src="https://goreportcard.com/badge/github.com/OpenIMSDK/Open-IM-Server" alt="A+"></a>
|
||||||
<a href="https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22"><img src="https://img.shields.io/github/issues/OpenIMSDK/Open-IM-Server/good%20first%20issue?logo=%22github%22" alt="good first"></a>
|
<a href="https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22"><img src="https://img.shields.io/github/issues/OpenIMSDK/Open-IM-Server/good%20first%20issue?logo=%22github%22" alt="good first"></a>
|
||||||
<a href="https://github.com/OpenIMSDK/Open-IM-Server"><img src="https://img.shields.io/github/stars/OpenIMSDK/Open-IM-Server.svg?style=flat&logo=github&colorB=deeppink&label=stars"></a>
|
<a href="https://github.com/OpenIMSDK/Open-IM-Server"><img src="https://img.shields.io/github/stars/OpenIMSDK/Open-IM-Server.svg?style=flat&logo=github&colorB=deeppink&label=stars"></a>
|
||||||
<a href="https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg"><img src="https://img.shields.io/badge/Slack-100%2B-blueviolet?logo=slack&logoColor=white"></a>
|
<a href="https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg"><img src="https://img.shields.io/badge/Slack-300%2B-blueviolet?logo=slack&logoColor=white"></a>
|
||||||
<a href="https://github.com/OpenIMSDK/Open-IM-Server/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green"></a>
|
<a href="https://github.com/OpenIMSDK/Open-IM-Server/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green"></a>
|
||||||
<a href="https://golang.org/"><img src="https://img.shields.io/badge/Language-Go-blue.svg"></a>
|
<a href="https://golang.org/"><img src="https://img.shields.io/badge/Language-Go-blue.svg"></a>
|
||||||
</p>
|
</p>
|
||||||
@@ -19,163 +22,219 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="./README.md"><b> English </b></a> •
|
<a href="./README.md"><b> English </b></a> •
|
||||||
<a href="./README_zh-CN.md"><b>中文</b></a>
|
<a href="./README-zh_CN.md"><b> 简体中文 </b></a> •
|
||||||
|
<a href="https://www.openim.online/en"><b> Docs </b></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Open-IM-Server 是什么
|
## ✨ 关于 OpenIM
|
||||||
|
|
||||||
Open-IM-Server 是一款即时通讯服务器,使用纯 Golang 开发,采用 JSON over WebSocket 传输协议。在 Open-IM-Server 中,所有东西都是消息,因此您可以轻松扩展自定义消息,而无需修改服务器代码。使用微服务架构,Open-IM-Server 可以使用集群进行部署。通过在服务器上部署 Open-IM-Server,开发人员可以快速地将即时通讯和实时网络功能集成到自己的应用程序中,并确保业务数据的安全性和隐私性。
|
Open-IM-Server 是使用纯 Golang 精心制作的强大的即时消息服务器。其通过 JSON over WebSocket 进行通信的独特方法将每次交互都视为消息。这简化了定制并消除了修改服务器代码的需求。通过利用微服务架构,服务器可以通过集群部署,保证出色的性能和可伸缩性。
|
||||||
|
|
||||||
Open-IM-Server并不是一个独立的产品,本身不包含账号的注册和登录服务。
|
Open-IM-Server 不仅仅是一个即时消息服务器;它是将实时网络集成到您的应用程序中的强大工具,定位为您集成的首选选择!🚀
|
||||||
为方便大家测试,我们开源了包括登录注册功能的 [chat 仓库](https://github.com/OpenIMSDK/chat),chat 业务服务端和 Open-IM-Server 一起部署,即可搭建一个聊天产品。
|
|
||||||
|
|
||||||
## 特点
|
请注意,Open-IM-Server 不作为独立产品运行,也不提供内置的帐户注册或登录服务。为了简化您的实施过程,我们已开源了 [chat repository](https://github.com/OpenIMSDK/chat),其中包括这些功能。与 Open-IM-Server 一起部署此聊天业务服务器可加快全面的聊天产品的设置。👥
|
||||||
|
|
||||||
+ 开源
|
为了进一步增强您的体验,我们还提供了 SDK 客户端,在其中实现了大多数复杂逻辑。可以在 [此链接](https://github.com/OpenIMSDK/openim-sdk-core) 找到 [SDK repository](https://github.com/OpenIMSDK/openim-sdk-core)。[chat repository](https://github.com/OpenIMSDK/chat) 是我们的业务服务器,而 'core' 代表 SDK 的高级封装,它们协同工作以提供卓越的结果。✨
|
||||||
+ 易于集成
|
|
||||||
+ 良好的可扩展性
|
|
||||||
+ 高性能
|
|
||||||
+ 轻量级
|
|
||||||
+ 支持多种协议
|
|
||||||
|
|
||||||
## 社区
|
## :star2: 为什么选择 OpenIM
|
||||||
|
|
||||||
+ 访问中文官方网站:[OpenIM中文开发文档](https://doc.rentsoft.cn/)
|
**🔍 功能截图显示**
|
||||||
|
|
||||||
## 快速开始
|
<div align="center">
|
||||||
|
|
||||||
### 使用 docker-compose 部署
|
| 💻🔄📱 多终端同步 🔄🖥️ | 📅⚡ 高效会议 🚀💼 |
|
||||||
|
| :----------------------------------------------------------: | :----------------------------------------------------------: |
|
||||||
|
|  |  |
|
||||||
|
| 📲🔄 **一对一和群聊** 👥🗣️ | 🎁💻 **特殊功能 - 自定义消息** ✉️🎨 |
|
||||||
|
|  |  |
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
1. **全面的消息类型支持 :speech_balloon:**
|
||||||
|
|
||||||
|
✅ 支持几乎所有类型的消息,包括文本、图片、表情符号、语音、视频、地理位置、文件、报价、名片、系统通知、自定义消息等
|
||||||
|
|
||||||
|
✅ 支持一对一和多人音视频通话
|
||||||
|
|
||||||
|
✅ 为 iOS、Android、Flutter、uni-app、ReactNative、Electron、Web、H5 等多个平台提供终端支持
|
||||||
|
|
||||||
|
2. **随时随地的高效会议 :earth_americas:**
|
||||||
|
|
||||||
|
✅ 基于具有 100% 可靠强制信令功能的 IM (Instant Messaging),为与聊天应用程序深度集成的 IM 系统铺平了道路
|
||||||
|
|
||||||
|
✅ 支持单次会议中的数百人,订阅人数达到数千,以及服务器端音视频录制
|
||||||
|
|
||||||
|
3. **适用于各种社交场景的一对一和群聊 :busts_in_silhouette:**
|
||||||
|
|
||||||
|
✅ OpenIM 有四种角色:应用程序管理员、群主、群管理员和普通成员
|
||||||
|
|
||||||
|
✅ 强大的群特性,如静音、群公告、群验证、无限群成员和根据需要加载群消息
|
||||||
|
|
||||||
|
4. **独特的功能 :star2:**
|
||||||
|
|
||||||
|
✅ 支持读取并烧毁私人聊天,可自定义时长
|
||||||
|
|
||||||
|
✅ 消息编辑功能扩大了社交场景,使即时通讯变得更加多样化和有趣
|
||||||
|
|
||||||
|
5. **开源 :open_hands:**
|
||||||
|
|
||||||
|
✅ OpenIM 的代码是开源的,数据自控,旨在构建一个全球领先的 IM 开源社区,包括客户端 SDK 和服务器
|
||||||
|
|
||||||
|
✅ 基于开源服务器,已经开发了许多出色的开源项目,例如 [OpenKF](https://github.com/OpenIMSDK/OpenKF) (开源 AI 客户服务系统)
|
||||||
|
|
||||||
|
6. **易于扩展 :wrench:**
|
||||||
|
|
||||||
|
✅ OpenIM 服务器是用 Golang 实现的,引入了创新的 "一切都是消息" 通信模型,简化了自定义消息和扩展功能的实现
|
||||||
|
|
||||||
|
7. **高性能 :racing_car:**
|
||||||
|
|
||||||
|
✅ OpenIM 支持集群中的分层治理架构,经过大量用户的测试,并抽象了在线消息、离线消息和历史消息的存储模型
|
||||||
|
|
||||||
|
8. **全平台支持 :tv:**
|
||||||
|
|
||||||
|
✅ 支持原生 iOS、Android;跨平台 Flutter、uni-app、ReactNative;主要的 Web 前端框架如 React、Vue;小程序和 Electron 支持的 PC 平台
|
||||||
|
|
||||||
|
9. **终极部署体验 🤖**
|
||||||
|
|
||||||
|
✅ 支持 [集群部署](https://github.com/OpenIMSDK/Open-IM-Server/edit/main/deployments/README.md)
|
||||||
|
|
||||||
|
✅ 支持多架构镜像,我们的 Docker 镜像不仅托管在 GitHub 上,而且还在阿里云和 Docker Hub 上支持多个架构。请访问 [我们的 GitHub packages](https://github.com/orgs/OpenIMSDK/packages?repo_name=Open-IM-Server) 并阅读我们的 [版本管理文档](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md) 以获取更多信息。
|
||||||
|
|
||||||
|
10. **开源社区的大生态系统 🤲**
|
||||||
|
|
||||||
|
✅ 我们有数万用户和许多解决方案来解决问题。
|
||||||
|
|
||||||
|
✅ 我们有一个大型的开源社区叫 [OpenIMSDK](https://github.com/OpenIMSDK),它运行核心模块,我们还有一个开源社区叫 [openim-sigs](https://github.com/openim-sigs) 以探索更多基于 IM 的基础设施产品。
|
||||||
|
|
||||||
|
## :rocket: 快速开始
|
||||||
|
|
||||||
|
<details> <summary>使用 Docker Compose 部署</summary>
|
||||||
|
|
||||||
1. 克隆项目
|
1. 克隆项目
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/OpenIMSDK/Open-IM-Server
|
bashCopy code# 选择您需要的
|
||||||
cd Open-IM-Server
|
BRANCH=release-v3.1
|
||||||
git checkout release-v3.0 #or other release branch
|
git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make build
|
||||||
```
|
```
|
||||||
|
|
||||||
2. 修改 .env
|
> **注意** 阅读我们的发布策略:https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md
|
||||||
|
|
||||||
|
1. 修改 `.env`
|
||||||
|
|
||||||
```
|
```
|
||||||
此处主要修改相关组件密码
|
bashCopy codeUSER=root #无需修改
|
||||||
USER=root #不用修改
|
PASSWORD=openIM123 #8位或更多数字和字母的组合,此密码适用于redis、mysql、mongo,以及config/config.yaml中的accessSecret
|
||||||
PASSWORD=openIM123 #8位以上的数字和字母组合密码,密码对redis mysql mongo生效,以及config/config.yaml中的accessSecret
|
ENDPOINT=http://127.0.0.1:10005 #minio的外部服务IP和端口,或使用域名storage.xx.xx,应用程序必须能够访问此IP和端口或域名,
|
||||||
ENDPOINT=http://127.0.0.1:10005 #minio对外服务的ip和端口,或用域名storage.xx.xx,app要能访问到此ip和端口或域名,
|
API_URL=http://127.0.0.1:10002/object/ #应用程序必须能够访问此IP和端口或域名,
|
||||||
API_URL=http://127.0.0.1:10002/object/ #app要能访问到此ip和端口或域名,
|
|
||||||
DATA_DIR=./ #指定大磁盘目录
|
DATA_DIR=./ #指定大磁盘目录
|
||||||
```
|
```
|
||||||
|
|
||||||
3. 部署和启动
|
1. 部署并启动
|
||||||
|
|
||||||
注意:此命令只能执行一次,它会根据.env 中的 PASSWORD 变量修改 docker-compose 中组件密码,并修改 config/config.yaml 中的组件密码
|
> **注意** 此命令只能执行一次。它会基于 `.env` 中的 `PASSWORD` 变量修改 docker-compose 中的组件密码,并修改 `config/config.yaml` 中的组件密码。如果 `.env` 中的密码发生变化,您需要首先执行 `docker-compose down`;`rm components -rf` 然后执行此命令。
|
||||||
如果.env 中的密码变了,需要先 docker-compose down ; rm components -rf 后再执行此命令。
|
|
||||||
|
|
||||||
```
|
```
|
||||||
chmod +x install_im_server.sh;
|
bashCopy code
|
||||||
./install_im_server.sh;
|
make install
|
||||||
```
|
```
|
||||||
|
|
||||||
4. 检查服务
|
1. 检查服务
|
||||||
|
|
||||||
```
|
```
|
||||||
cd scripts;
|
bashCopy code
|
||||||
./docker_check_service.sh
|
make check
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 使用源码编译
|
</details> <details> <summary>从源码编译</summary>
|
||||||
|
|
||||||
1. Go 1.18或更高版本。
|
您需要 `Go 1.18` 或更高版本,以及 `make`。
|
||||||
|
|
||||||
2. 克隆
|
版本详情:https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/OpenIMSDK/Open-IM-Server
|
bashCopy code# 选择您需要的
|
||||||
cd Open-IM-Server
|
BRANCH=release-v3.1
|
||||||
git checkout release-v3.0 #or other release branch
|
git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make build
|
||||||
```
|
```
|
||||||
|
|
||||||
3. 编译
|
阅读关于 [OpenIM 版本策略](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md)
|
||||||
|
|
||||||
|
使用 `make help` 来查看 OpenIM 支持的指令。
|
||||||
|
|
||||||
|
如图所示,所有服务已成功构建
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
</details> <details> <summary>组件配置说明</summary>
|
||||||
|
|
||||||
|
config/config.yaml 文件为存储组件提供了详细的配置说明。
|
||||||
|
|
||||||
|
- Zookeeper
|
||||||
|
|
||||||
|
- 用于 RPC 服务发现和注册,支持集群。
|
||||||
|
|
||||||
```
|
```
|
||||||
cd Open-IM-server/scripts
|
bashCopy codezookeeper:
|
||||||
chmod +x *.sh
|
|
||||||
./build_all_service.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
所有服务已成功构建如图所示
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### 组件配置说明
|
|
||||||
|
|
||||||
config/config.yaml中针对存储组件有详细的配置说明
|
|
||||||
|
|
||||||
+ Zookeeper
|
|
||||||
+ 用于RPC 服务发现和注册,支持集群。
|
|
||||||
|
|
||||||
````
|
|
||||||
```
|
|
||||||
zookeeper:
|
|
||||||
schema: openim #不建议修改
|
schema: openim #不建议修改
|
||||||
address: [ 127.0.0.1:2181 ] #地址
|
address: [ 127.0.0.1:2181 ] #地址
|
||||||
username: #用户名
|
username: #用户名
|
||||||
password: #密码
|
password: #密码
|
||||||
```
|
```
|
||||||
````
|
|
||||||
|
|
||||||
|
- MySQL
|
||||||
|
|
||||||
|
- 用于存储用户、关系和群组,支持主从数据库。
|
||||||
+ MySQL
|
|
||||||
|
|
||||||
+ 用于存储用户、关系链、群组,支持数据库主备。
|
|
||||||
|
|
||||||
```
|
```
|
||||||
mysql:
|
bashCopy codemysql:
|
||||||
address: [ 127.0.0.1:13306 ] #地址
|
address: [ 127.0.0.1:13306 ] #地址
|
||||||
username: root #用户名
|
username: root #用户名
|
||||||
password: openIM123 #密码
|
password: openIM123 #密码
|
||||||
database: openIM_v2 #不建议修改
|
database: openIM_v2 #不建议修改
|
||||||
maxOpenConn: 1000 #最大连接数
|
maxOpenConn: 1000 #最大连接
|
||||||
maxIdleConn: 100 #最大空闲连接数
|
maxIdleConn: 100 #最大空闲连接
|
||||||
maxLifeTime: 60 #连接可以重复使用的最长时间(秒)
|
maxLifeTime: 60 #连接可重用的最大时间(秒)
|
||||||
logLevel: 4 #日志级别 1=slient 2=error 3=warn 4=info
|
logLevel: 4 #日志级别 1=静音 2=错误 3=警告 4=信息
|
||||||
slowThreshold: 500 #慢语句阈值 (毫秒)
|
slowThreshold: 500 #慢语句阈值(毫秒)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Mongo
|
||||||
|
|
||||||
|
- 用于存储离线消息,支持 mongo 分片集群。
|
||||||
+ Mongo
|
|
||||||
+ 用于存储离线消息,支持mongo分片集群。
|
|
||||||
|
|
||||||
```
|
```
|
||||||
mongo:
|
bashCopy codemongo:
|
||||||
uri: #不为空则直接使用该值
|
uri: #如果不为空,则直接使用此值
|
||||||
address: [ 127.0.0.1:37017 ] #地址
|
address: [ 127.0.0.1:37017 ] #地址
|
||||||
database: openIM #mongo db 默认即可
|
database: openIM #默认 mongo 数据库
|
||||||
username: root #用户名
|
username: root #用户名
|
||||||
password: openIM123 #密码
|
password: openIM123 #密码
|
||||||
maxPoolSize: 100 #最大连接数
|
maxPoolSize: 100 #最大连接数
|
||||||
```
|
```
|
||||||
|
|
||||||
+ Redis
|
- Redis
|
||||||
+ 用于存储消息序列号、最新消息、用户token及mysql缓存,支持集群部署。
|
|
||||||
|
- 用于存储消息序列号、最新消息、用户令牌和 mysql 缓存,支持集群部署。
|
||||||
|
|
||||||
```
|
```
|
||||||
redis:
|
bashCopy coderedis:
|
||||||
address: [ 127.0.0.1:16379 ] #地址
|
address: [ 127.0.0.1:16379 ] #地址
|
||||||
username: #用户名
|
username: #用户名
|
||||||
password: openIM123 #密码
|
password: openIM123 #密码
|
||||||
```
|
```
|
||||||
|
|
||||||
+ Kafka
|
- Kafka
|
||||||
+ 用于消息队列,用于消息解耦,支持集群部署。
|
|
||||||
|
- 用于消息队列,用于消息解耦,支持集群部署。
|
||||||
|
|
||||||
```
|
```
|
||||||
kafka:
|
bashCopy codekafka:
|
||||||
username: #用户名
|
username: #用户名
|
||||||
password: #密码
|
password: #密码
|
||||||
addr: [ 127.0.0.1:9092 ] #地址
|
addr: [ 127.0.0.1:9092 ] #地址
|
||||||
@@ -195,71 +254,104 @@ config/config.yaml中针对存储组件有详细的配置说明
|
|||||||
msgToModify: modify
|
msgToModify: modify
|
||||||
```
|
```
|
||||||
|
|
||||||
### 启停服务
|
</details> <details> <summary>启动和停止服务</summary>
|
||||||
|
|
||||||
启动服务
|
启动服务
|
||||||
|
|
||||||
```
|
```
|
||||||
./start_all.sh;
|
bashCopy code
|
||||||
|
./scripts/start-all.sh;
|
||||||
```
|
```
|
||||||
|
|
||||||
检查服务
|
检查服务
|
||||||
|
|
||||||
```
|
```
|
||||||
./check_all.sh
|
bashCopy code
|
||||||
|
./scripts/check-all.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
停止服务
|
停止服务
|
||||||
|
|
||||||
```
|
```
|
||||||
./stop_all.sh
|
bashCopy code
|
||||||
|
./scripts/stop-all.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### 开放 IM 端口
|
</details>
|
||||||
|
|
||||||
| TCP 端口 | 说明 | 操作 |
|
<details> <summary>开放 IM 端口</summary>
|
||||||
| --------- | ----------------------------------------------------- | --------------------------------------- |
|
|
||||||
| TCP:10001 | ws 协议,消息端口,如消息发送、推送等,用于客户端 SDK | 端口放行或 nginx 反向代理,并关闭防火墙 |
|
|
||||||
| TCP:10002 | api 端口,如用户、好友、群组、消息等接口。 | 端口放行或 nginx 反向代理,并关闭防火墙 |
|
|
||||||
| TCP:10005 | 选择 minio 存储时需要(openIM 默认使用 minio 存储) | 端口放行或 nginx 反向代理,并关闭防火墙 |
|
|
||||||
|
|
||||||
### 开放 Chat 端口
|
| TCP 端口 | 描述 | 操作 |
|
||||||
|
| --------- | --------------------------------------------------- | --------------------------------------- |
|
||||||
|
| TCP:10001 | ws 协议,消息端口如消息发送、推送等,用于客户端 SDK | 端口释放或 nginx 反向代理,并关闭防火墙 |
|
||||||
|
| TCP:10002 | api 端口,如用户、朋友、组、消息接口。 | 端口释放或 nginx 反向代理,并关闭防火墙 |
|
||||||
|
| TCP:10005 | 选择 minio 存储时所需 (openIM 默认使用 minio 存储) | 端口释放或 nginx 反向代理,并关闭防火墙 |
|
||||||
|
|
||||||
| TCP 端口 | 说明 | 操作 |
|
</details> <details> <summary>开放聊天端口</summary>
|
||||||
|
|
||||||
|
- 聊天仓库: https://github.com/OpenIMSDK/chat
|
||||||
|
|
||||||
|
| TCP 端口 | 描述 | 操作 |
|
||||||
| --------- | ------------------------ | --------------------------------------- |
|
| --------- | ------------------------ | --------------------------------------- |
|
||||||
| TCP:10008 | 业务系统,如注册、登录等 | 端口放行或 nginx 反向代理,并关闭防火墙 |
|
| TCP:10008 | 业务系统,如注册、登录等 | 端口释放或 nginx 反向代理,并关闭防火墙 |
|
||||||
| TCP:10009 | 管理后台,如统计、封号等 | 端口放行或 nginx 反向代理,并关闭防火墙 |
|
| TCP:10009 | 管理后台,如统计、封禁等 | 端口释放或 nginx 反向代理,并关闭防火墙 |
|
||||||
|
|
||||||
## APP和OpenIM关系
|
</details>
|
||||||
|
|
||||||
OpenIM 是开源的即时通讯组件,它并不是一个独立的产品,此图展示了AppServer、AppClient、Open-IM-Server以及Open-IM-SDK之间的关系
|
## :link: APP 和 OpenIM 之间的关系
|
||||||
|
|
||||||

|
OpenIM 不仅仅是一个开源的即时消息组件,它是您的应用程序生态系统的一个不可分割的部分。查看此图表以了解 AppServer、AppClient、Open-IM-Server 和 Open-IM-SDK 如何互动。
|
||||||
|
|
||||||
## 整体架构
|

|
||||||
|
|
||||||

|
## :building_construction: 总体架构
|
||||||
|
|
||||||
## 开始开发 OpenIM
|
深入了解 Open-IM-Server 的功能与我们的架构图。
|
||||||
|
|
||||||
[社区存储库](https://github.com/OpenIMSDK/community)包含有关从源代码构建 Kubernetes、如何贡献代码和文档。
|

|
||||||
|
|
||||||
## 贡献
|
## :hammer_and_wrench: 开始开发 OpenIM
|
||||||
|
|
||||||
欢迎对该项目进行贡献!请参见 [CONTRIBUTING.md](http://CONTRIBUTING.md) 了解详细信息。
|
OpenIM 我们的目标是建立一个顶级的开源社区。我们有一套标准,在 [Community repository](https://github.com/OpenIMSDK/community) 中。
|
||||||
|
|
||||||
## 社区会议
|
如果您想为这个 Open-IM-Server 仓库做贡献,请阅读我们的 [贡献者文档](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CONTRIBUTING.md)。
|
||||||
|
|
||||||
我们希望任何人都能参与我们的社区,我们提供礼品和奖励,并欢迎您每周四晚上加入我们。
|
在您开始之前,请确保您的更改是需要的。最好的方法是创建一个 [新的讨论](https://github.com/OpenIMSDK/Open-IM-Server/discussions/new/choose) 或 [Slack 通讯](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg),或者如果您发现一个问题,首先 [报告它](https://github.com/OpenIMSDK/Open-IM-Server/issues/new/choose)。
|
||||||
|
|
||||||
我们在 [GitHub 讨论](https://github.com/OpenIMSDK/Open-IM-Server/discussions/categories/meeting) 中记录每个 [两周会议](https://github.com/OpenIMSDK/Open-IM-Server/issues/381),我们的记录写在 [Google 文档](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing) 中。
|
- [代码标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/go_code.md)
|
||||||
|
- [Docker 图像标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md)
|
||||||
|
- [目录标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/directory.md)
|
||||||
|
- [提交标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/commit.md)
|
||||||
|
- [版本控制标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md)
|
||||||
|
- [接口标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/api.md)
|
||||||
|
- [日志标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/log.md)
|
||||||
|
- [错误代码标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/error_code.md)
|
||||||
|
|
||||||
## 谁在使用 Open-IM-Server
|
## :busts_in_silhouette: 社区
|
||||||
|
|
||||||
[用户案例研究](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) 页面包括该项目的用户列表。您可以留下 [📝评论](https://github.com/OpenIMSDK/Open-IM-Server/issues/379) 让我们知道您的用例。
|
- 📚 [OpenIM 社区](https://github.com/OpenIMSDK/community)
|
||||||
|
- 💕 [OpenIM 兴趣小组](https://github.com/Openim-sigs)
|
||||||
|
- 🚀 [加入我们的 Slack 社区](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg)
|
||||||
|
- :eyes: [加入我们的微信群 (微信群)](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
|
||||||
|
|
||||||

|
## :calendar: 社区会议
|
||||||
|
|
||||||
## 许可证
|
我们希望任何人都可以参与我们的社区并贡献代码,我们提供礼物和奖励,欢迎您每周四晚上加入我们。
|
||||||
|
|
||||||
Open-IM-Server 使用 Apache 2.0 许可证。有关详情,请参阅 LICENSE 文件。
|
我们的会议在 [OpenIM Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) 🎯,然后您可以搜索 Open-IM-Server 管道加入。
|
||||||
|
|
||||||
|
我们在 [GitHub 讨论](https://github.com/OpenIMSDK/Open-IM-Server/discussions/categories/meeting) 中记下每次 [双周会议](https://github.com/orgs/OpenIMSDK/discussions/categories/meeting) 的笔记,我们的历史会议记录以及会议回放都可在 [Google Docs :bookmark_tabs:](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing) 中找到。
|
||||||
|
|
||||||
|
## :eyes: 谁在使用 OpenIM
|
||||||
|
|
||||||
|
查看我们的 [用户案例研究](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) 页面以获取项目用户列表。不要犹豫,留下一个 [📝评论](https://github.com/OpenIMSDK/Open-IM-Server/issues/379) 并分享您的使用案例。
|
||||||
|
|
||||||
|
## :page_facing_up: 许可证
|
||||||
|
|
||||||
|
OpenIM 根据 Apache 2.0 许可证授权。请查看 [LICENSE](https://github.com/OpenIMSDK/Open-IM-Server/tree/main/LICENSE) 以获取完整的许可证文本。
|
||||||
|
|
||||||
|
OpenIM logo,包括其变体和动画版本,在此存储库 [OpenIM](https://github.com/OpenIMSDK/Open-IM-Server) 下的 [assets/logo](./assets/logo) 和 [assets/logo-gif](./assets/logo-gif) 目录中显示,受版权法保护。
|
||||||
|
|
||||||
|
## 🔮 感谢我们的贡献者!
|
||||||
|
|
||||||
|
<a href="https://github.com/OpenIMSDK/Open-IM-Server/graphs/contributors"> <img src="https://contrib.rocks/image?repo=OpenIMSDK/Open-IM-Server" /> </a>
|
||||||
@@ -22,42 +22,136 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="./README.md"><b> English </b></a> •
|
<a href="./README.md"><b> English </b></a> •
|
||||||
<a href="./README-zh_CN.md"><b> 中文 </b></a>
|
<a href="./README-zh_CN.md"><b> 简体中文 </b></a> •
|
||||||
|
<a href="https://www.openim.online/en"><b> Docs </b></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## What is Open-IM-Server
|
## ✨ About OpenIM
|
||||||
|
|
||||||
Open-IM-Server is an instant messaging server developed using pure Golang, adopting JSON over WebSocket as the communication protocol. In Open-IM-Server, everything is a message, so you can easily extend custom messages without modifying the server code. With a microservice architecture, Open-IM-Server can be deployed using clusters. By deploying Open-IM-Server on a server, developers can quickly integrate instant messaging and real-time networking features into their applications, ensuring the security and privacy of business data.
|
Open-IM-Server, meticulously developed in pure Golang, is a powerful instant messaging server. Its distinct communication method, employing pb+websocket, views every interaction as a message, streamlining customization without altering server code. Built on a microservice architecture, it offers deployment through clusters for outstanding performance and scalability.
|
||||||
|
|
||||||
Open-IM-Server is not a standalone product and does not include account registration and login services. For your convenience, we have open-sourced the [chat repository](https://github.com/OpenIMSDK/chat) which includes login and registration functionality. By deploying the chat business server alongside Open-IM-Server, a chat product can be set up.
|
Open-IM-Server is more than an instant messaging server; it's a powerful tool for incorporating real-time networking into your applications, positioning itself as your premier choice for integration! 🚀
|
||||||
|
|
||||||
## Features
|
Please be aware that Open-IM-Server does not function as a standalone product and does not offer built-in account registration or login services. To ease your implementation process, we've open-sourced the [chat repository](https://github.com/OpenIMSDK/chat), which comprises these features. Deploying this chat business server in conjunction with Open-IM-Server expedites the setup of a comprehensive chat product. 👥
|
||||||
|
|
||||||
- Open source
|
Further enhancing your experience, we also provide an SDK client, wherein most complex logics are implemented. The [SDK repository](https://github.com/OpenIMSDK/openim-sdk-core) can be found at [this link](https://github.com/OpenIMSDK/openim-sdk-core). The [chat repository](https://github.com/OpenIMSDK/chat) is our business server while the 'core' represents the high-level encapsulation of the SDK, synergistically working together to deliver superior results. ✨
|
||||||
- Easy to integrate
|
|
||||||
- Excellent scalability
|
|
||||||
- High performance
|
|
||||||
- Lightweight
|
|
||||||
- Supports multiple protocols
|
|
||||||
|
|
||||||
## Community
|
## :star2: Why OpenIM
|
||||||
- Visit the official website: [OpenIM Developer Documentation](https://www.openim.online/)
|
|
||||||
|
|
||||||
## Quick Start
|
**🔍 Function screenshot display**
|
||||||
|
|
||||||
### Deploying with docker-compose
|
<div align="center">
|
||||||
|
|
||||||
1. Clone the project
|
| 💻🔄📱 Multi Terminal Synchronization 🔄🖥️ | 📅⚡ Efficient Meetings 🚀💼 |
|
||||||
|
| :----------------------------------------------------------: | :---------------------------------------------------------: |
|
||||||
|
|  |  |
|
||||||
|
| 📲🔄 **One-to-one and Group Chats** 👥🗣️ | 🎁💻 **Special Features - Custom Messages** ✉️🎨|
|
||||||
|
|  |  |
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
1. **Comprehensive Message Type Support :speech_balloon:**
|
||||||
|
|
||||||
|
✅ Supports almost all types of messages, including text, images, emojis, voice, video, geographical location, files, quotes, business cards, system notifications, custom messages and more
|
||||||
|
|
||||||
|
✅ Supports one-on-one and multi-person audio and video calls
|
||||||
|
|
||||||
|
✅ Provides terminal support for multiple platforms such as iOS, Android, Flutter, uni-app, ReactNative, Electron, Web, H5
|
||||||
|
|
||||||
|
2. **Efficient Meetings Anytime, Anywhere :earth_americas:**
|
||||||
|
|
||||||
|
✅ Based on IM (Instant Messaging) with 100% reliable forced signaling capabilities, it paves the way for IM systems, deeply integrated with chat applications
|
||||||
|
|
||||||
|
✅ Supports hundreds of people in a single meeting, with subscription numbers reaching thousands, and server-side audio and video recording
|
||||||
|
|
||||||
|
3. **One-on-one and Group Chats for Various Social Scenarios :busts_in_silhouette:**
|
||||||
|
|
||||||
|
✅ OpenIM has four roles: application administrator, group owner, group administrator, and regular member
|
||||||
|
|
||||||
|
✅ Powerful group features such as muting, group announcements, group validation, unlimited group members, and loading group messages as needed
|
||||||
|
|
||||||
|
4. **Unique Features :star2:**
|
||||||
|
|
||||||
|
✅ Supports read-and-burn private chats, customizable duration
|
||||||
|
|
||||||
|
✅ Message editing function broadens social scenarios, making instant communication more diverse and interesting
|
||||||
|
|
||||||
|
5. **Open Source :open_hands:**
|
||||||
|
|
||||||
|
✅ The code of OpenIM is open source, self-controlled data, aimed at building a globally leading IM open source community, including client SDK and server
|
||||||
|
|
||||||
|
✅ Based on open source Server, many excellent open source projects have been developed, such as [OpenKF](https://github.com/OpenIMSDK/OpenKF) (Open source AI customer service system)
|
||||||
|
|
||||||
|
6. **Easy to Expand :wrench:**
|
||||||
|
|
||||||
|
✅ The OpenIM server is implemented in Golang, introducing an innovative "everything is a message" communication model, simplifying the implementation of custom messages and extended features
|
||||||
|
|
||||||
|
7. **High Performance :racing_car:**
|
||||||
|
|
||||||
|
✅ OpenIM supports a hierarchical governance architecture in the cluster, tested by a large number of users, and abstracts the storage model of online messages, offline messages, and historical messages
|
||||||
|
|
||||||
|
8. **Full Platform Support :tv:**
|
||||||
|
|
||||||
|
✅ Supports native iOS, Android; cross-platform Flutter, uni-app, ReactNative; major web front-end frameworks such as React, Vue; applets; and PC platforms supported by Electron
|
||||||
|
|
||||||
|
9. **The ultimate deployment experience 🤖**
|
||||||
|
|
||||||
|
✅ Supports [cluster deployment](https://github.com/OpenIMSDK/Open-IM-Server/edit/main/deployments/README.md)
|
||||||
|
|
||||||
|
✅ Supports multi-architecture mirroring, our Docker images are hosted not only on GitHub but also on Alibaba Cloud and Docker Hub supporting multiple architectures. Visit [our GitHub packages](https://github.com/orgs/OpenIMSDK/packages?repo_name=Open-IM-Server) and read our [version management document](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md) for more information.
|
||||||
|
|
||||||
|
11. **A large ecosystem of open source communities 🤲**
|
||||||
|
|
||||||
|
✅ We have tens of thousands of users and many solutions to problems.
|
||||||
|
|
||||||
|
✅ We have a large open source community called [OpenIMSDK](https://github.com/OpenIMSDK) that runs the core modules, we have an open source community called [openim-sigs](https://github.com/openim-sigs) to explore more IM-based infrastructure products.
|
||||||
|
|
||||||
|
## :rocket: Quick Start
|
||||||
|
|
||||||
|
You can quickly learn OpenIM engineering solutions, all it takes is one simple command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# choose what you need
|
$ make demo
|
||||||
BRANCH=release-v3.0
|
|
||||||
git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make build
|
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Modify .env
|
🤲 In order to facilitate the user experience, we have provided a variety of deployment solutions, you can choose your own deployment method according to the list below:
|
||||||
|
|
||||||
|
<details> <summary>Deploying with Docker Compose</summary>
|
||||||
|
|
||||||
|
|
||||||
|
> docker compose will not be maintained in future versions, but it is still the easiest and most convenient way to organize docker compose deployments into a separate project https://github.com/openim-sigs/openim-docker to maintain.
|
||||||
|
|
||||||
|
**1. Clone the project**
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# choose what you need, We take branch 3.2 as an example
|
||||||
|
$ BRANCH=release-v3.2
|
||||||
|
$ git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim/openim-server && export openim_dir=$(pwd)/openim && cd ${openim_dir}/openim-server
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note**
|
||||||
|
> If you don't know OpenIM's versioning policy, 📚Read our release policy: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**2. Configure the config file**
|
||||||
|
|
||||||
|
If you tried to get started quickly with `make demo`, then you know that our config file is generated by automation.
|
||||||
|
|
||||||
|
You can use `make init` to quickly initialize a configuration file
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make init
|
||||||
|
$ git diff
|
||||||
|
```
|
||||||
|
|
||||||
|
Then feel free to modify your current config file, you can also modify `/scripts/install/environment.sh` document template, `make init` is essentially rendering `environment.sh` template, and then through the `make init` to automatically generate a new configuration.
|
||||||
|
|
||||||
|
If you only need to change the config file for a short time, or if you don't want to make any major changes in the future, you can modify the `.env file directly
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
USER=root #no need to modify
|
USER=root #no need to modify
|
||||||
@@ -67,53 +161,69 @@ API_URL=http://127.0.0.1:10002/object/ #the app must be able to access this IP a
|
|||||||
DATA_DIR=./ #designate large disk directory
|
DATA_DIR=./ #designate large disk directory
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Deploy and start
|
**3. Deploy and start**
|
||||||
|
|
||||||
> **Note**
|
> **Note**
|
||||||
> 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.
|
>
|
||||||
|
> You can deploy either directly with `make install` or with `docker compose up`, the logic is the same
|
||||||
|
|
||||||
```
|
```bash
|
||||||
make install
|
$ make install
|
||||||
|
# OR
|
||||||
|
$ docker-compose up
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Check the service
|
4. Check the service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make check
|
$ make check
|
||||||
```
|
```
|
||||||
|
|
||||||

|
Looking at the command line at this point, there are two items in the output, checking for the start of the component port that OpenIM depends on, and the start of the OpenIM core component
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details> <summary>Compile from Source</summary>
|
||||||
|
|
||||||
### Compile from source
|
|
||||||
|
|
||||||
Ur need `Go 1.18` or higher version, and `make`.
|
Ur need `Go 1.18` or higher version, and `make`.
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go version && make --version || echo "Error: One of the commands failed."
|
||||||
|
```
|
||||||
|
|
||||||
Version Details: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md
|
Version Details: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# choose what you need
|
# choose what you need
|
||||||
BRANCH=release-v3.1
|
$ BRANCH=release-v3.1
|
||||||
git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make build
|
$ git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make start
|
||||||
```
|
```
|
||||||
Read about the [OpenIM Version Policy](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md)
|
|
||||||
|
|
||||||
`make help` to help you see the instructions supported by OpenIM.
|
> `make help` to help you see the instructions supported by OpenIM.
|
||||||
|
|
||||||
All services have been successfully built as shown in the figure
|
Use `make check` to check all component starts
|
||||||
|
|
||||||

|
```bash
|
||||||
|
$ make check
|
||||||
|
```
|
||||||
|
|
||||||
### Component Configuration Instructions
|
You can use the `make help-all` see OpenIM in action.
|
||||||
|
|
||||||
The config/config.yaml file has detailed configuration instructions for the storage components.
|
</details>
|
||||||
|
|
||||||
|
<details> <summary>Component Configuration Instructions</summary>
|
||||||
|
The `config/config.yaml` file has detailed configuration instructions for the storage components.
|
||||||
|
|
||||||
|
|
||||||
|
The config file is available via [environment.sh](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/scripts/install/environment.sh) configuration [openim.yaml](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployments/templates/openim.yaml) template, and then through the `make init` to automatically generate a new configuration.
|
||||||
|
|
||||||
- Zookeeper
|
- Zookeeper
|
||||||
|
|
||||||
- Used for RPC service discovery and registration, cluster support.
|
- Used for RPC service discovery and registration, cluster support.
|
||||||
|
|
||||||
```
|
```bash
|
||||||
zookeeper:
|
zookeeper:
|
||||||
schema: openim #Not recommended to modify
|
schema: openim #Not recommended to modify
|
||||||
address: [ 127.0.0.1:2181 ] #address
|
address: [ 127.0.0.1:2181 ] #address
|
||||||
@@ -125,7 +235,7 @@ The config/config.yaml file has detailed configuration instructions for the stor
|
|||||||
|
|
||||||
- Used for storing users, relationships, and groups, supports master-slave database.
|
- Used for storing users, relationships, and groups, supports master-slave database.
|
||||||
|
|
||||||
```
|
```bash
|
||||||
mysql:
|
mysql:
|
||||||
address: [ 127.0.0.1:13306 ] #address
|
address: [ 127.0.0.1:13306 ] #address
|
||||||
username: root #username
|
username: root #username
|
||||||
@@ -142,7 +252,7 @@ The config/config.yaml file has detailed configuration instructions for the stor
|
|||||||
|
|
||||||
- Used for storing offline messages, supports mongo sharded clusters.
|
- Used for storing offline messages, supports mongo sharded clusters.
|
||||||
|
|
||||||
```
|
```bash
|
||||||
mongo:
|
mongo:
|
||||||
uri: #Use this value directly if not empty
|
uri: #Use this value directly if not empty
|
||||||
address: [ 127.0.0.1:37017 ] #address
|
address: [ 127.0.0.1:37017 ] #address
|
||||||
@@ -156,7 +266,7 @@ The config/config.yaml file has detailed configuration instructions for the stor
|
|||||||
|
|
||||||
- Used for storing message sequence numbers, latest messages, user tokens, and mysql cache, supports cluster deployment.
|
- Used for storing message sequence numbers, latest messages, user tokens, and mysql cache, supports cluster deployment.
|
||||||
|
|
||||||
```
|
```bash
|
||||||
redis:
|
redis:
|
||||||
address: [ 127.0.0.1:16379 ] #address
|
address: [ 127.0.0.1:16379 ] #address
|
||||||
username: #username
|
username: #username
|
||||||
@@ -167,7 +277,7 @@ The config/config.yaml file has detailed configuration instructions for the stor
|
|||||||
|
|
||||||
- Used for message queues, for message decoupling, supports cluster deployment.
|
- Used for message queues, for message decoupling, supports cluster deployment.
|
||||||
|
|
||||||
```
|
```bash
|
||||||
kafka:
|
kafka:
|
||||||
username: #username
|
username: #username
|
||||||
password: #password
|
password: #password
|
||||||
@@ -188,27 +298,17 @@ The config/config.yaml file has detailed configuration instructions for the stor
|
|||||||
msgToModify: modify
|
msgToModify: modify
|
||||||
```
|
```
|
||||||
|
|
||||||
### Start and Stop Services
|
</details>
|
||||||
|
|
||||||
Start services
|
<details> <summary>Deployed with kubernetes</summary>
|
||||||
|
|
||||||
```
|
|
||||||
./start_all.sh;
|
|
||||||
```
|
|
||||||
|
|
||||||
Check services
|
read: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployments/README.md
|
||||||
|
|
||||||
```
|
</details>
|
||||||
./check_all.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Stop services
|
<details> <summary>Open IM Ports</summary>
|
||||||
|
|
||||||
```
|
|
||||||
./stop_all.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Open IM Ports
|
|
||||||
|
|
||||||
| TCP Port | Description | Operation |
|
| TCP Port | Description | Operation |
|
||||||
| --------- | ------------------------------------------------------------ | ----------------------------------------------------- |
|
| --------- | ------------------------------------------------------------ | ----------------------------------------------------- |
|
||||||
@@ -216,42 +316,77 @@ Stop services
|
|||||||
| TCP:10002 | api port, such as user, friend, group, message interfaces. | Port release or nginx reverse proxy, and firewall off |
|
| TCP:10002 | api port, such as user, friend, group, message interfaces. | Port release or nginx reverse proxy, and firewall off |
|
||||||
| TCP:10005 | Required when choosing minio storage (openIM uses minio storage by default) | Port release or nginx reverse proxy, and firewall off |
|
| TCP:10005 | Required when choosing minio storage (openIM uses minio storage by default) | Port release or nginx reverse proxy, and firewall off |
|
||||||
|
|
||||||
### Open Chat Ports
|
</details>
|
||||||
|
|
||||||
|
<details> <summary>Open Chat Ports</summary>
|
||||||
|
|
||||||
|
|
||||||
|
+ chat warehouse: https://github.com/OpenIMSDK/chat
|
||||||
|
|
||||||
| TCP Port | Description | Operation |
|
| TCP Port | Description | Operation |
|
||||||
| --------- | --------------------------------------------------- | ----------------------------------------------------- |
|
| --------- | --------------------------------------------------- | ----------------------------------------------------- |
|
||||||
| TCP:10008 | Business system, such as registration, login etc | Port release or nginx reverse proxy, and firewall off |
|
| TCP:10008 | Business system, such as registration, login etc | Port release or nginx reverse proxy, and firewall off |
|
||||||
| TCP:10009 | Management backend, such as statistics, banning etc | Port release or nginx reverse proxy, and firewall off |
|
| TCP:10009 | Management backend, such as statistics, banning etc | Port release or nginx reverse proxy, and firewall off |
|
||||||
|
|
||||||
## Relationship Between APP and OpenIM
|
</details>
|
||||||
|
|
||||||
OpenIM is an open source instant messaging component, it is not an independent product. This image shows the relationship between AppServer, AppClient, Open-IM-Server and Open-IM-SDK.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Overall Architecture
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## To start developing OpenIM
|
|
||||||
The [community repository](https://github.com/OpenIMSDK/community) hosts all information about building Kubernetes from source, how to contribute code and documentation, who to contact about what, etc.
|
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
## :link: Relationship Between APP and OpenIM
|
||||||
|
|
||||||
Contributions to this project are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for details.
|
OpenIM isn't just an open-source instant messaging component, it's an integral part of your application ecosystem. Check out this diagram to understand how AppServer, AppClient, Open-IM-Server, and Open-IM-SDK interact.
|
||||||
|
|
||||||
## Community Meetings
|

|
||||||
We want anyone to get involved in our community, we offer gifts and rewards, and we welcome you to join us every Thursday night.
|
|
||||||
|
|
||||||
We take notes of each [biweekly meeting](https://github.com/OpenIMSDK/Open-IM-Server/issues/381) in [GitHub discussions](https://github.com/OpenIMSDK/Open-IM-Server/discussions/categories/meeting), and our minutes are written in [Google Docs](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing).
|
## :building_construction: Overall Architecture
|
||||||
|
|
||||||
|
Delve into the heart of Open-IM-Server's functionality with our architecture diagram.
|
||||||
|
|
||||||
## Who are using Open-IM-Server
|

|
||||||
The [user case studies](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) page includes the user list of the project. You can leave a [📝comment](https://github.com/OpenIMSDK/Open-IM-Server/issues/379) to let us know your use case.
|
|
||||||
|
|
||||||

|
## :hammer_and_wrench: To start developing OpenIM
|
||||||
|
|
||||||
## License
|
OpenIM Our goal is to build a top-level open source community. We have a set of standards, in the [Community repository](https://github.com/OpenIMSDK/community).
|
||||||
|
|
||||||
Open-IM-Server is under the Apache 2.0 license. See the [LICENSE](./LICENSE) file for details
|
If you'd like to contribute to this Open-IM-Server repository, please read our [contributor documentation](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
Before you start, please make sure your changes are in demand. The best for that is to create a [new discussion](https://github.com/OpenIMSDK/Open-IM-Server/discussions/new/choose) OR [Slack Communication](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg), or if you find an issue, [report it](https://github.com/OpenIMSDK/Open-IM-Server/issues/new/choose) first.
|
||||||
|
|
||||||
|
- [Code Standards](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/go_code.md)
|
||||||
|
- [Docker Images Standards](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md)
|
||||||
|
- [Directory Standards](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/directory.md)
|
||||||
|
- [Commit Standards](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/commit.md)
|
||||||
|
- [Versioning Standards](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md)
|
||||||
|
- [Interface Standards](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/api.md)
|
||||||
|
- [Log Standards](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/log.md)
|
||||||
|
- [Error Code Standards](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/error_code.md)
|
||||||
|
|
||||||
|
## :busts_in_silhouette: Community
|
||||||
|
|
||||||
|
+ 📚 [OpenIM Community](https://github.com/OpenIMSDK/community)
|
||||||
|
+ 💕 [OpenIM Interest Group](https://github.com/Openim-sigs)
|
||||||
|
+ 🚀 [Join our Slack community](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg)
|
||||||
|
+ :eyes: [Join our wechat (微信群)](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
|
||||||
|
|
||||||
|
## :calendar: Community Meetings
|
||||||
|
|
||||||
|
We want anyone to get involved in our community and contributing code, we offer gifts and rewards, and we welcome you to join us every Thursday night.
|
||||||
|
|
||||||
|
Our conference is in the [OpenIM Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) 🎯, then you can search the Open-IM-Server pipeline to join
|
||||||
|
|
||||||
|
We take notes of each [biweekly meeting](https://github.com/orgs/OpenIMSDK/discussions/categories/meeting) in [GitHub discussions](https://github.com/OpenIMSDK/Open-IM-Server/discussions/categories/meeting), Our historical meeting notes, as well as replays of the meetings are available at [Google Docs :bookmark_tabs:](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing).
|
||||||
|
|
||||||
|
## :eyes: Who are using OpenIM
|
||||||
|
|
||||||
|
Check out our [user case studies](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) page for a list of the project users. Don't hesitate to leave a [📝comment](https://github.com/OpenIMSDK/Open-IM-Server/issues/379) and share your use case.
|
||||||
|
|
||||||
|
## :page_facing_up: License
|
||||||
|
|
||||||
|
OpenIM is licensed under the Apache 2.0 license. See [LICENSE](https://github.com/OpenIMSDK/Open-IM-Server/tree/main/LICENSE) for the full license text.
|
||||||
|
|
||||||
|
The OpenIM logo, including its variations and animated versions, displayed in this repository [OpenIM](https://github.com/OpenIMSDK/Open-IM-Server) under the [assets/logo](./assets/logo) and [assets/logo-gif](assets/logo-gif) directories, are protected by copyright laws.
|
||||||
|
|
||||||
|
## 🔮 Thanks to our contributors!
|
||||||
|
|
||||||
|
<a href="https://github.com/OpenIMSDK/Open-IM-Server/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=OpenIMSDK/Open-IM-Server" />
|
||||||
|
</a>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
## :star2: Why OpenIM
|
||||||
|
|
||||||
|
**🔍 Function screenshot display**
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
|
||||||
|
| multiple message | Efficient meetings |
|
||||||
|
| :---------------------------------------: | :---------------------------------------------: |
|
||||||
|
|  |  |
|
||||||
|
| **One-to-one and group chats** | **Special features - Custom messages** |
|
||||||
|
|  |  |
|
||||||
|
|
||||||
|
</div>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 418 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 931 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 318 KiB |
@@ -479,53 +479,4 @@ checksum:
|
|||||||
algorithm: sha256
|
algorithm: sha256
|
||||||
|
|
||||||
release:
|
release:
|
||||||
|
|
||||||
prerelease: auto
|
prerelease: auto
|
||||||
|
|
||||||
footer: |
|
|
||||||
|
|
||||||
## Welcome to the {{ .Tag }} release of [chat](https://github.com/OpenIMSDK/chat)!🎉🎉!
|
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/OpenIMSDK/Open-IM-Server/compare/{{ .PreviousTag }}...{{ .Tag }}
|
|
||||||
|
|
||||||
## Helping out
|
|
||||||
|
|
||||||
+ We release logs are recorded on [✨CHANGELOG](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CHANGELOG/CHANGELOG.md)
|
|
||||||
|
|
||||||
+ For information on versions of OpenIM and how to maintain branches, read [📚this article](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md)
|
|
||||||
|
|
||||||
+ If you wish to use mirroring, read OpenIM's [image management policy](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md)
|
|
||||||
|
|
||||||
**Want to be one of them 😘?**
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://github.com/kubbot" style="float: left; margin-right: 10px;">
|
|
||||||
<img src="https://github.com/openimbot/openimbot/blob/main/assets/icon/blue%E9%80%8F%E6%98%8E.png" width="50" height="50" />
|
|
||||||
</a>
|
|
||||||
<a href="https://www.openim.online">
|
|
||||||
<img src="https://github.com/OpenIMSDK/Open-IM-Server/blob/main/assets/logo/openim-logo.png" />
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/openimbot" style="float: right; margin-left: 10px;">
|
|
||||||
<img src="https://github.com/openimbot/openimbot/blob/main/assets/icon/red%E9%80%8F%E6%98%8E.png" width="50" height="50" />
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
> **Note**
|
|
||||||
> @openimbot and @kubbot have made great contributions to the community as community 🤖robots(@openimsdk/bot), respectively.
|
|
||||||
> Thanks to the @openimsdk/openim team for all their hard work on this release.
|
|
||||||
> Thank you to all the [💕developers and contributors](https://github.com/OpenIMSDK/Open-IM-Server/graphs/contributors), people from all over the world, OpenIM brings us together
|
|
||||||
> Contributions to this project are welcome! Please see [CONTRIBUTING.md](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CONTRIBUTING.md) for details.
|
|
||||||
|
|
||||||
## Get Involved with OpenIM!
|
|
||||||
|
|
||||||
**Here are some ways to get involved with the OpenIM community:**
|
|
||||||
|
|
||||||
📢 **Slack Channel**: Join our Slack channels for discussions, communication, and support. Click [here](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to join the Open-IM-Server Slack team channel.
|
|
||||||
|
|
||||||
📧 **Gmail Contact**: If you have any questions, suggestions, or feedback for our open-source projects, please feel free to [contact us via email](https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=winxu81@gmail.com).
|
|
||||||
|
|
||||||
📖 **Blog**: Stay up-to-date with OpenIM-Server projects and trends by reading our [blog](https://doc.rentsoft.cn/). We share the latest developments, tech trends, and other interesting information related to OpenIM.
|
|
||||||
|
|
||||||
📱 **WeChat**: Add us on WeChat (QR Code) and indicate that you are a user or developer of Open-IM-Server. We'll process your request as soon as possible.
|
|
||||||
|
|
||||||
Remember, your contributions play a vital role in making OpenIM successful, and we look forward to your active participation in our community! 🙌
|
|
||||||
@@ -34,6 +34,7 @@ COPY . .
|
|||||||
RUN make clean
|
RUN make clean
|
||||||
RUN make build BINS=openim-api
|
RUN make build BINS=openim-api
|
||||||
|
|
||||||
|
# FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
||||||
FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
||||||
|
|
||||||
WORKDIR /openim/openim-server
|
WORKDIR /openim/openim-server
|
||||||
@@ -41,6 +42,8 @@ WORKDIR /openim/openim-server
|
|||||||
COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
||||||
COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||||
|
|
||||||
EXPOSE ${10002}
|
ENV PORT 10002
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-api --port 10002 -c ${SERVER_WORKDIR}/config"]
|
EXPOSE ${PORT}
|
||||||
|
|
||||||
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-api --port ${PORT} -c ${SERVER_WORKDIR}/config"]
|
||||||
@@ -39,7 +39,7 @@ FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
|||||||
|
|
||||||
WORKDIR /openim/openim-server
|
WORKDIR /openim/openim-server
|
||||||
|
|
||||||
COPY --from=builder ${SERVER_WORKDIR}/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
COPY --from=builder $OPENIM_SERVER_BINDIR/platforms /openim/openim-server/_output/bin/platforms
|
||||||
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
|
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-cmdutils"]
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-cmdutils"]
|
||||||
@@ -41,4 +41,4 @@ WORKDIR /openim/openim-server
|
|||||||
COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
||||||
COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-crontask"]
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-crontask"]
|
||||||
+1
-1
@@ -47,4 +47,4 @@ ENV ARCH ${ARCH}
|
|||||||
EXPOSE 10140
|
EXPOSE 10140
|
||||||
EXPOSE 10001
|
EXPOSE 10001
|
||||||
|
|
||||||
CMD ${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-msggateway --port 10140 --ws_port 10001
|
CMD ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-msggateway --port 10140 --ws_port 10001
|
||||||
+1
-1
@@ -44,4 +44,4 @@ WORKDIR /openim/openim-server
|
|||||||
COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
||||||
COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||||
|
|
||||||
CMD ${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-msgtransfer
|
CMD ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-msgtransfer
|
||||||
@@ -46,4 +46,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
|||||||
|
|
||||||
EXPOSE 10170
|
EXPOSE 10170
|
||||||
|
|
||||||
CMD ${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-push --port 10170
|
CMD ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-push --port 10170
|
||||||
@@ -49,4 +49,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
|||||||
|
|
||||||
EXPOSE 10160
|
EXPOSE 10160
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-auth --port 10160 -c ${SERVER_WORKDIR}/config"]
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-auth --port 10160 -c ${SERVER_WORKDIR}/config"]
|
||||||
+1
-1
@@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
|||||||
EXPOSE 10230
|
EXPOSE 10230
|
||||||
EXPOSE 20230
|
EXPOSE 20230
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-conversation --port 10230 --prometheus_port 20230 -c ${SERVER_WORKDIR}/config"]
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-conversation --port 10230 --prometheus_port 20230 -c ${SERVER_WORKDIR}/config"]
|
||||||
+1
-1
@@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
|||||||
EXPOSE 10120
|
EXPOSE 10120
|
||||||
EXPOSE 20120
|
EXPOSE 20120
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-friend --port 10120 --prometheus_port 20120 -c ${SERVER_WORKDIR}/config"]
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-friend --port 10120 --prometheus_port 20120 -c ${SERVER_WORKDIR}/config"]
|
||||||
@@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
|||||||
EXPOSE 10150
|
EXPOSE 10150
|
||||||
EXPOSE 20150
|
EXPOSE 20150
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-group --port 10150 --prometheus_port 20150 -c ${SERVER_WORKDIR}/config"]
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-group --port 10150 --prometheus_port 20150 -c ${SERVER_WORKDIR}/config"]
|
||||||
@@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
|||||||
EXPOSE 10130
|
EXPOSE 10130
|
||||||
EXPOSE 20130
|
EXPOSE 20130
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-msg --port 10130 --prometheus_port 20130 -c ${SERVER_WORKDIR}/config"]
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-msg --port 10130 --prometheus_port 20130 -c ${SERVER_WORKDIR}/config"]
|
||||||
@@ -55,4 +55,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
|||||||
|
|
||||||
EXPOSE 10200
|
EXPOSE 10200
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-third --port 10200 -c ${SERVER_WORKDIR}/config"]
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-third --port 10200 -c ${SERVER_WORKDIR}/config"]
|
||||||
@@ -55,4 +55,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
|||||||
|
|
||||||
EXPOSE 10110
|
EXPOSE 10110
|
||||||
|
|
||||||
CMD ["sh","-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-user --port 10110 -c ${SERVER_WORKDIR}/config"]
|
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-user --port 10110 -c ${SERVER_WORKDIR}/config"]
|
||||||
@@ -21,7 +21,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cronTaskCmd := cmd.NewCronTaskCmd()
|
cronTaskCmd := cmd.NewCronTaskCmd()
|
||||||
if err := cronTaskCmd.Exec(tools.StartCronTask); err != nil {
|
if err := cronTaskCmd.Exec(tools.StartTask); err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,378 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
# Infrastructural configurations, please modify based on your setup
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
|
||||||
|
###################### Zookeeper ######################
|
||||||
|
# Zookeeper configuration
|
||||||
|
# It's not recommended to modify the schema
|
||||||
|
#
|
||||||
|
# Zookeeper address
|
||||||
|
# Zookeeper username
|
||||||
|
# Zookeeper password
|
||||||
|
zookeeper:
|
||||||
|
schema: openim
|
||||||
|
address: [ 127.0.0.1:2181 ]
|
||||||
|
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: [ 127.0.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
|
||||||
|
#
|
||||||
|
# MongoDB address for standalone setup, Mongos address for sharded cluster setup
|
||||||
|
# Default MongoDB database name
|
||||||
|
# Maximum connection pool size
|
||||||
|
mongo:
|
||||||
|
uri:
|
||||||
|
address: [ 127.0.0.1:37017 ]
|
||||||
|
database: openIM_v3
|
||||||
|
username: root
|
||||||
|
password: openIM123
|
||||||
|
maxPoolSize: 100
|
||||||
|
|
||||||
|
###################### Redis ######################
|
||||||
|
# Redis configuration
|
||||||
|
#
|
||||||
|
# Username is required only for Redis version 6.0+
|
||||||
|
redis:
|
||||||
|
address: [ 127.0.0.1:16379 ]
|
||||||
|
username:
|
||||||
|
password: openIM123
|
||||||
|
|
||||||
|
###################### Kafka ######################
|
||||||
|
# Kafka configuration
|
||||||
|
#
|
||||||
|
# Kafka username
|
||||||
|
# Kafka password
|
||||||
|
# It's not recommended to modify this topic name
|
||||||
|
# Consumer group ID, it's not recommended to modify
|
||||||
|
kafka:
|
||||||
|
username:
|
||||||
|
password:
|
||||||
|
addr: [ 127.0.0.1:9092 ]
|
||||||
|
latestMsgToRedis:
|
||||||
|
topic: "latestMsgToRedis"
|
||||||
|
offlineMsgToMongo:
|
||||||
|
topic: "offlineMsgToMongoMysql"
|
||||||
|
msgToPush:
|
||||||
|
topic: "msgToPush"
|
||||||
|
consumerGroupID:
|
||||||
|
msgToRedis: redis
|
||||||
|
msgToMongo: mongo
|
||||||
|
msgToMySql: mysql
|
||||||
|
msgToPush: push
|
||||||
|
|
||||||
|
###################### RPC ######################
|
||||||
|
# RPC configuration
|
||||||
|
#
|
||||||
|
# IP address to register with zookeeper when starting RPC, the IP and corresponding rpcPort should be accessible by api/gateway
|
||||||
|
# Default listen IP is 0.0.0.0
|
||||||
|
rpc:
|
||||||
|
registerIP:
|
||||||
|
listenIP: 0.0.0.0
|
||||||
|
|
||||||
|
###################### API ######################
|
||||||
|
# API configuration
|
||||||
|
#
|
||||||
|
# API service port
|
||||||
|
# Default listen IP is 0.0.0.0
|
||||||
|
api:
|
||||||
|
openImApiPort: [ 10002 ]
|
||||||
|
listenIP: 0.0.0.0
|
||||||
|
|
||||||
|
###################### Gateway ######################
|
||||||
|
# Object storage configuration
|
||||||
|
#
|
||||||
|
# Use minio for object storage
|
||||||
|
# API URL should be accessible by the app
|
||||||
|
# It's not recommended to modify the bucket name
|
||||||
|
# Endpoint should be accessible by the app
|
||||||
|
# Session token
|
||||||
|
# Configuration for Tencent COS
|
||||||
|
# Configuration for Aliyun OSS
|
||||||
|
# apiURL is the address of the api, the access address of the app, use s3 must be configured
|
||||||
|
# minio.endpoint can be configured as an intranet address,
|
||||||
|
# minio.signEndpoint is minio public network address
|
||||||
|
object:
|
||||||
|
enable: "minio"
|
||||||
|
apiURL: "http://127.0.0.1:10002"
|
||||||
|
minio:
|
||||||
|
bucket: "openim"
|
||||||
|
endpoint: "http://127.0.0.1:10005"
|
||||||
|
accessKeyID: "root"
|
||||||
|
secretAccessKey: "openIM123"
|
||||||
|
sessionToken: ""
|
||||||
|
signEndpoint: "http://127.0.0.1:10005"
|
||||||
|
cos:
|
||||||
|
bucketURL: "https://temp-1252357374.cos.ap-chengdu.myqcloud.com"
|
||||||
|
secretID: ""
|
||||||
|
secretKey: ""
|
||||||
|
sessionToken: ""
|
||||||
|
oss:
|
||||||
|
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
|
||||||
|
bucket: "demo-9999999"
|
||||||
|
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
|
||||||
|
accessKeyID: ""
|
||||||
|
accessKeySecret: ""
|
||||||
|
sessionToken: ""
|
||||||
|
|
||||||
|
# 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:
|
||||||
|
openImUserPort: [ 10110 ]
|
||||||
|
openImFriendPort: [ 10120 ]
|
||||||
|
openImMessagePort: [ 10130 ]
|
||||||
|
openImMessageGatewayPort: [ 10140 ]
|
||||||
|
openImGroupPort: [ 10150 ]
|
||||||
|
openImAuthPort: [ 10160 ]
|
||||||
|
openImPushPort: [ 10170 ]
|
||||||
|
openImConversationPort: [ 10180 ]
|
||||||
|
openImThirdPort: [ 10190 ]
|
||||||
|
|
||||||
|
# RPC service names for registration, it's not recommended to modify these
|
||||||
|
rpcRegisterName:
|
||||||
|
openImUserName: User
|
||||||
|
openImFriendName: Friend
|
||||||
|
openImMsgName: Msg
|
||||||
|
openImPushName: Push
|
||||||
|
openImMessageGatewayName: MessageGateway
|
||||||
|
openImGroupName: Group
|
||||||
|
openImAuthName: Auth
|
||||||
|
openImConversationName: Conversation
|
||||||
|
openImThirdName: Third
|
||||||
|
|
||||||
|
# Log configuration
|
||||||
|
#
|
||||||
|
# Storage directory
|
||||||
|
# Log rotation time
|
||||||
|
# Maximum number of logs to retain
|
||||||
|
# Log level, 6 means all levels
|
||||||
|
# Whether to output to stdout
|
||||||
|
# Whether to output in json format
|
||||||
|
# Whether to include stack trace in logs
|
||||||
|
log:
|
||||||
|
storageLocation: ../../../../../logs/
|
||||||
|
rotationTime: 24
|
||||||
|
remainRotationCount: 2
|
||||||
|
remainLogLevel: 6
|
||||||
|
isStdout: false
|
||||||
|
isJson: false
|
||||||
|
withStack: false
|
||||||
|
|
||||||
|
# Long connection server configuration
|
||||||
|
#
|
||||||
|
# Websocket port for msg_gateway
|
||||||
|
# Maximum number of websocket connections
|
||||||
|
# Maximum length of websocket request package
|
||||||
|
# Websocket connection handshake timeout
|
||||||
|
longConnSvr:
|
||||||
|
openImWsPort: [ 10001 ]
|
||||||
|
websocketMaxConnNum: 100000
|
||||||
|
websocketMaxMsgLen: 4096
|
||||||
|
websocketTimeout: 10
|
||||||
|
|
||||||
|
# Push notification service configuration
|
||||||
|
#
|
||||||
|
# Use GeTui for push notifications
|
||||||
|
# GeTui offline push configuration
|
||||||
|
# FCM offline push configuration
|
||||||
|
# Account file, place it in the config directory
|
||||||
|
# JPush configuration, modify these after applying in JPush backend
|
||||||
|
push:
|
||||||
|
enable: getui
|
||||||
|
geTui:
|
||||||
|
pushUrl: "https://restapi.getui.com/v2/$appId"
|
||||||
|
masterSecret: ""
|
||||||
|
appKey: ""
|
||||||
|
intent: ""
|
||||||
|
channelID: ""
|
||||||
|
channelName: ""
|
||||||
|
fcm:
|
||||||
|
serviceAccount: "x.json"
|
||||||
|
jpns:
|
||||||
|
appKey:
|
||||||
|
masterSecret:
|
||||||
|
pushUrl:
|
||||||
|
pushIntent:
|
||||||
|
|
||||||
|
# App manager configuration
|
||||||
|
#
|
||||||
|
# Built-in app manager user IDs
|
||||||
|
# Built-in app manager nicknames
|
||||||
|
manager:
|
||||||
|
userID: [ "openIM123456","openIM654321","openIMAdmin" ]
|
||||||
|
nickname: [ "system1","system2", "system3" ]
|
||||||
|
|
||||||
|
# Multi-platform login policy
|
||||||
|
# For each platform(Android, iOS, Windows, Mac, web), only one can be online at a time
|
||||||
|
multiLoginPolicy: 1
|
||||||
|
|
||||||
|
# Whether to store messages in MySQL, messages in MySQL are only used for management background
|
||||||
|
chatPersistenceMysql: true
|
||||||
|
|
||||||
|
# Message cache timeout in seconds, it's not recommended to modify
|
||||||
|
msgCacheTimeout: 86400
|
||||||
|
|
||||||
|
# Whether to enable read receipts for group chat
|
||||||
|
groupMessageHasReadReceiptEnable: true
|
||||||
|
|
||||||
|
# Whether to enable read receipts for single chat
|
||||||
|
singleMessageHasReadReceiptEnable: true
|
||||||
|
|
||||||
|
# MongoDB offline message retention period in days
|
||||||
|
retainChatRecords: 365
|
||||||
|
|
||||||
|
# Schedule to clear expired messages(older than retainChatRecords days) in MongoDB every Wednesday at 2am
|
||||||
|
# This deletion is just for cleaning up disk usage according to previous configuration retainChatRecords, no notification will be sent
|
||||||
|
chatRecordsClearTime: "0 2 * * 3"
|
||||||
|
|
||||||
|
# Schedule to auto delete messages every day at 2am
|
||||||
|
# This deletion is for messages that have been retained for more than msg_destruct_time (seconds) in the conversation field
|
||||||
|
msgDestructTime: "0 2 * * *"
|
||||||
|
|
||||||
|
# Secret key
|
||||||
|
secret: openIM123
|
||||||
|
|
||||||
|
# Token policy
|
||||||
|
#
|
||||||
|
# Token expiration period in days
|
||||||
|
tokenPolicy:
|
||||||
|
expire: 90
|
||||||
|
|
||||||
|
# Message verification policy
|
||||||
|
#
|
||||||
|
# Whether to verify friendship when sending messages
|
||||||
|
messageVerify:
|
||||||
|
friendVerify: false
|
||||||
|
|
||||||
|
# iOS push notification configuration
|
||||||
|
#
|
||||||
|
# iOS push notification sound
|
||||||
|
# Whether to count badge
|
||||||
|
# Whether it's production environment
|
||||||
|
iosPush:
|
||||||
|
pushSound: "xxx"
|
||||||
|
badgeCount: true
|
||||||
|
production: false
|
||||||
|
|
||||||
|
# Callback configuration
|
||||||
|
#
|
||||||
|
# Callback URL
|
||||||
|
# Whether to enable this callback event
|
||||||
|
# Timeout in seconds
|
||||||
|
# Whether to continue execution if callback fails
|
||||||
|
callback:
|
||||||
|
url:
|
||||||
|
beforeSendSingleMsg:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
afterSendSingleMsg:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
beforeSendGroupMsg:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
afterSendGroupMsg:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
msgModify:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
userOnline:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
userOffline:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
userKickOff:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
offlinePush:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
onlinePush:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
superGroupOnlinePush:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
beforeAddFriend:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
beforeCreateGroup:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
beforeMemberJoinGroup:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
beforeSetGroupMemberInfo:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
setMessageReactionExtensions:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
|
||||||
|
###################### Prometheus ######################
|
||||||
|
# Prometheus configuration
|
||||||
|
# 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
|
||||||
|
userPrometheusPort: [ 20110 ]
|
||||||
|
friendPrometheusPort: [ 20120 ]
|
||||||
|
messagePrometheusPort: [ 20130 ]
|
||||||
|
messageGatewayPrometheusPort: [ 20140 ]
|
||||||
|
groupPrometheusPort: [ 20150 ]
|
||||||
|
authPrometheusPort: [ 20160 ]
|
||||||
|
pushPrometheusPort: [ 20170 ]
|
||||||
|
conversationPrometheusPort: [ 20230 ]
|
||||||
|
rtcPrometheusPort: [ 21300 ]
|
||||||
|
thirdPrometheusPort: [ 21301 ]
|
||||||
|
messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ]
|
||||||
+9
-5
@@ -124,15 +124,19 @@ api:
|
|||||||
# Session token
|
# Session token
|
||||||
# Configuration for Tencent COS
|
# Configuration for Tencent COS
|
||||||
# Configuration for Aliyun OSS
|
# Configuration for Aliyun OSS
|
||||||
|
# apiURL is the address of the api, the access address of the app, use s3 must be configured
|
||||||
|
# minio.endpoint can be configured as an intranet address,
|
||||||
|
# minio.signEndpoint is minio public network address
|
||||||
object:
|
object:
|
||||||
enable: "minio"
|
enable: "minio"
|
||||||
apiURL: http://127.0.0.1:10002/object/
|
apiURL: "http://127.0.0.1:10002"
|
||||||
minio:
|
minio:
|
||||||
bucket: "openim"
|
bucket: "openim"
|
||||||
endpoint: http://127.0.0.1:10005
|
endpoint: "http://127.0.0.1:10005"
|
||||||
accessKeyID: root
|
accessKeyID: "root"
|
||||||
secretAccessKey: openIM123
|
secretAccessKey: "openIM123"
|
||||||
sessionToken: ""
|
sessionToken: ""
|
||||||
|
signEndpoint: "http://127.0.0.1:10005"
|
||||||
cos:
|
cos:
|
||||||
bucketURL: "https://temp-1252357374.cos.ap-chengdu.myqcloud.com"
|
bucketURL: "https://temp-1252357374.cos.ap-chengdu.myqcloud.com"
|
||||||
secretID: ""
|
secretID: ""
|
||||||
@@ -142,7 +146,7 @@ object:
|
|||||||
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
|
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
|
||||||
bucket: "demo-9999999"
|
bucket: "demo-9999999"
|
||||||
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
|
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
|
||||||
accessKeyID: root
|
accessKeyID: ""
|
||||||
accessKeySecret: ""
|
accessKeySecret: ""
|
||||||
sessionToken: ""
|
sessionToken: ""
|
||||||
|
|
||||||
|
|||||||
@@ -304,6 +304,16 @@ userInfoUpdated:
|
|||||||
desc: "Remove a blocked user"
|
desc: "Remove a blocked user"
|
||||||
ext: "Remove a blocked user"
|
ext: "Remove a blocked user"
|
||||||
|
|
||||||
|
userStatusChanged:
|
||||||
|
isSendMsg: false
|
||||||
|
reliabilityLevel: 1
|
||||||
|
unreadCount: false
|
||||||
|
offlinePush:
|
||||||
|
enable: false
|
||||||
|
title: "user status changed"
|
||||||
|
desc: "user status changed"
|
||||||
|
ext: "user status changed"
|
||||||
|
|
||||||
#####################conversation#########################
|
#####################conversation#########################
|
||||||
conversationChanged:
|
conversationChanged:
|
||||||
isSendMsg: false
|
isSendMsg: false
|
||||||
|
|||||||
@@ -2,6 +2,16 @@
|
|||||||
|
|
||||||
OpenIM 支持很多种集群化部署方式,包括但不限于 helm, sealos, kubeam, kubesphere, kubeflow, kuboard, kubespray, k3s, k3d, k3c, k3sup, k3v, k3x
|
OpenIM 支持很多种集群化部署方式,包括但不限于 helm, sealos, kubeam, kubesphere, kubeflow, kuboard, kubespray, k3s, k3d, k3c, k3sup, k3v, k3x
|
||||||
|
|
||||||
|
**目前还在开发这个模块,预计 v3.2.0 之前会有一个集群方案。**
|
||||||
|
|
||||||
|
目前各个贡献者,以及之前的官方有出过一些可以参考的方案:
|
||||||
|
|
||||||
|
- https://github.com/OpenIMSDK/k8s-jenkins
|
||||||
|
- https://github.com/OpenIMSDK/Open-IM-Server-k8s-deploy
|
||||||
|
- https://github.com/OpenIMSDK/openim-charts
|
||||||
|
- https://github.com/showurl/deploy-openim
|
||||||
|
|
||||||
|
|
||||||
### 依赖检查
|
### 依赖检查
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
USER=${USER}
|
||||||
|
PASSWORD=${PASSWORD}
|
||||||
|
MINIO_ENDPOINT=${MINIO_ENDPOINT}
|
||||||
|
API_URL=${API_URL}
|
||||||
|
DATA_DIR=${DATA_DIR}
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
# Systemd Configuration, Installation, and Startup
|
||||||
|
|
||||||
|
- [Systemd Configuration, Installation, and Startup](#systemd-configuration-installation-and-startup)
|
||||||
|
- [1. Introduction](#1-introduction)
|
||||||
|
- [2. Prerequisites (Requires root permissions)](#2-prerequisites-requires-root-permissions)
|
||||||
|
- [3. Create `openim-api` systemd unit template file](#3-create-openim-api-systemd-unit-template-file)
|
||||||
|
- [4. Copy systemd unit template file to systemd config directory (Requires root permissions)](#4-copy-systemd-unit-template-file-to-systemd-config-directory-requires-root-permissions)
|
||||||
|
- [5. Start systemd service](#5-start-systemd-service)
|
||||||
|
|
||||||
|
## 1. Introduction
|
||||||
|
|
||||||
|
Systemd is the default service management form for the latest Linux distributions, replacing the original init.
|
||||||
|
|
||||||
|
Format introduction:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
[Unit] : Unit of the service
|
||||||
|
|
||||||
|
Description: Brief description of the service
|
||||||
|
|
||||||
|
[Service]: Configuration of the service's runtime behavior
|
||||||
|
|
||||||
|
ExecStart: Complete path of the program
|
||||||
|
|
||||||
|
Restart: Restart configurations like no, always, on-success, on-failure, on-abnormal, on-abort, on-watchdog
|
||||||
|
|
||||||
|
[Install]: Installation configuration
|
||||||
|
|
||||||
|
WantedBy: Multi-user, etc.
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details, refer to: [Systemd Service Manual](https://www.freedesktop.org/software/systemd/man/systemd.service.html)
|
||||||
|
|
||||||
|
Starting command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl daemon-reload && systemctl enable openim-api && systemctl restart openim-api
|
||||||
|
```
|
||||||
|
|
||||||
|
Service status:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status openim-api
|
||||||
|
```
|
||||||
|
|
||||||
|
Stop command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl stop openim-api
|
||||||
|
```
|
||||||
|
|
||||||
|
More command:
|
||||||
|
```bash
|
||||||
|
# 列出正在运行的Unit,可以直接使用systemctl
|
||||||
|
systemctl list-units
|
||||||
|
|
||||||
|
# 列出所有Unit,包括没有找到配置文件的或者启动失败的
|
||||||
|
systemctl list-units --all
|
||||||
|
|
||||||
|
# 列出所有没有运行的 Unit
|
||||||
|
systemctl list-units --all --state=inactive
|
||||||
|
|
||||||
|
# 列出所有加载失败的 Unit
|
||||||
|
systemctl list-units --failed
|
||||||
|
|
||||||
|
# 列出所有正在运行的、类型为service的Unit
|
||||||
|
systemctl list-units --type=service
|
||||||
|
|
||||||
|
# 显示某个 Unit 是否正在运行
|
||||||
|
systemctl is-active application.service
|
||||||
|
|
||||||
|
# 显示某个 Unit 是否处于启动失败状态
|
||||||
|
systemctl is-failed application.service
|
||||||
|
|
||||||
|
# 显示某个 Unit 服务是否建立了启动链接
|
||||||
|
systemctl is-enabled application.service
|
||||||
|
|
||||||
|
# 立即启动一个服务
|
||||||
|
sudo systemctl start apache.service
|
||||||
|
|
||||||
|
# 立即停止一个服务
|
||||||
|
sudo systemctl stop apache.service
|
||||||
|
|
||||||
|
# 重启一个服务
|
||||||
|
sudo systemctl restart apache.service
|
||||||
|
|
||||||
|
# 重新加载一个服务的配置文件
|
||||||
|
sudo systemctl reload apache.service
|
||||||
|
|
||||||
|
# 重载所有修改过的配置文件
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why choose systemd?**
|
||||||
|
|
||||||
|
**Advanced requirements:**
|
||||||
|
|
||||||
|
- Convenient service runtime log recording for problem analysis
|
||||||
|
- Service management logs
|
||||||
|
- Option to restart upon abnormal exit
|
||||||
|
|
||||||
|
The daemon does not meet these advanced requirements.
|
||||||
|
|
||||||
|
`nohup` only logs the service's runtime outputs and errors.
|
||||||
|
|
||||||
|
Only systemd can fulfill all of the above requirements.
|
||||||
|
|
||||||
|
> The default logs are enhanced with timestamps, usernames, service names, PIDs, etc., making them user-friendly. You can view logs of abnormal service exits. Advanced customization is possible through the configuration files in `/lib/systemd/system/`.
|
||||||
|
|
||||||
|
In short, systemd is the current mainstream way to manage backend services on Linux, so I've abandoned `nohup` in my new versions of bash scripts, opting instead for systemd.
|
||||||
|
|
||||||
|
## 2. Prerequisites (Requires root permissions)
|
||||||
|
|
||||||
|
1. Configure `environment.sh` based on the comments.
|
||||||
|
2. Create a data directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ${OPENIM_DATA_DIR}/{openim-api,openim-crontask}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Create a bin directory and copy `openim-api` and `openim-crontask` executable files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source ./environment.sh
|
||||||
|
mkdir -p ${OPENIM_INSTALL_DIR}/bin
|
||||||
|
cp openim-api openim-crontask ${OPENIM_INSTALL_DIR}/bin
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Copy the configuration files of `openim-api` and `openim-crontask` to the `${OPENIM_CONFIG_DIR}` directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ${OPENIM_CONFIG_DIR}
|
||||||
|
cp openim-api.yaml openim-crontask.yaml ${OPENIM_CONFIG_DIR}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Create `openim-api` systemd unit template file
|
||||||
|
|
||||||
|
For each OpenIM service, we will create a systemd unit template. Follow the steps below for each service:
|
||||||
|
|
||||||
|
Run the following shell script to generate the `openim-api.service.template`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source ./environment.sh
|
||||||
|
cat > openim-api.service.template <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=OpenIM Server API
|
||||||
|
Documentation=https://github.com/marmotedu/iam/blob/master/init/README.md
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=${OPENIM_DATA_DIR}/openim-api
|
||||||
|
ExecStart=${OPENIM_INSTALL_DIR}/bin/openim-api --config=${OPENIM_CONFIG_DIR}/openim-api.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Following the above style, create the respective template files or generate them in bulk:
|
||||||
|
|
||||||
|
First, make sure you've sourced the environment variables:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source ./environment.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the shell script to generate the systemd unit template for each service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
declare -a services=(
|
||||||
|
"openim-api"
|
||||||
|
... [other services]
|
||||||
|
)
|
||||||
|
|
||||||
|
for service in "${services[@]}"
|
||||||
|
do
|
||||||
|
cat > $service.service.template <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=OpenIM Server - $service
|
||||||
|
Documentation=https://github.com/marmotedu/iam/blob/master/init/README.md
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=${OPENIM_DATA_DIR}/$service
|
||||||
|
ExecStart=${OPENIM_INSTALL_DIR}/bin/$service --config=${OPENIM_CONFIG_DIR}/$service.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Copy systemd unit template file to systemd config directory (Requires root permissions)
|
||||||
|
|
||||||
|
Ensure you have root permissions to perform this operation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
for service in "${services[@]}"
|
||||||
|
do
|
||||||
|
sudo cp $service.service.template /etc/systemd/system/$service.service
|
||||||
|
done
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Start systemd service
|
||||||
|
|
||||||
|
To start the OpenIM services:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
for service in "${services[@]}"
|
||||||
|
do
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable $service
|
||||||
|
sudo systemctl restart $service
|
||||||
|
done
|
||||||
|
```
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=OPENIM OPENIM API
|
||||||
|
Documentation=Control interface for the OpenIM API service.
|
||||||
|
Documentation=https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployment/init/README.md
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=${OPENIM_DATA_DIR}/openim-api
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_DATA_DIR}/openim-api
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_LOG_DIR}
|
||||||
|
ExecStart=${OPENIM_INSTALL_DIR}/bin/openim-api --config=${OPENIM_CONFIG_DIR}/openim-api.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=OPENIM OPENIM CMDUTILS
|
||||||
|
Documentation=Utility toolkit for common OpenIM command-line operations.
|
||||||
|
Documentation=https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployment/init/README.md
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=${OPENIM_DATA_DIR}/openim-cmdutils
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_DATA_DIR}/openim-cmdutils
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_LOG_DIR}
|
||||||
|
ExecStart=${OPENIM_INSTALL_DIR}/bin/openim-cmdutils --config=${OPENIM_CONFIG_DIR}/openim-cmdutils.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=OPENIM OPENIM CRONTASK
|
||||||
|
Documentation=Manages the OpenIM CronTask service, with both direct and systemctl installation methods.
|
||||||
|
Documentation=https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployment/init/README.md
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=${OPENIM_DATA_DIR}/openim-crontask
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_DATA_DIR}/openim-crontask
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_LOG_DIR}
|
||||||
|
ExecStart=${OPENIM_INSTALL_DIR}/bin/openim-crontask -c=${OPENIM_CONFIG_DIR}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=OPENIM OPENIM MSGGATEWAY
|
||||||
|
Documentation=https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployment/init/README.md
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=${OPENIM_DATA_DIR}/openim-msggateway
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_DATA_DIR}/openim-msggateway
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_LOG_DIR}
|
||||||
|
ExecStart=${OPENIM_INSTALL_DIR}/bin/openim-msggateway --config=${OPENIM_CONFIG_DIR}/openim-msggateway.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=OPENIM OPENIM MSGTRANSFER
|
||||||
|
Documentation=https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployment/init/README.md
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=${OPENIM_DATA_DIR}/openim-msgtransfer
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_DATA_DIR}/openim-msgtransfer
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_LOG_DIR}
|
||||||
|
ExecStart=${OPENIM_INSTALL_DIR}/bin/openim-msgtransfer --config=${OPENIM_CONFIG_DIR}/openim-msgtransfer.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=OPENIM OPENIM PUSH
|
||||||
|
Documentation=Interface for controlling the OpenIM Push Notification service.
|
||||||
|
Documentation=https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployment/init/README.md
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=${OPENIM_DATA_DIR}/openim-push
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_DATA_DIR}/openim-push
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_LOG_DIR}
|
||||||
|
ExecStart=${OPENIM_INSTALL_DIR}/bin/openim-push --port ${OPENIM_PUSH_PORT} --prometheus_port ${PUSH_PROM_PORT}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=OPENIM OPENIM RPC AUTH
|
||||||
|
Documentation=https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployment/init/README.md
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=${OPENIM_DATA_DIR}/openim-rpc-auth
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_DATA_DIR}/openim-rpc-auth
|
||||||
|
ExecStartPre=/usr/bin/mkdir -p ${OPENIM_LOG_DIR}
|
||||||
|
ExecStart=${OPENIM_INSTALL_DIR}/bin/openim-rpc-auth --config=${OPENIM_CONFIG_DIR}/openim-rpc-auth.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
name: openim-api
|
||||||
|
description: "This is a description for openim-api"
|
||||||
|
type: "service"
|
||||||
@@ -0,0 +1,387 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
# TODO: This config file is the template file
|
||||||
|
# --| source: deployments/templates/openim.yaml
|
||||||
|
# --| env: scripts/install/environment
|
||||||
|
# --| target: config/config.yaml
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
|
||||||
|
###################### Zookeeper ######################
|
||||||
|
# Zookeeper configuration
|
||||||
|
# It's not recommended to modify the schema
|
||||||
|
#
|
||||||
|
# Zookeeper address
|
||||||
|
# Zookeeper username
|
||||||
|
# Zookeeper password
|
||||||
|
zookeeper:
|
||||||
|
schema: ${ZOOKEEPER_SCHEMA}
|
||||||
|
address: [ ${ZOOKEEPER_ADDRESS}:${ZOOKEEPER_PORT} ]
|
||||||
|
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
|
||||||
|
#
|
||||||
|
# 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}
|
||||||
|
password: ${MONGO_PASSWORD}
|
||||||
|
maxPoolSize: ${MONGO_MAX_POOL_SIZE}
|
||||||
|
|
||||||
|
###################### Redis configuration information ######################
|
||||||
|
# Redis configuration
|
||||||
|
#
|
||||||
|
# Username is required only for Redis version 6.0+
|
||||||
|
redis:
|
||||||
|
address: [ ${REDIS_ADDRESS}:${REDIS_PORT} ]
|
||||||
|
username: ${REDIS_USERNAME}
|
||||||
|
password: ${REDIS_PASSWORD}
|
||||||
|
|
||||||
|
###################### Kafka configuration information ######################
|
||||||
|
# Kafka configuration
|
||||||
|
#
|
||||||
|
# Kafka username
|
||||||
|
# Kafka password
|
||||||
|
# It's not recommended to modify this topic name
|
||||||
|
# Consumer group ID, it's not recommended to modify
|
||||||
|
kafka:
|
||||||
|
username: ${KAFKA_USERNAME}
|
||||||
|
password: ${KAFKA_PASSWORD}
|
||||||
|
addr: [ ${KAFKA_ADDR}:${KAFKA_PORT} ]
|
||||||
|
latestMsgToRedis:
|
||||||
|
topic: "${KAFKA_LATESTMSG_REDIS_TOPIC}"
|
||||||
|
offlineMsgToMongo:
|
||||||
|
topic: "${KAFKA_OFFLINEMSG_MONGO_TOPIC}"
|
||||||
|
msgToPush:
|
||||||
|
topic: "${KAFKA_MSG_PUSH_TOPIC}"
|
||||||
|
consumerGroupID:
|
||||||
|
msgToRedis: ${KAFKA_CONSUMERGROUPID_REDIS}
|
||||||
|
msgToMongo: ${KAFKA_CONSUMERGROUPID_MONGO}
|
||||||
|
msgToMySql: ${KAFKA_CONSUMERGROUPID_MYSQL}
|
||||||
|
msgToPush: ${KAFKA_CONSUMERGROUPID_PUSH}
|
||||||
|
|
||||||
|
###################### RPC configuration information ######################
|
||||||
|
# RPC configuration
|
||||||
|
#
|
||||||
|
# IP address to register with zookeeper when starting RPC, the IP and corresponding rpcPort should be accessible by api/gateway
|
||||||
|
# Default listen IP is 0.0.0.0
|
||||||
|
rpc:
|
||||||
|
registerIP: ${RPC_REGISTER_IP}
|
||||||
|
listenIP: ${RPC_LISTEN_IP}
|
||||||
|
|
||||||
|
###################### API configuration information ######################
|
||||||
|
# API configuration
|
||||||
|
#
|
||||||
|
# API service port
|
||||||
|
# Default listen IP is 0.0.0.0
|
||||||
|
api:
|
||||||
|
openImApiPort: [ ${API_OPENIM_PORT} ]
|
||||||
|
listenIP: ${API_LISTEN_IP}
|
||||||
|
|
||||||
|
###################### Object configuration information ######################
|
||||||
|
# Object storage configuration
|
||||||
|
#
|
||||||
|
# Use minio for object storage
|
||||||
|
# API URL should be accessible by the app
|
||||||
|
# It's not recommended to modify the bucket name
|
||||||
|
# Endpoint should be accessible by the app
|
||||||
|
# Session token
|
||||||
|
# Configuration for Tencent COS
|
||||||
|
# Configuration for Aliyun OSS
|
||||||
|
# apiURL is the address of the api, the access address of the app, use s3 must be configured
|
||||||
|
# minio.endpoint can be configured as an intranet address,
|
||||||
|
# minio.signEndpoint is minio public network address
|
||||||
|
object:
|
||||||
|
enable: "${OBJECT_ENABLE}"
|
||||||
|
apiURL: "${OBJECT_APIURL}"
|
||||||
|
minio:
|
||||||
|
bucket: "${MINIO_BUCKET}"
|
||||||
|
endpoint: "${MINIO_ENDPOINT}"
|
||||||
|
accessKeyID: "${MINIO_ACCESS_KEY}"
|
||||||
|
secretAccessKey: "${MINIO_SECRET_KEY}"
|
||||||
|
sessionToken: ${MINIO_SESSION_TOKEN}
|
||||||
|
signEndpoint: "${MINIO_SIGN_ENDPOINT}"
|
||||||
|
cos:
|
||||||
|
bucketURL: ${COS_BUCKET_URL}
|
||||||
|
secretID: ${COS_SECRET_ID}
|
||||||
|
secretKey: ${COS_SECRET_KEY}
|
||||||
|
sessionToken: ${COS_SESSION_TOKEN}
|
||||||
|
oss:
|
||||||
|
endpoint: "${OSS_ENDPOINT}"
|
||||||
|
bucket: "${OSS_BUCKET}"
|
||||||
|
bucketURL: "${OSS_BUCKET_URL}"
|
||||||
|
accessKeyID: ${OSS_ACCESS_KEY_ID}
|
||||||
|
accessKeySecret: ${OSS_ACCESS_KEY_SECRET}
|
||||||
|
sessionToken: ${OSS_SESSION_TOKEN}
|
||||||
|
|
||||||
|
|
||||||
|
###################### 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:
|
||||||
|
openImUserPort: [ ${OPENIM_USER_PORT} ]
|
||||||
|
openImFriendPort: [ ${OPENIM_FRIEND_PORT} ]
|
||||||
|
openImMessagePort: [ ${OPENIM_MESSAGE_PORT} ]
|
||||||
|
openImMessageGatewayPort: [ ${OPENIM_MESSAGE_GATEWAY_PORT} ]
|
||||||
|
openImGroupPort: [ ${OPENIM_GROUP_PORT} ]
|
||||||
|
openImAuthPort: [ ${OPENIM_AUTH_PORT} ]
|
||||||
|
openImPushPort: [ ${OPENIM_PUSH_PORT} ]
|
||||||
|
openImConversationPort: [ ${OPENIM_CONVERSATION_PORT} ]
|
||||||
|
openImThirdPort: [ ${OPENIM_THIRD_PORT} ]
|
||||||
|
|
||||||
|
###################### RPC Register Name Configuration ######################
|
||||||
|
# RPC service names for registration, it's not recommended to modify these
|
||||||
|
rpcRegisterName:
|
||||||
|
openImUserName: ${OPENIM_USER_NAME}
|
||||||
|
openImFriendName: ${OPENIM_FRIEND_NAME}
|
||||||
|
openImMsgName: ${OPENIM_MSG_NAME}
|
||||||
|
openImPushName: ${OPENIM_PUSH_NAME}
|
||||||
|
openImMessageGatewayName: ${OPENIM_MESSAGE_GATEWAY_NAME}
|
||||||
|
openImGroupName: ${OPENIM_GROUP_NAME}
|
||||||
|
openImAuthName: ${OPENIM_AUTH_NAME}
|
||||||
|
openImConversationName: ${OPENIM_CONVERSATION_NAME}
|
||||||
|
openImThirdName: ${OPENIM_THIRD_NAME}
|
||||||
|
|
||||||
|
###################### Log Configuration ######################
|
||||||
|
# Log configuration
|
||||||
|
#
|
||||||
|
# Storage directory
|
||||||
|
# Log rotation time
|
||||||
|
# Maximum number of logs to retain
|
||||||
|
# Log level, 6 means all levels
|
||||||
|
# Whether to output to stdout
|
||||||
|
# Whether to output in json format
|
||||||
|
# Whether to include stack trace in logs
|
||||||
|
log:
|
||||||
|
storageLocation: ${LOG_STORAGE_LOCATION}
|
||||||
|
rotationTime: ${LOG_ROTATION_TIME}
|
||||||
|
remainRotationCount: ${LOG_REMAIN_ROTATION_COUNT}
|
||||||
|
remainLogLevel: ${LOG_REMAIN_LOG_LEVEL}
|
||||||
|
isStdout: ${LOG_IS_STDOUT}
|
||||||
|
isJson: ${LOG_IS_JSON}
|
||||||
|
withStack: ${LOG_WITH_STACK}
|
||||||
|
|
||||||
|
###################### Variables definition ######################
|
||||||
|
# Long connection server configuration
|
||||||
|
#
|
||||||
|
# Websocket port for msg_gateway
|
||||||
|
# Maximum number of websocket connections
|
||||||
|
# Maximum length of websocket request package
|
||||||
|
# Websocket connection handshake timeout
|
||||||
|
longConnSvr:
|
||||||
|
openImWsPort: [ ${OPENIM_WS_PORT} ]
|
||||||
|
websocketMaxConnNum: ${WEBSOCKET_MAX_CONN_NUM}
|
||||||
|
websocketMaxMsgLen: ${WEBSOCKET_MAX_MSG_LEN}
|
||||||
|
websocketTimeout: ${WEBSOCKET_TIMEOUT}
|
||||||
|
|
||||||
|
# Push notification service configuration
|
||||||
|
#
|
||||||
|
# Use GeTui for push notifications
|
||||||
|
# GeTui offline push configuration
|
||||||
|
# FCM offline push configuration
|
||||||
|
# Account file, place it in the config directory
|
||||||
|
# JPush configuration, modify these after applying in JPush backend
|
||||||
|
push:
|
||||||
|
enable: ${PUSH_ENABLE}
|
||||||
|
geTui:
|
||||||
|
pushUrl: "${GETUI_PUSH_URL}"
|
||||||
|
masterSecret: ""
|
||||||
|
appKey: ""
|
||||||
|
intent: ""
|
||||||
|
channelID: ""
|
||||||
|
channelName: ""
|
||||||
|
fcm:
|
||||||
|
serviceAccount: "${FCM_SERVICE_ACCOUNT}"
|
||||||
|
jpns:
|
||||||
|
appKey:
|
||||||
|
masterSecret:
|
||||||
|
pushUrl:
|
||||||
|
pushIntent:
|
||||||
|
|
||||||
|
# App manager configuration
|
||||||
|
#
|
||||||
|
# Built-in app manager user IDs
|
||||||
|
# Built-in app manager nicknames
|
||||||
|
manager:
|
||||||
|
userID: [ "${MANAGER_USERID_1}", "${MANAGER_USERID_2}", "${MANAGER_USERID_3}" ]
|
||||||
|
nickname: [ "${NICKNAME_1}", "${NICKNAME_2}", "${NICKNAME_3}" ]
|
||||||
|
|
||||||
|
# Multi-platform login policy
|
||||||
|
# For each platform(Android, iOS, Windows, Mac, web), only one can be online at a time
|
||||||
|
multiLoginPolicy: ${MULTILOGIN_POLICY}
|
||||||
|
|
||||||
|
# Whether to store messages in MySQL, messages in MySQL are only used for management background
|
||||||
|
chatPersistenceMysql: ${CHAT_PERSISTENCE_MYSQL}
|
||||||
|
|
||||||
|
# Message cache timeout in seconds, it's not recommended to modify
|
||||||
|
msgCacheTimeout: ${MSG_CACHE_TIMEOUT}
|
||||||
|
|
||||||
|
# Whether to enable read receipts for group chat
|
||||||
|
groupMessageHasReadReceiptEnable: ${GROUP_MSG_READ_RECEIPT}
|
||||||
|
|
||||||
|
# Whether to enable read receipts for single chat
|
||||||
|
singleMessageHasReadReceiptEnable: ${SINGLE_MSG_READ_RECEIPT}
|
||||||
|
|
||||||
|
# MongoDB offline message retention period in days
|
||||||
|
retainChatRecords: ${RETAIN_CHAT_RECORDS}
|
||||||
|
|
||||||
|
# Schedule to clear expired messages(older than retainChatRecords days) in MongoDB every Wednesday at 2am
|
||||||
|
# This deletion is just for cleaning up disk usage according to previous configuration retainChatRecords, no notification will be sent
|
||||||
|
chatRecordsClearTime: "${CHAT_RECORDS_CLEAR_TIME}"
|
||||||
|
|
||||||
|
# Schedule to auto delete messages every day at 2am
|
||||||
|
# This deletion is for messages that have been retained for more than msg_destruct_time (seconds) in the conversation field
|
||||||
|
msgDestructTime: "${MSG_DESTRUCT_TIME}"
|
||||||
|
|
||||||
|
# Secret key
|
||||||
|
secret: ${SECRET}
|
||||||
|
|
||||||
|
# Token policy
|
||||||
|
#
|
||||||
|
# Token expiration period in days
|
||||||
|
tokenPolicy:
|
||||||
|
expire: ${TOKEN_EXPIRE}
|
||||||
|
|
||||||
|
# Message verification policy
|
||||||
|
#
|
||||||
|
# Whether to verify friendship when sending messages
|
||||||
|
messageVerify:
|
||||||
|
friendVerify: false
|
||||||
|
|
||||||
|
# iOS push notification configuration
|
||||||
|
#
|
||||||
|
# iOS push notification sound
|
||||||
|
# Whether to count badge
|
||||||
|
# Whether it's production environment
|
||||||
|
iosPush:
|
||||||
|
pushSound: "xxx"
|
||||||
|
badgeCount: true
|
||||||
|
production: false
|
||||||
|
|
||||||
|
###################### Third-party service configuration ######################
|
||||||
|
# Callback configuration
|
||||||
|
#
|
||||||
|
# Callback URL
|
||||||
|
# Whether to enable this callback event
|
||||||
|
# Timeout in seconds
|
||||||
|
# Whether to continue execution if callback fails
|
||||||
|
callback:
|
||||||
|
url:
|
||||||
|
beforeSendSingleMsg:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
afterSendSingleMsg:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
beforeSendGroupMsg:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
afterSendGroupMsg:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
msgModify:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
userOnline:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
userOffline:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
userKickOff:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
offlinePush:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
onlinePush:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
superGroupOnlinePush:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
beforeAddFriend:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
beforeCreateGroup:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
beforeMemberJoinGroup:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
beforeSetGroupMemberInfo:
|
||||||
|
enable: false
|
||||||
|
timeout: 5
|
||||||
|
failedContinue: true
|
||||||
|
setMessageReactionExtensions:
|
||||||
|
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: ${PROMETHEUS_ENABLE}
|
||||||
|
userPrometheusPort: [ ${USER_PROM_PORT} ]
|
||||||
|
friendPrometheusPort: [ ${FRIEND_PROM_PORT} ]
|
||||||
|
messagePrometheusPort: [ ${MESSAGE_PROM_PORT} ]
|
||||||
|
messageGatewayPrometheusPort: [ ${MSG_GATEWAY_PROM_PORT} ]
|
||||||
|
groupPrometheusPort: [ ${GROUP_PROM_PORT} ]
|
||||||
|
authPrometheusPort: [ ${AUTH_PROM_PORT} ]
|
||||||
|
pushPrometheusPort: [ ${PUSH_PROM_PORT} ]
|
||||||
|
conversationPrometheusPort: [ ${CONVERSATION_PROM_PORT} ]
|
||||||
|
rtcPrometheusPort: [ ${RTC_PROM_PORT} ]
|
||||||
|
thirdPrometheusPort: [ ${THIRD_PROM_PORT} ]
|
||||||
|
messageTransferPrometheusPort: [ ${MSG_TRANSFER_PROM_PORT} ] # List of ports
|
||||||
+49
-30
@@ -52,7 +52,6 @@ services:
|
|||||||
net.core.somaxconn: 1024
|
net.core.somaxconn: 1024
|
||||||
command: redis-server --requirepass ${PASSWORD} --appendonly yes
|
command: redis-server --requirepass ${PASSWORD} --appendonly yes
|
||||||
|
|
||||||
|
|
||||||
zookeeper:
|
zookeeper:
|
||||||
image: wurstmeister/zookeeper
|
image: wurstmeister/zookeeper
|
||||||
ports:
|
ports:
|
||||||
@@ -63,7 +62,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
restart: always
|
restart: always
|
||||||
|
network_mode: "host"
|
||||||
|
|
||||||
kafka:
|
kafka:
|
||||||
image: wurstmeister/kafka
|
image: wurstmeister/kafka
|
||||||
@@ -74,7 +73,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
KAFKA_BROKER_ID: 0
|
KAFKA_BROKER_ID: 0
|
||||||
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
KAFKA_ZOOKEEPER_CONNECT: 127.0.0.1:2181
|
||||||
KAFKA_CREATE_TOPICS: "latestMsgToRedis:8:1,msgToPush:8:1,offlineMsgToMongoMysql:8:1"
|
KAFKA_CREATE_TOPICS: "latestMsgToRedis:8:1,msgToPush:8:1,offlineMsgToMongoMysql:8:1"
|
||||||
KAFKA_ADVERTISED_LISTENERS: INSIDE://127.0.0.1:9092,OUTSIDE://103.116.45.174:9092
|
KAFKA_ADVERTISED_LISTENERS: INSIDE://127.0.0.1:9092,OUTSIDE://103.116.45.174:9092
|
||||||
KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9093
|
KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9093
|
||||||
@@ -82,6 +81,7 @@ services:
|
|||||||
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
|
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
|
||||||
depends_on:
|
depends_on:
|
||||||
- zookeeper
|
- zookeeper
|
||||||
|
network_mode: "host"
|
||||||
|
|
||||||
minio:
|
minio:
|
||||||
image: minio/minio
|
image: minio/minio
|
||||||
@@ -98,14 +98,20 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
command: minio server /data --console-address ':9090'
|
command: minio server /data --console-address ':9090'
|
||||||
|
|
||||||
|
openim-server:
|
||||||
openim_server:
|
# image: ghcr.io/openimsdk/openim-server:release-v3.2
|
||||||
image: ghcr.io/openim-sigs/openim-server:v1.0.0-debug.11 #ghcr.io/openimsdk/openim-server:main
|
image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server:release-v3.2
|
||||||
|
# image: openim/openim-server:release-v3.2
|
||||||
container_name: openim-server
|
container_name: openim-server
|
||||||
|
# healthcheck:
|
||||||
|
# test: ["CMD-SHELL", "./scripts/check-all.sh"]
|
||||||
|
# interval: 30s
|
||||||
|
# timeout: 10s
|
||||||
|
# retries: 5
|
||||||
volumes:
|
volumes:
|
||||||
- ./logs:/openim/openim-server/logs
|
- ${DATA_DIR}/_output/openim/logs:/openim/openim-server/logs
|
||||||
- ./config:/openim/openim-server/config
|
- ${DATA_DIR}/config:/openim/openim-server/config
|
||||||
- ./scripts:/openim/openim-server/scripts
|
- ${DATA_DIR}/scripts:/openim/openim-server/scripts
|
||||||
restart: always
|
restart: always
|
||||||
depends_on:
|
depends_on:
|
||||||
- zookeeper
|
- zookeeper
|
||||||
@@ -121,26 +127,34 @@ services:
|
|||||||
max-size: "1g"
|
max-size: "1g"
|
||||||
max-file: "2"
|
max-file: "2"
|
||||||
|
|
||||||
openim-chat:
|
# openim-chat:
|
||||||
image: ghcr.io/openim-sigs/openim-chat:v1.0.0-debug.11 # ghcr.io/openimsdk/openim-chat:main
|
# # image: ghcr.io/openimsdk/openim-server:release-v1.2
|
||||||
container_name: openim-chat
|
# image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server:release-v1.2
|
||||||
volumes:
|
# # image: openim/openim-server:release-v1.2
|
||||||
- ./_output/openim/openim-chat/logs:/openim/openim-chat/logs
|
# container_name: openim-chat
|
||||||
- ./_output/openim/openim-chat/config:/openim/openim-chat/config
|
# # healthcheck:
|
||||||
- ./_output/openim/openim-chat/scripts:/openim/openim-chat/scripts
|
# # test: ["CMD-SHELL", "./scripts/check-all.sh"]
|
||||||
restart: always
|
# # interval: 30s
|
||||||
depends_on:
|
# # timeout: 10s
|
||||||
- mysql
|
# # retries: 5
|
||||||
- mongodb
|
# volumes:
|
||||||
- redis
|
# - openim-chat_logs:/openim/openim-chat/logs
|
||||||
- minio
|
# - openim-chat_config:/openim/openim-chat/config
|
||||||
- openim_server
|
# - openim-chat_scripts:/openim/openim-chat/scripts
|
||||||
network_mode: "host"
|
# restart: always
|
||||||
logging:
|
# user: root:root
|
||||||
driver: json-file
|
# depends_on:
|
||||||
options:
|
# - mysql
|
||||||
max-size: "1g"
|
# - mongodb
|
||||||
max-file: "2"
|
# - redis
|
||||||
|
# - minio
|
||||||
|
# - openim-server
|
||||||
|
# network_mode: "host"
|
||||||
|
# logging:
|
||||||
|
# driver: json-file
|
||||||
|
# options:
|
||||||
|
# max-size: "1g"
|
||||||
|
# max-file: "2"
|
||||||
|
|
||||||
prometheus:
|
prometheus:
|
||||||
image: prom/prometheus
|
image: prom/prometheus
|
||||||
@@ -150,7 +164,7 @@ services:
|
|||||||
# ports:
|
# ports:
|
||||||
# - 9091:9091
|
# - 9091:9091
|
||||||
depends_on:
|
depends_on:
|
||||||
- openim_server
|
- openim-server
|
||||||
command: --web.listen-address=:9091 --config.file="/etc/prometheus/prometheus.yml"
|
command: --web.listen-address=:9091 --config.file="/etc/prometheus/prometheus.yml"
|
||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
@@ -165,6 +179,11 @@ services:
|
|||||||
- prometheus
|
- prometheus
|
||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
openim-chat_logs:
|
||||||
|
openim-chat_config:
|
||||||
|
openim-chat_scripts:
|
||||||
|
|
||||||
# node-exporter:
|
# node-exporter:
|
||||||
# image: quay.io/prometheus/node-exporter
|
# image: quay.io/prometheus/node-exporter
|
||||||
# container_name: node-exporter
|
# container_name: node-exporter
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
docs/.generated_docs
|
docs/.generated_docs
|
||||||
docs/guide/en-US/cmd/iam-apiserver.md
|
|
||||||
docs/guide/en-US/cmd/iam-authz-server.md
|
|
||||||
docs/guide/en-US/cmd/iam-pump.md
|
|
||||||
docs/guide/en-US/cmd/iam-watcher.md
|
|
||||||
docs/guide/en-US/cmd/openim/openim.md
|
docs/guide/en-US/cmd/openim/openim.md
|
||||||
docs/guide/en-US/cmd/openim/openim_color.md
|
docs/guide/en-US/cmd/openim/openim_color.md
|
||||||
docs/guide/en-US/cmd/openim/openim_completion.md
|
docs/guide/en-US/cmd/openim/openim_completion.md
|
||||||
@@ -47,10 +44,6 @@ docs/guide/en-US/yaml/openim/openim_set.yaml
|
|||||||
docs/guide/en-US/yaml/openim/openim-rpc-user.yaml
|
docs/guide/en-US/yaml/openim/openim-rpc-user.yaml
|
||||||
docs/guide/en-US/yaml/openim/openim_validate.yaml
|
docs/guide/en-US/yaml/openim/openim_validate.yaml
|
||||||
docs/guide/en-US/yaml/openim/openim_version.yaml
|
docs/guide/en-US/yaml/openim/openim_version.yaml
|
||||||
docs/man/man1/iam-apiserver.1
|
|
||||||
docs/man/man1/iam-authz-server.1
|
|
||||||
docs/man/man1/iam-pump.1
|
|
||||||
docs/man/man1/iam-watcher.1
|
|
||||||
docs/man/man1/openim-color.1
|
docs/man/man1/openim-color.1
|
||||||
docs/man/man1/openim-completion.1
|
docs/man/man1/openim-completion.1
|
||||||
docs/man/man1/openim-info.1
|
docs/man/man1/openim-info.1
|
||||||
|
|||||||
+3
-4
@@ -64,12 +64,11 @@ cmd/*
|
|||||||
# config directory
|
# config directory
|
||||||
config/* @skiffer-git
|
config/* @skiffer-git
|
||||||
|
|
||||||
# db directory
|
|
||||||
db/sdk @cubxxw @FGadvancer
|
|
||||||
|
|
||||||
# internal directory
|
# internal directory
|
||||||
internal/ @openimsdk/openim @skiffer-git @FGadvancer
|
internal/ @openimsdk/openim @skiffer-git @FGadvancer
|
||||||
|
|
||||||
|
tools @openimsdk/openim @openimsdk/bot @cubxxw @skiffer-git @FGadvancer
|
||||||
|
|
||||||
# logs directory
|
# logs directory
|
||||||
logs/* @skiffer-git @FGadvancer
|
logs/* @skiffer-git @FGadvancer
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ logs/* @skiffer-git @FGadvancer
|
|||||||
pkg/a2r @openimsdk/openim @skiffer-git @cubxxw @openimsdk/bot
|
pkg/a2r @openimsdk/openim @skiffer-git @cubxxw @openimsdk/bot
|
||||||
|
|
||||||
# scripts directory
|
# scripts directory
|
||||||
scripts/LICENSE/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
scripts/template/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
||||||
scripts/enterprise/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
scripts/enterprise/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
||||||
scripts/githooks/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
scripts/githooks/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
||||||
scripts/lib/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
scripts/lib/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
||||||
|
|||||||
@@ -0,0 +1,177 @@
|
|||||||
|
# Git Cherry-Pick Guide
|
||||||
|
|
||||||
|
- Git Cherry-Pick Guide
|
||||||
|
- [Introduction](#introduction)
|
||||||
|
- [What is git cherry-pick?](#what-is-git-cherry-pick)
|
||||||
|
- [Using git cherry-pick](#using-git-cherry-pick)
|
||||||
|
- [Applying Multiple Commits](#applying-multiple-commits)
|
||||||
|
- [Configurations](#configurations)
|
||||||
|
- [Handling Conflicts](#handling-conflicts)
|
||||||
|
- [Applying Commits from Another Repository](#applying-commits-from-another-repository)
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
Author: @cubxxw
|
||||||
|
|
||||||
|
As OpenIM has progressively embarked on a standardized path, I've had the honor of initiating a significant project, `git cherry-pick`. While some may see it as merely a naming convention in the Go language, it represents more. It's a thoughtful design within the OpenIM project, my very first conscious design, and a first in laying out an extensive collaboration process and copyright management with goals of establishing a top-tier community standard.
|
||||||
|
|
||||||
|
## What is git cherry-pick?
|
||||||
|
|
||||||
|
In multi-branch repositories, transferring commits from one branch to another is common. You can either merge all changes from one branch (using `git merge`) or selectively apply certain commits. This selective application of commits is where `git cherry-pick` comes into play.
|
||||||
|
|
||||||
|
Our collaboration strategy with GitHub necessitates maintenance of multiple `release-v*` branches alongside the `main` branch. To manage this, we mainly develop on the `main` branch and selectively merge into `release-v*` branches. This ensures the `main` branch stays current while the `release-v*` branches remain stable.
|
||||||
|
|
||||||
|
Ensuring this strategy's success extends beyond just documentation; it hinges on well-engineered solutions and automation tools, like Makefile, powerful CI/CD processes, and even Prow.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- [Contributor License Agreement](https://github.com/openim-sigs/cla) is considered implicit for all code within cherry pick pull requests, **unless there is a large conflict**.
|
||||||
|
- A pull request merged against the `main` branch.
|
||||||
|
- The release branch exists (example: [`release-1.18`](https://github.com/OpenIMSDK/Open-IM-Server/tree/release-v3.1))
|
||||||
|
- The normal git and GitHub configured shell environment for pushing to your openim-server `origin` fork on GitHub and making a pull request against a configured remote `upstream` that tracks `https://github.com/OpenIMSDK/Open-IM-Server.git`, including `GITHUB_USER`.
|
||||||
|
- Have GitHub CLI (`gh`) installed following [installation instructions](https://github.com/cli/cli#installation).
|
||||||
|
- A github personal access token which has permissions "repo" and "read:org". Permissions are required for [gh auth login](https://cli.github.com/manual/gh_auth_login) and not used for anything unrelated to cherry-pick creation process (creating a branch and initiating PR).
|
||||||
|
|
||||||
|
## What Kind of PRs are Good for Cherry Picks
|
||||||
|
|
||||||
|
Compared to the normal main branch's merge volume across time, the release branches see one or two orders of magnitude less PRs. This is because there is an order or two of magnitude higher scrutiny. Again, the emphasis is on critical bug fixes, e.g.,
|
||||||
|
|
||||||
|
- Loss of data
|
||||||
|
- Memory corruption
|
||||||
|
- Panic, crash, hang
|
||||||
|
- Security
|
||||||
|
|
||||||
|
A bugfix for a functional issue (not a data loss or security issue) that only affects an alpha feature does not qualify as a critical bug fix.
|
||||||
|
|
||||||
|
If you are proposing a cherry pick and it is not a clear and obvious critical bug fix, please reconsider. If upon reflection you wish to continue, bolster your case by supplementing your PR with e.g.,
|
||||||
|
|
||||||
|
- A GitHub issue detailing the problem
|
||||||
|
- Scope of the change
|
||||||
|
- Risks of adding a change
|
||||||
|
- Risks of associated regression
|
||||||
|
- Testing performed, test cases added
|
||||||
|
- Key stakeholder SIG reviewers/approvers attesting to their confidence in the change being a required backport
|
||||||
|
|
||||||
|
If the change is in cloud provider-specific platform code (which is in the process of being moved out of core openim-server), describe the customer impact, how the issue escaped initial testing, remediation taken to prevent similar future escapes, and why the change cannot be carried in your downstream fork of the openim-server project branches.
|
||||||
|
|
||||||
|
It is critical that our full community is actively engaged on enhancements in the project. If a released feature was not enabled on a particular provider's platform, this is a community miss that needs to be resolved in the `main` branch for subsequent releases. Such enabling will not be backported to the patch release branches.
|
||||||
|
|
||||||
|
## Initiate a Cherry Pick
|
||||||
|
|
||||||
|
### Before you begin
|
||||||
|
|
||||||
|
- Plan to initiate a cherry-pick against *every* supported release branch. If you decide to skip some release branch, explain your decision in a comment to the PR being cherry-picked.
|
||||||
|
- Initiate cherry-picks in order, from newest to oldest supported release branches. For example, if 3.1 is the newest supported release branch, then, before cherry-picking to 2.25, make sure the cherry-pick PR already exists for in 2.26 and 3.1. This helps to prevent regressions as a result of an upgrade to the next release.
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
|
||||||
|
- Run the [cherry pick script](https://github.com/OpenIMSDK/Open-IM-Server/tree/main/scripts/cherry-pick.sh)
|
||||||
|
|
||||||
|
This example applies a main branch PR #98765 to the remote branch `upstream/release-v3.1`:
|
||||||
|
|
||||||
|
```
|
||||||
|
scripts/cherry-pick.sh upstream/release-v3.1 98765
|
||||||
|
```
|
||||||
|
|
||||||
|
- Be aware the cherry pick script assumes you have a git remote called `upstream` that points at the openim-server github org.
|
||||||
|
|
||||||
|
Please see our [recommended Git workflow](https://github.com/openim-server/community/blob/main/contributors/guide/github-workflow.md#workflow).
|
||||||
|
|
||||||
|
- You will need to run the cherry pick script separately for each patch release you want to cherry pick to. Cherry picks should be applied to all [active](https://github.com/openim-server/website/blob/main/content/en/releases/patch-releases.md#detailed-release-history-for-active-branches) release branches where the fix is applicable.
|
||||||
|
|
||||||
|
- If `GITHUB_TOKEN` is not set you will be asked for your github password: provide the github [personal access token](https://github.com/settings/tokens) rather than your actual github password. If you can securely set the environment variable `GITHUB_TOKEN` to your personal access token then you can avoid an interactive prompt. Refer [mislav/hub#2655 (comment)](https://github.com/mislav/hub/issues/2655#issuecomment-735836048)
|
||||||
|
|
||||||
|
- Your cherry pick PR will immediately get the `do-not-merge/cherry-pick-not-approved` label.
|
||||||
|
|
||||||
|
[Normal rules apply for code merge](https://github.com/openim-server/community/blob/main/contributors/devel/sig-release/release.md#tldr), with some additional caveats outlined in the next section of this document.
|
||||||
|
|
||||||
|
## Cherry Pick Review
|
||||||
|
|
||||||
|
As with any other PR, code OWNERS review (`/lgtm`) and approve (`/approve`) on cherry pick PRs as they deem appropriate.
|
||||||
|
|
||||||
|
The same release note requirements apply as normal pull requests, except the release note stanza will auto-populate from the main branch pull request from which the cherry pick originated.
|
||||||
|
|
||||||
|
|
||||||
|
## Using git cherry-pick
|
||||||
|
|
||||||
|
`git cherry-pick` applies specified commits from one branch to another.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git cherry-pick <commitHash>
|
||||||
|
```
|
||||||
|
|
||||||
|
As an example, consider a repository with `main` and `release-v3.1` branches. To apply commit `f` from the `release-v3.1` branch to the `main` branch:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Switch to main branch
|
||||||
|
$ git checkout main
|
||||||
|
|
||||||
|
# Perform cherry-pick
|
||||||
|
$ git cherry-pick f
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use a branch name instead of a commit hash to cherry-pick the latest commit from that branch.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git cherry-pick release-v3.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Applying Multiple Commits
|
||||||
|
|
||||||
|
To apply multiple commits simultaneously:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git cherry-pick <HashA> <HashB>
|
||||||
|
```
|
||||||
|
|
||||||
|
To apply a range of consecutive commits:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git cherry-pick <HashA>..<HashB>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configurations
|
||||||
|
|
||||||
|
Here are some commonly used configurations for `git cherry-pick`:
|
||||||
|
|
||||||
|
- **`-e`, `--edit`**: Open an external editor to modify the commit message.
|
||||||
|
- **`-n`, `--no-commit`**: Update the working directory and staging area without creating a new commit.
|
||||||
|
- **`-x`**: Append a reference in the commit message for tracking the source of the cherry-picked commit.
|
||||||
|
- **`-s`, `--signoff`**: Add a sign-off message at the end of the commit indicating who performed the cherry-pick.
|
||||||
|
- **`-m parent-number`, `--mainline parent-number`**: When the original commit is a merge of two branches, specify which parent branch's changes should be used.
|
||||||
|
|
||||||
|
## Handling Conflicts
|
||||||
|
|
||||||
|
If conflicts arise during the cherry-pick:
|
||||||
|
|
||||||
|
- **`--continue`**: After resolving conflicts, stage the changes with `git add .` and then continue the cherry-pick process.
|
||||||
|
- **`--abort`**: Abandon the cherry-pick and revert to the previous state.
|
||||||
|
- **`--quit`**: Exit the cherry-pick without reverting to the previous state.
|
||||||
|
|
||||||
|
## Applying Commits from Another Repository
|
||||||
|
|
||||||
|
You can also cherry-pick commits from another repository:
|
||||||
|
|
||||||
|
1. Add the external repository as a remote:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git remote add target git://gitUrl
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Fetch the commits from the remote:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git fetch target
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Identify the commit hash you wish to cherry-pick:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git log target/main
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Perform the cherry-pick:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git cherry-pick <commitHash>
|
||||||
|
```
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
# Init OpenIM Config
|
||||||
|
|
||||||
|
- [Init OpenIM Config](#init-openim-config)
|
||||||
|
- [Start](#start)
|
||||||
|
- [Define Automated Configuration](#define-automated-configuration)
|
||||||
|
- [Define Configuration Variables](#define-configuration-variables)
|
||||||
|
- [Bash Parsing Features](#bash-parsing-features)
|
||||||
|
- [Reasons and Advantages of the Design](#reasons-and-advantages-of-the-design)
|
||||||
|
|
||||||
|
|
||||||
|
## Start
|
||||||
|
|
||||||
|
With the increasing complexity of software engineering, effective configuration management has become more and more important. Yaml and other configuration files provide the necessary parameters and guidance for systems, but they also impose additional management overhead for developers. This article explores how to automate and optimize configuration management, thereby improving efficiency and reducing the chances of errors.
|
||||||
|
|
||||||
|
First, obtain the OpenIM code through the contributor documentation and initialize it following the steps below.
|
||||||
|
|
||||||
|
## Define Automated Configuration
|
||||||
|
|
||||||
|
We no longer strongly recommend modifying the same configuration file. If you have a new configuration file related to your business, we suggest generating and managing it through automation.
|
||||||
|
|
||||||
|
In the `scripts/init_config.sh` file, we defined some template files. These templates will be automatically generated to the corresponding directories when executing `make init`.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Defines an associative array where the keys are the template files and the values are the corresponding output files.
|
||||||
|
declare -A TEMPLATES=(
|
||||||
|
["${OPENIM_ROOT}/scripts/template/config-tmpl/env.template"]="${OPENIM_OUTPUT_SUBPATH}/bin/.env"
|
||||||
|
["${OPENIM_ROOT}/scripts/template/config-tmpl/config.yaml"]="${OPENIM_OUTPUT_SUBPATH}/bin/config.yaml"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have your new mapping files, you can implement them by appending them to the array.
|
||||||
|
|
||||||
|
Lastly, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./scripts/init_config.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Define Configuration Variables
|
||||||
|
|
||||||
|
In the `scripts/install/environment.sh` file, we defined many reusable variables for automation convenience.
|
||||||
|
|
||||||
|
In the provided example, the def function is a core element. This function not only provides a concise way to define variables but also offers default value options for each variable. This way, even if a specific variable is not explicitly set in an environment or scenario, it can still have an expected value.
|
||||||
|
|
||||||
|
```
|
||||||
|
function def() {
|
||||||
|
local var_name="$1"
|
||||||
|
local default_value="$2"
|
||||||
|
eval "readonly $var_name=\${$var_name:-$default_value}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bash Parsing Features
|
||||||
|
|
||||||
|
Since bash is a parsing script language, it executes commands in the order they appear in the script. This characteristic means we can define commonly used or core variables at the beginning of the script and then reuse or modify them later on.
|
||||||
|
|
||||||
|
For instance, we can initially set a universal password and reuse this password in subsequent variable definitions.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Set a consistent password for easy memory
|
||||||
|
def "PASSWORD" "openIM123"
|
||||||
|
|
||||||
|
# Linux system user for openim
|
||||||
|
def "LINUX_USERNAME" "openim"
|
||||||
|
def "LINUX_PASSWORD" "${PASSWORD}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reasons and Advantages of the Design
|
||||||
|
|
||||||
|
1. **Simplify Configuration Management**: Through automation scripts, we can avoid manual operations and configurations, thus reducing tedious repetitive tasks.
|
||||||
|
2. **Reduce Errors**: Manually editing yaml or other configuration files can lead to formatting mistakes or typographical errors. Automating with scripts can lower the risk of such errors.
|
||||||
|
3. **Enhanced Readability**: Using the `def` function and other bash scripting techniques, we can establish a clear, easy-to-read, and maintainable configuration system.
|
||||||
|
4. **Improved Reusability**: As demonstrated above, we can reuse variables and functions in different parts of the script, reducing redundant code and increasing overall consistency.
|
||||||
|
5. **Flexible Default Value Mechanism**: By providing default values for variables, we can ensure configurations are complete and consistent across various scenarios, while also offering customization options for advanced users.
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# Install Docker
|
||||||
|
|
||||||
|
The installation command is as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ curl -fsSL https://get.docker.com | bash -s docker --mirror aliyun
|
||||||
|
``
|
||||||
|
|
||||||
|
## 2.2 Start Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ systemctl start docker
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.3 Test Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker run hello-world
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.4 Configure Docker Acceleration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ mkdir -p /etc/docker
|
||||||
|
$ tee /etc/docker/daemon.json <<-'EOF'
|
||||||
|
{
|
||||||
|
"registry-mirrors": ["https://registry.docker-cn.com"]
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
$ systemctl daemon-reload
|
||||||
|
$ systemctl restart docker
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.5 Install Docker Compose
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo curl -L "https://github.com/docker/compose/releases/download/latest/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
|
$ sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.6 Test Docker Compose
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker-compose --version
|
||||||
|
```
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
# Ubuntu 22.04 OpenIM Project Development Guide
|
||||||
|
|
||||||
|
## TOC
|
||||||
|
- [Ubuntu 22.04 OpenIM Project Development Guide](#ubuntu-2204-openim-project-development-guide)
|
||||||
|
- [TOC](#toc)
|
||||||
|
- [1. Setting Up Ubuntu Server](#1-setting-up-ubuntu-server)
|
||||||
|
- [1.1 Create `openim` Standard User](#11-create-openim-standard-user)
|
||||||
|
- [1.2 Setting up the `openim` User's Shell Environment](#12-setting-up-the-openim-users-shell-environment)
|
||||||
|
- [1.3 Installing Dependencies](#13-installing-dependencies)
|
||||||
|
|
||||||
|
## 1. Setting Up Ubuntu Server
|
||||||
|
|
||||||
|
You can use tools like PuTTY or other SSH clients to log in to your Ubuntu server. Once logged in, a few fundamental configurations are required, such as creating a standard user, adding to sudoers, and setting up the `$HOME/.bashrc` file. The steps are as follows:
|
||||||
|
|
||||||
|
## 1.1 Create `openim` Standard User
|
||||||
|
|
||||||
|
1. Log in to the Ubuntu system as the `root` user and create a standard user.
|
||||||
|
|
||||||
|
Generally, a project will involve multiple developers. Instead of provisioning a server for every developer, many organizations share a single development machine among developers. To simulate this real-world scenario, we'll use a standard user for development. To create the `openim` user:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code# adduser openim # Create the openim user, which developers will use for login and development.
|
||||||
|
# passwd openim # Set the login password for openim.
|
||||||
|
```
|
||||||
|
|
||||||
|
Working with a non-root user ensures the system's safety and is a good practice. It's recommended to avoid using the root user as much as possible during everyday development.
|
||||||
|
|
||||||
|
1. Add to sudoers.
|
||||||
|
|
||||||
|
Often, even standard users need root privileges. Instead of frequently asking the system administrator for the root password, you can add the standard user to the sudoers. This allows them to temporarily gain root access using the sudo command. To add the `openim` user to sudoers:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code
|
||||||
|
# sed -i '/^root.*ALL=(ALL:ALL).*ALL/a\openim\tALL=(ALL) \tALL' /etc/sudoers
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1.2 Setting up the `openim` User's Shell Environment
|
||||||
|
|
||||||
|
1. Log into the Ubuntu system.
|
||||||
|
|
||||||
|
Assuming we're using the **openim** user, log in using PuTTY or other SSH clients.
|
||||||
|
|
||||||
|
1. Configure the `$HOME/.bashrc` file.
|
||||||
|
|
||||||
|
The first step after logging into a new server is to configure the `$HOME/.bashrc` file. It makes the Linux shell more user-friendly by setting environment variables like `LANG` and `PS1`. Here's how the configuration would look:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code# .bashrc
|
||||||
|
|
||||||
|
# User specific aliases and functions
|
||||||
|
|
||||||
|
alias rm='rm -i'
|
||||||
|
alias cp='cp -i'
|
||||||
|
alias mv='mv -i'
|
||||||
|
|
||||||
|
# Source global definitions
|
||||||
|
if [ -f /etc/bashrc ]; then
|
||||||
|
. /etc/bashrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d $HOME/workspace ]; then
|
||||||
|
mkdir -p $HOME/workspace
|
||||||
|
fi
|
||||||
|
|
||||||
|
# User specific environment
|
||||||
|
export LANG="en_US.UTF-8"
|
||||||
|
export PS1='[\u@dev \W]\$ '
|
||||||
|
export WORKSPACE="$HOME/workspace"
|
||||||
|
export PATH=$HOME/bin:$PATH
|
||||||
|
|
||||||
|
cd $WORKSPACE
|
||||||
|
```
|
||||||
|
|
||||||
|
After updating `$HOME/.bashrc`, run the `bash` command to reload the configurations into the current shell.
|
||||||
|
|
||||||
|
## 1.3 Installing Dependencies
|
||||||
|
|
||||||
|
The OpenIM project on Ubuntu may have various dependencies. Some are direct, and others are indirect. Installing these in advance prevents issues like missing packages or compile-time errors later on.
|
||||||
|
|
||||||
|
1. Install dependencies.
|
||||||
|
|
||||||
|
You can use the `apt` command to install the required tools on Ubuntu:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code$ sudo apt-get update
|
||||||
|
$ sudo apt-get install build-essential autoconf automake cmake perl libcurl4-gnutls-dev libtool gcc g++ glibc-doc-reference zlib1g-dev git-lfs telnet lrzsz jq libexpat1-dev libssl-dev
|
||||||
|
$ sudo apt install libcurl4-openssl-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Install Git.
|
||||||
|
|
||||||
|
A higher version of Git ensures compatibility with certain commands like `git fetch --unshallow`. To install a recent version:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code$ cd /tmp
|
||||||
|
$ wget --no-check-certificate https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.36.1.tar.gz
|
||||||
|
$ tar -xvzf git-2.36.1.tar.gz
|
||||||
|
$ cd git-2.36.1/
|
||||||
|
$ ./configure
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
$ git --version
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, add Git's binary directory to the `PATH`:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code
|
||||||
|
$ echo 'export PATH=/usr/local/libexec/git-core:$PATH' >> $HOME/.bashrc
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Configure Git.
|
||||||
|
|
||||||
|
To set up Git:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code$ git config --global user.name "Your Name"
|
||||||
|
$ git config --global user.email "your_email@example.com"
|
||||||
|
$ git config --global credential.helper store
|
||||||
|
$ git config --global core.longpaths true
|
||||||
|
```
|
||||||
|
|
||||||
|
Other Git configurations include:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code
|
||||||
|
$ git config --global core.quotepath off
|
||||||
|
```
|
||||||
|
|
||||||
|
And for handling larger files:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code
|
||||||
|
$ git lfs install --skip-repo
|
||||||
|
```
|
||||||
|
|
||||||
|
By following the steps in this guide, your Ubuntu 22.04 server should now be set up and ready for OpenIM project development.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# act
|
||||||
|
|
||||||
|
Run your [GitHub Actions](https://developer.github.com/actions/) locally! Why would you want to do this? Two reasons:
|
||||||
|
|
||||||
|
- **Fast Feedback** - Rather than having to commit/push every time you want to test out the changes you are making to your `.github/workflows/` files (or for any changes to embedded GitHub actions), you can use `act` to run the actions locally. The [environment variables](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables) and [filesystem](https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners#filesystems-on-github-hosted-runners) are all configured to match what GitHub provides.
|
||||||
|
- **Local Task Runner** - I love [make](https://en.wikipedia.org/wiki/Make_(software)). However, I also hate repeating myself. With `act`, you can use the GitHub Actions defined in your `.github/workflows/` to replace your `Makefile`!
|
||||||
|
|
||||||
|
## install act
|
||||||
|
|
||||||
|
+ [https://github.com/nektos/act](https://github.com/nektos/act)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
|
||||||
|
···
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# OpenIM Protoc Tool
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
OpenIM is passionate about ensuring that its suite of tools is custom-tailored to cater to the unique needs of its users. That commitment led us to develop and release our custom Protoc tool, version v1.0.0.
|
||||||
|
|
||||||
|
### Why a Custom Version?
|
||||||
|
|
||||||
|
There are several reasons to choose our custom Protoc tool over generic open-source versions:
|
||||||
|
|
||||||
|
- **Specialized Features**: OpenIM's Protoc tool has been enriched with features and plugins that are optimized for the OpenIM ecosystem. This makes it more aligned with the needs of OpenIM users.
|
||||||
|
- **Optimized Performance**: Built from the ground up with OpenIM's infrastructure in mind, our tool guarantees faster and more efficient operations.
|
||||||
|
- **Enhanced Compatibility**: Our Protoc tool ensures full compatibility with OpenIM's offerings, minimizing potential conflicts and integration challenges.
|
||||||
|
- **Rich Output Support**: Unlike generic tools, our custom tool provides a wide array of output options including C++, C#, Java, Kotlin, Objective-C, PHP, Python, Ruby, and more. This allows developers to generate code for their preferred platform with ease.
|
||||||
|
|
||||||
|
## Download
|
||||||
|
|
||||||
|
+ https://github.com/OpenIMSDK/Open-IM-Protoc
|
||||||
|
|
||||||
|
Access the official release of the Protoc tool on the OpenIM repository here: [OpenIM Protoc Tool v1.0.0 Release](https://github.com/OpenIMSDK/Open-IM-Protoc/releases/tag/v1.0.0)
|
||||||
|
|
||||||
|
### Direct Download Links:
|
||||||
|
|
||||||
|
- **Windows**: [Download for Windows](https://github.com/OpenIMSDK/Open-IM-Protoc/releases/download/v1.0.0/windows.zip)
|
||||||
|
- **Linux**: [Download for Linux](https://github.com/OpenIMSDK/Open-IM-Protoc/releases/download/v1.0.0/linux.zip)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
For Windows:
|
||||||
|
|
||||||
|
1. Navigate to the Windows download link provided above and download the version suitable for your system.
|
||||||
|
2. Extract the contents of the zip file.
|
||||||
|
3. Add the path of the extracted tool to your `PATH` environment variable to run the Protoc tool directly from the command line.
|
||||||
|
|
||||||
|
For Linux:
|
||||||
|
|
||||||
|
1. Navigate to the Linux download link provided above and download the version suitable for your system.
|
||||||
|
2. Extract the contents of the zip file.
|
||||||
|
3. Use `chmod +x ./*` to make the extracted files executable.
|
||||||
|
4. Add the path of the extracted tool to your `PATH` environment variable to run the Protoc tool directly from the command line.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The OpenIM Protoc tool provides a multitude of options for parsing `.proto` files and generating output:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code
|
||||||
|
./protoc [OPTION] PROTO_FILES
|
||||||
|
```
|
||||||
|
|
||||||
|
Some of the key options include:
|
||||||
|
|
||||||
|
- `--proto_path=PATH`: Specify the directory to search for imports.
|
||||||
|
- `--version`: Show version info.
|
||||||
|
- `--encode=MESSAGE_TYPE`: Convert a text-format message of a given type from standard input to binary on standard output.
|
||||||
|
- `--decode=MESSAGE_TYPE`: Convert a binary message of a given type from standard input to text format on standard output.
|
||||||
|
- `--cpp_out=OUT_DIR`: Generate C++ header and source.
|
||||||
|
- `--java_out=OUT_DIR`: Generate Java source file.
|
||||||
|
|
||||||
|
... and many more. For a full list of options, run `./protoc --help` or refer to the official documentation.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# utils go
|
||||||
|
|
||||||
|
+ [toold readme](https://github.com/OpenIMSDK/Open-IM-Server/tree/main/tools)
|
||||||
|
|
||||||
|
about scripts fix:
|
||||||
|
```
|
||||||
|
"${OPENIM-ROOT}/_output/bin/tools/${platform}/${lookfor}"
|
||||||
|
```
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
# Open-IM-Server Development Tools Guide
|
||||||
|
|
||||||
|
- [Open-IM-Server Development Tools Guide](#open-im-server-development-tools-guide)
|
||||||
|
- [Introduction](#introduction)
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
- [Toolset Categories](#toolset-categories)
|
||||||
|
- [Installation Commands](#installation-commands)
|
||||||
|
- [Basic Installation](#basic-installation)
|
||||||
|
- [Individual Tool Installation](#individual-tool-installation)
|
||||||
|
- [Tool Verification](#tool-verification)
|
||||||
|
- [Detailed Tool Descriptions](#detailed-tool-descriptions)
|
||||||
|
- [Best Practices](#best-practices)
|
||||||
|
- [Conclusion](#conclusion)
|
||||||
|
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
Open-IM-Server boasts a robust set of tools encapsulated within its Makefile system, designed to ease development, code formatting, and tool management. This guide aims to familiarize developers with the features and usage of the Makefile toolset provided within the Open-IM-Server project.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
Executing `make tools` ensures verification and installation of the default tools:
|
||||||
|
|
||||||
|
- golangci-lint
|
||||||
|
- goimports
|
||||||
|
- addlicense
|
||||||
|
- deepcopy-gen
|
||||||
|
- conversion-gen
|
||||||
|
- ginkgo
|
||||||
|
- go-junit-report
|
||||||
|
- go-gitlint
|
||||||
|
|
||||||
|
The installation path is situated at `/root/workspaces/openim/Open-IM-Server/_output/tools/`.
|
||||||
|
|
||||||
|
## Toolset Categories
|
||||||
|
|
||||||
|
The Makefile logically groups tools into different categories for better management:
|
||||||
|
|
||||||
|
- **Development Tools**: `BUILD_TOOLS`
|
||||||
|
- **Code Analysis Tools**: `ANALYSIS_TOOLS`
|
||||||
|
- **Code Generation Tools**: `GENERATION_TOOLS`
|
||||||
|
- **Testing Tools**: `TEST_TOOLS`
|
||||||
|
- **Version Control Tools**: `VERSION_CONTROL_TOOLS`
|
||||||
|
- **Utility Tools**: `UTILITY_TOOLS`
|
||||||
|
- **Tencent Cloud Object Storage Tools**: `COS_TOOLS`
|
||||||
|
|
||||||
|
## Installation Commands
|
||||||
|
|
||||||
|
1. **golangci-lint**: high performance Go code linter with integration of multiple inspection tools.
|
||||||
|
2. **goimports**: Used to format Go source files and automatically add or remove imports.
|
||||||
|
3. **addlicense**: Adds a license header to the source file.
|
||||||
|
4. **deepcopy-gen and conversions-gen **: Generate deepcopy and conversion functionality.
|
||||||
|
5. **ginkgo**: Testing framework for Go.
|
||||||
|
6. **go-junit-report**: Converts Go test output to junit xml format.
|
||||||
|
7. **go-gitlint**: For checking git commit information. ... (And so on, list all the tools according to the `make tools.help` output above)...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Basic Installation
|
||||||
|
|
||||||
|
- `tools.install`: Installs tools mentioned in the `BUILD_TOOLS` list.
|
||||||
|
- `tools.install-all`: Installs all tools from the `ALL_TOOLS` list.
|
||||||
|
|
||||||
|
### Individual Tool Installation
|
||||||
|
|
||||||
|
- `tools.install.%`: Installs a single tool in the `$GOBIN/` directory.
|
||||||
|
- `tools.install-all.%`: Parallelly installs an individual tool located in `./tools/*`.
|
||||||
|
|
||||||
|
### Tool Verification
|
||||||
|
|
||||||
|
- `tools.verify.%`: Checks if a specific tool is installed, and if not, installs it.
|
||||||
|
|
||||||
|
## Detailed Tool Descriptions
|
||||||
|
|
||||||
|
The following commands serve the purpose of installing particular development tools:
|
||||||
|
|
||||||
|
- `install.golangci-lint`: Installs `golangci-lint`.
|
||||||
|
- `install.addlicense`: Installs `addlicense`. ... (and so on for every tool as mentioned in the provided Makefile source)...
|
||||||
|
|
||||||
|
The commands primarily leverage Go's `install` operation, fetching and installing tools from their respective repositories. This method is especially convenient as it auto-handles dependencies and installation paths. For tools not written directly with Go (like `install.coscli`), other installation methods like wget or pip are employed.
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Regular Updates**: To ensure tools are up-to-date, periodically run the `make tools` command.
|
||||||
|
2. **Individual Tools**: If only specific tools are required, employ the `make install.<tool-name>` command for individual installations.
|
||||||
|
3. **Verification**: Before code submissions, use the `make tools.verify.%` command to guarantee that all necessary tools are present and up-to-date.
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
The Makefile provided by Open-IM-Server presents a centralized approach to manage and install all necessary tools during the development process. It ensures that all developers employ consistent tool versions, reducing potential issues due to version disparities. Whether you're a maintainer or a contributor to the Open-IM-Server project, understanding the workings of this Makefile will significantly enhance your developmental efficiency.
|
||||||
@@ -0,0 +1,248 @@
|
|||||||
|
# OpenIM Bash Utility Script
|
||||||
|
|
||||||
|
This script offers a variety of utilities and helpers to enhance and simplify operations related to the OpenIM project.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [OpenIM Bash Utility Script](#openim-bash-utility-script)
|
||||||
|
- [Table of Contents](#table-of-contents)
|
||||||
|
- [brief descriptions of each function](#brief-descriptions-of-each-function)
|
||||||
|
- [Introduction](#introduction)
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [SSH Key Setup](#ssh-key-setup)
|
||||||
|
- [openim::util::ensure-gnu-sed](#openimutilensure-gnu-sed)
|
||||||
|
- [openim::util::ensure-gnu-date](#openimutilensure-gnu-date)
|
||||||
|
- [openim::util::check-file-in-alphabetical-order](#openimutilcheck-file-in-alphabetical-order)
|
||||||
|
- [openim::util::require-jq](#openimutilrequire-jq)
|
||||||
|
- [openim::util::md5](#openimutilmd5)
|
||||||
|
- [openim::util::read-array](#openimutilread-array)
|
||||||
|
- [Color Definitions](#color-definitions)
|
||||||
|
- [openim::util::desc and related functions](#openimutildesc-and-related-functions)
|
||||||
|
- [openim::util::onCtrlC](#openimutilonctrlc)
|
||||||
|
- [openim::util::list-to-string](#openimutillist-to-string)
|
||||||
|
- [openim::util::remove-space](#openimutilremove-space)
|
||||||
|
- [openim::util::gencpu](#openimutilgencpu)
|
||||||
|
- [openim::util::gen-os-arch](#openimutilgen-os-arch)
|
||||||
|
- [openim::util::download-file](#openimutildownload-file)
|
||||||
|
- [openim::util::get-public-ip](#openimutilget-public-ip)
|
||||||
|
- [openim::util::extract-tarball](#openimutilextract-tarball)
|
||||||
|
- [openim::util::check-port-open](#openimutilcheck-port-open)
|
||||||
|
- [openim::util::file-lines-count](#openimutilfile-lines-count)
|
||||||
|
|
||||||
|
|
||||||
|
## brief descriptions of each function
|
||||||
|
|
||||||
|
**Englist:**
|
||||||
|
1. `openim::util::ensure-gnu-sed` - Determines if GNU version of `sed` exists on the system and sets its name.
|
||||||
|
2. `openim::util::ensure-gnu-date` - Determines if GNU version of `date` exists on the system and sets its name.
|
||||||
|
3. `openim::util::check-file-in-alphabetical-order` - Checks if a file is sorted in alphabetical order.
|
||||||
|
4. `openim::util::require-jq` - Checks if `jq` is installed.
|
||||||
|
5. `openim::util::md5` - Outputs the MD5 hash of a file.
|
||||||
|
6. `openim::util::read-array` - Reads content from standard input into an array.
|
||||||
|
7. `openim::util::desc` - Displays descriptive information.
|
||||||
|
8. `openim::util::run::prompt` - Displays a prompt.
|
||||||
|
9. `openim::util::run::maybe-first-prompt` - Possibly displays the first prompt based on whether it's started or not.
|
||||||
|
10. `openim::util::run` - Executes a command and captures its output.
|
||||||
|
11. `openim::util::run::relative` - Returns paths relative to the current script.
|
||||||
|
12. `openim::util::onCtrlC` - Performs an action when Ctrl+C is pressed.
|
||||||
|
13. `openim::util::list-to-string` - Converts a list into a string.
|
||||||
|
14. `openim::util::remove-space` - Removes spaces from a string.
|
||||||
|
15. `openim::util::gencpu` - Retrieves CPU information.
|
||||||
|
16. `openim::util::gen-os-arch` - Generates a repository directory based on the operating system and architecture.
|
||||||
|
17. `openim::util::download-file` - Downloads a file from a URL.
|
||||||
|
18. `openim::util::get-public-ip` - Retrieves the public IP address of the machine.
|
||||||
|
19. `openim::util::extract-tarball` - Extracts a tarball to a specified directory.
|
||||||
|
20. `openim::util::check-port-open` - Checks if a given port is open on the machine.
|
||||||
|
21. `openim::util::file-lines-count` - Counts the number of lines in a file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
This script is mainly used to validate whether the code is correctly formatted by `gofmt`. Apart from that, it offers utilities like setting up SSH keys, various wait conditions, host and platform detection, documentation generation, etc.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### SSH Key Setup
|
||||||
|
|
||||||
|
To set up an SSH key:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#1. Write IPs in a file, one IP per line. Let's name it hosts-file.
|
||||||
|
#2. Modify the default username and password in the script.
|
||||||
|
hosts-file-path="path/to/your/hosts/file"
|
||||||
|
openim:util::setup_ssh_key_copy "$hosts-file-path" "root" "123"
|
||||||
|
```
|
||||||
|
|
||||||
|
## openim::util::ensure-gnu-sed
|
||||||
|
|
||||||
|
Ensures the presence of the GNU version of the `sed` command. Different operating systems may have variations of the `sed` command, and this utility function is used to make sure the script uses the GNU version. If it finds the GNU `sed`, it sets the `SED` variable accordingly. If not found, it checks for `gsed`, which is usually the name of GNU `sed` on macOS. If neither is found, an error message is displayed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::ensure-gnu-date
|
||||||
|
|
||||||
|
Similar to the function for `sed`, this function ensures the script uses the GNU version of the `date` command. If it identifies the GNU `date`, it sets the `DATE` variable. On macOS, it looks for `gdate` as an alternative. In the absence of both, an error message is recommended.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::check-file-in-alphabetical-order
|
||||||
|
|
||||||
|
This function checks if the contents of a given file are sorted in alphabetical order. If not, it provides a command suggestion for the user to sort the file correctly.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::require-jq
|
||||||
|
|
||||||
|
Verifies the installation of `jq`, a popular command-line JSON parser. If it's not present, a prompt to install it is displayed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::md5
|
||||||
|
|
||||||
|
A cross-platform function that computes the MD5 hash of its input. This function takes into account the differences in the `md5` command between macOS and Linux.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::read-array
|
||||||
|
|
||||||
|
A function designed to read from stdin and populate an array, line by line. It's provided as an alternative to `mapfile -t` and is compatible with bash 3.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Color Definitions
|
||||||
|
|
||||||
|
The script also defines a set of colors to enhance its console output. These include colors like red, yellow, green, blue, cyan, etc., which can be used for better user experience and clear logs.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::desc and related functions
|
||||||
|
|
||||||
|
These functions seem to aid in building interactive demonstrations or tutorials in the terminal. They use the `pv` utility to control the display rate of the output, emulating typing. There's also functionality to handle user prompts and execute commands while capturing their output.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::onCtrlC
|
||||||
|
|
||||||
|
Handles the `CTRL+C` command. It terminates background processes of the script when the user interrupts it using `CTRL+C`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::list-to-string
|
||||||
|
|
||||||
|
Transforms a list format (like `[10023, 2323, 3434]`) to a space-separated string (`10023 2323 3434`). Also removes unnecessary spaces and characters.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::remove-space
|
||||||
|
|
||||||
|
Removes spaces from a given string.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::gencpu
|
||||||
|
|
||||||
|
Fetches the number of CPUs using the `lscpu` command.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::gen-os-arch
|
||||||
|
|
||||||
|
Identifies the operating system and architecture of the system running the script. This is useful to determine directories or binaries specific to that OS and architecture.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::download-file
|
||||||
|
|
||||||
|
This function can be used to download a file from a URL. If `curl` is available, it uses `curl`. If not, it falls back to `wget`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
function openim::util::download-file() {
|
||||||
|
local url="$1"
|
||||||
|
local dest="$2"
|
||||||
|
|
||||||
|
if command -v curl &>/dev/null; then
|
||||||
|
curl -L "${url}" -o "${dest}"
|
||||||
|
elif command -v wget &>/dev/null; then
|
||||||
|
wget "${url}" -O "${dest}"
|
||||||
|
else
|
||||||
|
openim::log::error "Neither curl nor wget available. Cannot download file."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::get-public-ip
|
||||||
|
|
||||||
|
Fetches the public IP address of the machine.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
function openim::util::get-public-ip() {
|
||||||
|
if command -v curl &>/dev/null; then
|
||||||
|
curl -s https://ipinfo.io/ip
|
||||||
|
elif command -v wget &>/dev/null; then
|
||||||
|
wget -qO- https://ipinfo.io/ip
|
||||||
|
else
|
||||||
|
openim::log::error "Neither curl nor wget available. Cannot fetch public IP."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::extract-tarball
|
||||||
|
|
||||||
|
This function extracts a tarball to a specified directory.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
function openim::util::extract-tarball() {
|
||||||
|
local tarball="$1"
|
||||||
|
local dest="$2"
|
||||||
|
|
||||||
|
mkdir -p "${dest}"
|
||||||
|
tar -xzf "${tarball}" -C "${dest}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::check-port-open
|
||||||
|
|
||||||
|
Checks if a given port is open on the local machine.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
function openim::util::check-port-open() {
|
||||||
|
local port="$1"
|
||||||
|
if command -v nc &>/dev/null; then
|
||||||
|
echo -n > /dev/tcp/127.0.0.1/"${port}" 2>&1
|
||||||
|
return $?
|
||||||
|
elif command -v telnet &>/dev/null; then
|
||||||
|
telnet 127.0.0.1 "${port}" 2>&1 | grep -q "Connected"
|
||||||
|
return $?
|
||||||
|
else
|
||||||
|
openim::log::error "Neither nc nor telnet available. Cannot check port."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## openim::util::file-lines-count
|
||||||
|
|
||||||
|
Counts the number of lines in a file.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
function openim::util::file-lines-count() {
|
||||||
|
local file="$1"
|
||||||
|
if [[ -f "${file}" ]]; then
|
||||||
|
wc -l < "${file}"
|
||||||
|
else
|
||||||
|
openim::log::error "File does not exist: ${file}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
## OpenIM Logging System: Design and Usage
|
||||||
|
|
||||||
|
**PATH:** `scripts/lib/logging.sh`
|
||||||
|
|
||||||
|
### Introduction
|
||||||
|
|
||||||
|
OpenIM, an intricate project, requires a robust logging mechanism to diagnose issues, maintain system health, and provide insights. A custom-built logging system embedded within OpenIM ensures consistent and structured logs. Let's delve into the design of this logging system and understand its various functions and their usage scenarios.
|
||||||
|
|
||||||
|
### Design Overview
|
||||||
|
|
||||||
|
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 `ENABLE_LOGGING=flase`.
|
||||||
|
|
||||||
|
### Key Functions & Their Usages
|
||||||
|
|
||||||
|
1. **Error Handling**:
|
||||||
|
- `openim::log::errexit()`: Activated when a command exits with an error. It prints a call tree showing the sequence of functions leading to the error and then calls `openim::log::error_exit()` with relevant information.
|
||||||
|
- `openim::log::install_errexit()`: Sets up the trap for catching errors and ensures that the error handler (`errexit`) gets propagated to various script constructs like functions, expansions, and subshells.
|
||||||
|
2. **Logging Levels**:
|
||||||
|
- `openim::log::error()`: Logs error messages with a timestamp. The log message starts with '!!!' to indicate its severity.
|
||||||
|
- `openim::log::info()`: Provides informational messages. The display of these messages is governed by the verbosity level (`OPENIM_VERBOSE`).
|
||||||
|
- `openim::log::progress()`: Designed for logging progress messages or creating progress bars.
|
||||||
|
- `openim::log::status()`: Logs status messages with a timestamp, prefixing each entry with '+++' for easy identification.
|
||||||
|
- `openim::log::success()`: Highlights successful operations with a bright green prefix. It's ideal for visually signifying operations that completed successfully.
|
||||||
|
3. **Exit and Stack Trace**:
|
||||||
|
- `openim::log::error_exit()`: Logs an error message, dumps the call stack, and exits the script with a specified exit code.
|
||||||
|
- `openim::log::stack()`: Prints out a stack trace, showing the call hierarchy leading to the point where this function was invoked.
|
||||||
|
4. **Usage Information**:
|
||||||
|
- `openim::log::usage() & openim::log::usage_from_stdin()`: Both functions provide a mechanism to display usage instructions. The former accepts arguments directly, while the latter reads them from stdin.
|
||||||
|
5. **Test Function**:
|
||||||
|
- `openim::log::test_log()`: This function is a test suite to verify that all logging functions are operating as expected.
|
||||||
|
|
||||||
|
### Usage Scenario
|
||||||
|
|
||||||
|
Imagine a situation where an OpenIM operation fails, and you need to ascertain the cause. With the logging system in place, you can:
|
||||||
|
|
||||||
|
- Check the log file for the specific day to find error messages with the '!!!' prefix.
|
||||||
|
- View the call tree and stack trace to trace back the sequence of operations leading to the failure.
|
||||||
|
- Use the verbosity level to filter out unnecessary details and focus on the crux of the issue.
|
||||||
|
|
||||||
|
This systematic and structured approach greatly simplifies the debugging process, making system maintenance more efficient.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
|
||||||
|
OpenIM's logging system is a testament to the importance of structured and detailed logging in complex projects. By using this logging mechanism, developers and system administrators can streamline troubleshooting and ensure the seamless operation of the OpenIM project.
|
||||||
+201
-212
@@ -1,23 +1,19 @@
|
|||||||
## Go 代码开发规范
|
## OpenIM development specification
|
||||||
在Go 项目开发中,一个好的编码规范可以极大的提高代码质量。为了帮你节省时间和精力,这里我整理了一份清晰、可直接套用的 Go 编码规范,供你参考。
|
We have very high standards for code style and specification, and we want our products to be polished and perfect
|
||||||
|
|
||||||
这份规范,是我参考了 Go 官方提供的编码规范,以及 Go 社区沉淀的一些比较合理的规范之后,加入自己的理解总结出的,它比很多公司内部的规范更全面,你掌握了,以后在面试大厂的时候,或者在大厂里写代码的时候,都会让人高看你一眼,觉得你code很专业。
|
## 1. Code style
|
||||||
|
|
||||||
这份编码规范中包含代码风格、命名规范、注释规范、类型、控制结构、函数、GOPATH 设置规范、依赖管理和最佳实践九类规范。如果你觉得这些规范内容太多了,看完一遍也记不住,这完全没关系。你可以多看几遍,也可以在用到时把它翻出来,在实际应用中掌握。这篇特别放送的内容,更多是作为写代码时候的一个参考手册。
|
### 1.1 Code format
|
||||||
|
|
||||||
## 1. 代码风格
|
- Code must be formatted with `gofmt`.
|
||||||
|
- Leave spaces between operators and operands.
|
||||||
### 1.1 代码格式
|
- It is recommended that a line of code does not exceed 120 characters. If the part exceeds, please use an appropriate line break method. But there are also some exception scenarios, such as import lines, code automatically generated by tools, and struct fields with tags.
|
||||||
|
- The file length cannot exceed 800 lines.
|
||||||
- 代码都必须用 `gofmt` 进行格式化。
|
- Function length cannot exceed 80 lines.
|
||||||
- 运算符和操作数之间要留空格。
|
- import specification
|
||||||
- 建议一行代码不超过120个字符,超过部分,请采用合适的换行方式换行。但也有些例外场景,例如import行、工具自动生成的代码、带tag的struct字段。
|
- All code must be formatted with `goimports` (it is recommended to set the code Go code editor to: run `goimports` on save).
|
||||||
- 文件长度不能超过800行。
|
- Do not use relative paths to import packages, such as `import ../util/net`.
|
||||||
- 函数长度不能超过80行。
|
- Import aliases must be used when the package name does not match the last directory name of the import path, or when multiple identical package names conflict.
|
||||||
- import规范
|
|
||||||
- 代码都必须用`goimports`进行格式化(建议将代码Go代码编辑器设置为:保存时运行 `goimports`)。
|
|
||||||
- 不要使用相对路径引入包,例如 `import ../util/net` 。
|
|
||||||
- 包名称与导入路径的最后一个目录名不匹配时,或者多个相同包名冲突时,则必须使用导入别名。
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -26,32 +22,29 @@
|
|||||||
//good
|
//good
|
||||||
jwt "github.com/dgrijalva/jwt-go/v4"
|
jwt "github.com/dgrijalva/jwt-go/v4"
|
||||||
```
|
```
|
||||||
- 导入的包建议进行分组,匿名包的引用使用一个新的分组,并对匿名包引用进行说明。
|
- Imported packages are suggested to be grouped, and anonymous package references use a new group, and anonymous package references are explained.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
// go 标准包
|
// go standard package
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
// 第三方包
|
// third party package
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
// 匿名包单独分组,并对匿名包引用进行说明
|
// Anonymous packages are grouped separately, and anonymous package references are explained
|
||||||
// import mysql driver
|
// import mysql driver
|
||||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
|
|
||||||
// 内部包
|
// inner package
|
||||||
v1 "github.com/marmotedu/api/apiserver/v1"
|
|
||||||
metav1 "github.com/marmotedu/apimachinery/pkg/meta/v1"
|
|
||||||
"github.com/marmotedu/iam/pkg/cli/genericclioptions"
|
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.2 声明、初始化和定义
|
### 1.2 Declaration, initialization and definition
|
||||||
|
|
||||||
当函数中需要使用到多个变量时,可以在函数开始处使用`var`声明。在函数外部声明必须使用 `var` ,不要采用 `:=` ,容易踩到变量的作用域的问题。
|
When multiple variables need to be used in a function, the `var` declaration can be used at the beginning of the function. Declaration outside the function must use `var`, do not use `:=`, it is easy to step on the scope of the variable.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var (
|
var (
|
||||||
@@ -60,7 +53,7 @@ var (
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
- 在初始化结构引用时,请使用`&T{}`代替`new(T)`,以使其与结构体初始化一致。
|
- When initializing a structure reference, please use `&T{}` instead of `new(T)` to make it consistent with structure initialization.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -71,7 +64,7 @@ sptr.Name = "bar"
|
|||||||
sptr := &T{Name: "bar"}
|
sptr := &T{Name: "bar"}
|
||||||
```
|
```
|
||||||
|
|
||||||
- struct 声明和初始化格式采用多行,定义如下。
|
- The struct declaration and initialization format takes multiple lines and is defined as follows.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type User struct{
|
type User struct{
|
||||||
@@ -85,7 +78,7 @@ user := User{
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- 相似的声明放在一组,同样适用于常量、变量和类型声明。
|
- Similar declarations are grouped together, and the same applies to constant, variable, and type declarations.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -99,14 +92,14 @@ import (
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
- 尽可能指定容器容量,以便为容器预先分配内存,例如:
|
- Specify container capacity where possible to pre-allocate memory for the container, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
v := make(map[int]string, 4)
|
v := make(map[int]string, 4)
|
||||||
v := make([]string, 0, 4)
|
v := make([]string, 0, 4)
|
||||||
```
|
```
|
||||||
|
|
||||||
- 在顶层,使用标准var关键字。请勿指定类型,除非它与表达式的类型不同。
|
- At the top level, use the standard var keyword. Do not specify a type unless it is different from the type of the expression.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -116,13 +109,13 @@ func F() string { return "A" }
|
|||||||
|
|
||||||
// good
|
// good
|
||||||
var_s = F()
|
var_s = F()
|
||||||
// 由于 F 已经明确了返回一个字符串类型,因此我们没有必要显式指定_s 的类型
|
// Since F already explicitly returns a string type, we don't need to explicitly specify the type of _s
|
||||||
// 还是那种类型
|
// still of that type
|
||||||
|
|
||||||
func F() string { return "A" }
|
func F() string { return "A" }
|
||||||
```
|
```
|
||||||
|
|
||||||
- 对于未导出的顶层常量和变量,使用`_`作为前缀。
|
- Use `_` as a prefix for unexported top-level constants and variables.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -138,7 +131,7 @@ const (
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
- 嵌入式类型(例如 mutex)应位于结构体内的字段列表的顶部,并且必须有一个空行将嵌入式字段与常规字段分隔开。
|
- Embedded types (such as mutexes) should be at the top of the field list within the struct, and there must be a blank line separating embedded fields from regular fields.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -155,9 +148,9 @@ type Client struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.3 错误处理
|
### 1.3 Error Handling
|
||||||
|
|
||||||
- `error`作为函数的值返回,必须对`error`进行处理,或将返回值赋值给明确忽略。对于`defer xx.Close()`可以不用显式处理。
|
- `error` is returned as the value of the function, `error` must be handled, or the return value assigned to explicitly ignore. For `defer xx.Close()`, there is no need to explicitly handle it.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func load() error {
|
func load() error {
|
||||||
@@ -171,7 +164,7 @@ load()
|
|||||||
_ = load()
|
_ = load()
|
||||||
```
|
```
|
||||||
|
|
||||||
- `error`作为函数的值返回且有多个返回值的时候,`error`必须是最后一个参数。
|
- When `error` is returned as the value of a function and there are multiple return values, `error` must be the last parameter.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -185,7 +178,7 @@ func load() (int, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- 尽早进行错误处理,并尽早返回,减少嵌套。
|
- Perform error handling as early as possible and return as early as possible to reduce nesting.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -203,7 +196,7 @@ if err != nil {
|
|||||||
// normal code
|
// normal code
|
||||||
```
|
```
|
||||||
|
|
||||||
- 如果需要在 if 之外使用函数调用的结果,则应采用下面的方式。
|
- If you need to use the result of the function call outside if, you should use the following method.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -218,7 +211,7 @@ if err != nil {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- 错误要单独判断,不与其他逻辑组合判断。
|
- Errors should be judged independently, not combined with other logic.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -241,7 +234,7 @@ if v == nil {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- 如果返回值需要初始化,则采用下面的方式。
|
- If the return value needs to be initialized, use the following method.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
v, err := f()
|
v, err := f()
|
||||||
@@ -251,8 +244,8 @@ if err != nil {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- 错误描述建议
|
- Bug description suggestions
|
||||||
- 错误描述用小写字母开头,结尾不要加标点符号,例如:
|
- Error descriptions start with a lowercase letter and do not end with punctuation, for example:
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
errors.New("Redis connection failed")
|
errors.New("Redis connection failed")
|
||||||
@@ -261,34 +254,34 @@ if err != nil {
|
|||||||
// good
|
// good
|
||||||
errors.New("redis connection failed")
|
errors.New("redis connection failed")
|
||||||
```
|
```
|
||||||
- 告诉用户他们可以做什么,而不是告诉他们不能做什么。
|
- Tell users what they can do, not what they can't.
|
||||||
- 当声明一个需求时,用must 而不是should。例如,`must be greater than 0、must match regex '[a-z]+'`。
|
- When declaring a requirement, use must instead of should. For example, `must be greater than 0, must match regex '[a-z]+'`.
|
||||||
- 当声明一个格式不对时,用must not。例如,`must not contain`。
|
- When declaring that a format is incorrect, use must not. For example, `must not contain`.
|
||||||
- 当声明一个动作时用may not。例如,`may not be specified when otherField is empty、only name may be specified`。
|
- Use may not when declaring an action. For example, `may not be specified when otherField is empty, only name may be specified`.
|
||||||
- 引用文字字符串值时,请在单引号中指示文字。例如,`ust not contain '..'`。
|
- When quoting a literal string value, indicate the literal in single quotes. For example, `ust not contain '..'`.
|
||||||
- 当引用另一个字段名称时,请在反引号中指定该名称。例如,must be greater than `request`。
|
- When referencing another field name, specify that name in backticks. For example, must be greater than `request`.
|
||||||
- 指定不等时,请使用单词而不是符号。例如,`must be less than 256、must be greater than or equal to 0 (不要用 larger than、bigger than、more than、higher than)`。
|
- When specifying unequal, use words instead of symbols. For example, `must be less than 256, must be greater than or equal to 0 (do not use larger than, bigger than, more than, higher than)`.
|
||||||
- 指定数字范围时,请尽可能使用包含范围。
|
- When specifying ranges of numbers, use inclusive ranges whenever possible.
|
||||||
- 建议 Go 1.13 以上,error 生成方式为 `fmt.Errorf("module xxx: %w", err)`。
|
- Go 1.13 or above is recommended, and the error generation method is `fmt.Errorf("module xxx: %w", err)`.
|
||||||
|
|
||||||
### 1.4 panic处理
|
### 1.4 panic processing
|
||||||
|
|
||||||
- 在业务逻辑处理中禁止使用panic。
|
- Panic is prohibited in business logic processing.
|
||||||
- 在main包中,只有当程序完全不可运行时使用panic,例如无法打开文件、无法连接数据库导致程序无法正常运行。
|
- In the main package, panic is only used when the program is completely inoperable, for example, the file cannot be opened, the database cannot be connected, and the program cannot run normally.
|
||||||
- 在main包中,使用 `log.Fatal` 来记录错误,这样就可以由log来结束程序,或者将panic抛出的异常记录到日志文件中,方便排查问题。
|
- In the main package, use `log.Fatal` to record errors, so that the program can be terminated by the log, or the exception thrown by the panic can be recorded in the log file, which is convenient for troubleshooting.
|
||||||
- 可导出的接口一定不能有panic。
|
- An exportable interface must not panic.
|
||||||
- 包内建议采用error而不是panic来传递错误。
|
- It is recommended to use error instead of panic to convey errors in the package.
|
||||||
|
|
||||||
### 1.5 单元测试
|
### 1.5 Unit Tests
|
||||||
|
|
||||||
- 单元测试文件名命名规范为 `example_test.go`。
|
- The unit test filename naming convention is `example_test.go`.
|
||||||
- 每个重要的可导出函数都要编写测试用例。
|
- Write a test case for every important exportable function.
|
||||||
- 因为单元测试文件内的函数都是不对外的,所以可导出的结构体、函数等可以不带注释。
|
- Because the functions in the unit test file are not external, the exportable structures, functions, etc. can be uncommented.
|
||||||
- 如果存在 `func (b *Bar) Foo` ,单测函数可以为 `func TestBar_Foo`。
|
- If `func (b *Bar) Foo` exists, the single test function can be `func TestBar_Foo`.
|
||||||
|
|
||||||
### 1.6 类型断言失败处理
|
### 1.6 Type assertion failure handling
|
||||||
|
|
||||||
- type assertion 的单个返回值针对不正确的类型将产生 panic。请始终使用 “comma ok”的惯用法。
|
- A single return value from a type assertion will panic for an incorrect type. Always use the "comma ok" idiom.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -301,85 +294,85 @@ if !ok {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. 命名规范
|
## 2. Naming convention
|
||||||
|
|
||||||
命名规范是代码规范中非常重要的一部分,一个统一的、短小的、精确的命名规范可以大大提高代码的可读性,也可以借此规避一些不必要的Bug。
|
The naming convention is a very important part of the code specification. A uniform, short, and precise naming convention can greatly improve the readability of the code and avoid unnecessary bugs.
|
||||||
|
|
||||||
### 2.1 包命名
|
### 2.1 Package Naming
|
||||||
|
|
||||||
- 包名必须和目录名一致,尽量采取有意义、简短的包名,不要和标准库冲突。
|
- The package name must be consistent with the directory name, try to use a meaningful and short package name, and do not conflict with the standard library.
|
||||||
- 包名全部小写,没有大写或下划线,使用多级目录来划分层级。
|
- Package names are all lowercase, without uppercase or underscores, and use multi-level directories to divide the hierarchy.
|
||||||
- 项目名可以通过中划线来连接多个单词。
|
- Item names can connect multiple words with dashes.
|
||||||
- 包名以及包所在的目录名,不要使用复数,例如,是`net/url`,而不是`net/urls`。
|
- Do not use plurals for the package name and the directory name where the package is located, for example, `net/url` instead of `net/urls`.
|
||||||
- 不要用 common、util、shared 或者 lib 这类宽泛的、无意义的包名。
|
- Don't use broad, meaningless package names like common, util, shared or lib.
|
||||||
- 包名要简单明了,例如 net、time、log。
|
- The package name should be simple and clear, such as net, time, log.
|
||||||
|
|
||||||
### 2.2 函数命名
|
### 2.2 Function Naming
|
||||||
|
|
||||||
- 函数名采用驼峰式,首字母根据访问控制决定使用大写或小写,例如:`MixedCaps`或者`mixedCaps`。
|
- The function name is in camel case, and the first letter is uppercase or lowercase according to the access control decision,For example: `MixedCaps` or `mixedCaps`.
|
||||||
- 代码生成工具自动生成的代码(如`xxxx.pb.go`)和为了对相关测试用例进行分组,而采用的下划线(如`TestMyFunction_WhatIsBeingTested`)排除此规则。
|
- Code automatically generated by code generation tools (such as `xxxx.pb.go`) and underscores used to group related test cases (such as `TestMyFunction_WhatIsBeingTested`) exclude this rule.
|
||||||
|
|
||||||
### 2.3 文件命名
|
### 2.3 File Naming
|
||||||
|
|
||||||
- 文件名要简短有意义。
|
- Keep the filename short and meaningful.
|
||||||
- 文件名应小写,并使用下划线分割单词。
|
- Filenames should be lowercase and use underscores to separate words.
|
||||||
|
|
||||||
### 2.4 结构体命名
|
### 2.4 Structure Naming
|
||||||
|
|
||||||
- 采用驼峰命名方式,首字母根据访问控制决定使用大写或小写,例如`MixedCaps`或者`mixedCaps`。
|
- The camel case is adopted, and the first letter is uppercase or lowercase according to the access control, such as `MixedCaps` or `mixedCaps`.
|
||||||
- 结构体名不应该是动词,应该是名词,比如 `Node`、`NodeSpec`。
|
- Struct names should not be verbs, but should be nouns, such as `Node`, `NodeSpec`.
|
||||||
- 避免使用Data、Info这类无意义的结构体名。
|
- Avoid using meaningless structure names such as Data and Info.
|
||||||
- 结构体的声明和初始化应采用多行,例如:
|
- The declaration and initialization of the structure should take multiple lines, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// User 多行声明
|
// User multi-line declaration
|
||||||
type User struct {
|
type User struct {
|
||||||
Name string
|
name string
|
||||||
Email string
|
Email string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 多行初始化
|
// multi-line initialization
|
||||||
u := User{
|
u := User{
|
||||||
UserName: "belm",
|
UserName: "belm",
|
||||||
Email: "nosbelm@qq.com",
|
Email: "nosbelm@qq.com",
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.5 接口命名
|
### 2.5 Interface Naming
|
||||||
|
|
||||||
- 接口命名的规则,基本和结构体命名规则保持一致:
|
- The interface naming rules are basically consistent with the structure naming rules:
|
||||||
- 单个函数的接口名以 “er"”作为后缀(例如Reader,Writer),有时候可能导致蹩脚的英文,但是没关系。
|
- Interface names of individual functions suffixed with "er"" (e.g. Reader, Writer) can sometimes lead to broken English, but that's okay.
|
||||||
- 两个函数的接口名以两个函数名命名,例如ReadWriter。
|
- The interface name of the two functions is named after the two function names, eg ReadWriter.
|
||||||
- 三个以上函数的接口名,类似于结构体名。
|
- An interface name for more than three functions, similar to a structure name.
|
||||||
|
|
||||||
例如:
|
For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
// Seeking to an offset before the start of the file is an error.
|
// Seeking to an offset before the start of the file is an error.
|
||||||
// Seeking to any positive offset is legal, but the behavior of subsequent
|
// Seeking to any positive offset is legal, but the behavior of subsequent
|
||||||
// I/O operations on the underlying object is implementation-dependent.
|
// I/O operations on the underlying object are implementation-dependent.
|
||||||
type Seeker interface {
|
type Seeker interface {
|
||||||
Seek(offset int64, whence int) (int64, error)
|
Seek(offset int64, whence int) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadWriter is the interface that groups the basic Read and Write methods.
|
// ReadWriter is the interface that groups the basic Read and Write methods.
|
||||||
type ReadWriter interface {
|
type ReadWriter interface {
|
||||||
Reader
|
reader
|
||||||
Writer
|
Writer
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.6 变量命名
|
### 2.6 Variable Naming
|
||||||
|
|
||||||
- 变量名必须遵循驼峰式,首字母根据访问控制决定使用大写或小写。
|
- Variable names must follow camel case, and the initial letter is uppercase or lowercase according to the access control decision.
|
||||||
- 在相对简单(对象数量少、针对性强)的环境中,可以将一些名称由完整单词简写为单个字母,例如:
|
- In relatively simple (few objects, highly targeted) environments, some names can be abbreviated from full words to single letters, for example:
|
||||||
- user 可以简写为 u;
|
- user can be abbreviated as u;
|
||||||
- userID 可以简写 uid。
|
- userID can be abbreviated as uid.
|
||||||
- 特有名词时,需要遵循以下规则:
|
- When using proper nouns, the following rules need to be followed:
|
||||||
- 如果变量为私有,且特有名词为首个单词,则使用小写,如 apiClient。
|
- If the variable is private and the proper noun is the first word, use lowercase, such as apiClient.
|
||||||
- 其他情况都应当使用该名词原有的写法,如 APIClient、repoID、UserID。
|
- In other cases, the original wording of the noun should be used, such as APIClient, repoID, UserID.
|
||||||
|
|
||||||
下面列举了一些常见的特有名词。
|
Some common nouns are listed below.
|
||||||
|
|
||||||
```
|
```
|
||||||
// A GonicMapper that contains a list of common initialisms taken from golang/lint
|
// A GonicMapper that contains a list of common initialisms taken from golang/lint
|
||||||
@@ -420,7 +413,7 @@ var LintGonicMapper = GonicMapper{
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- 若变量类型为bool类型,则名称应以Has,Is,Can或Allow开头,例如:
|
- If the variable type is bool, the name should start with Has, Is, Can or Allow, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var has Conflict bool
|
var has Conflict bool
|
||||||
@@ -429,13 +422,13 @@ var canManage bool
|
|||||||
var allowGitHook bool
|
var allowGitHook bool
|
||||||
```
|
```
|
||||||
|
|
||||||
- 局部变量应当尽可能短小,比如使用buf指代buffer,使用i指代index。
|
- Local variables should be as short as possible, for example, use buf to refer to buffer, and use i to refer to index.
|
||||||
- 代码生成工具自动生成的代码可排除此规则(如`xxx.pb.go`里面的Id)
|
- The code automatically generated by the code generation tool can exclude this rule (such as the Id in `xxx.pb.go`)
|
||||||
|
|
||||||
### 2.7 常量命名
|
### 2.7 Constant naming
|
||||||
|
|
||||||
- 常量名必须遵循驼峰式,首字母根据访问控制决定使用大写或小写。
|
- The constant name must follow the camel case, and the initial letter is uppercase or lowercase according to the access control decision.
|
||||||
- 如果是枚举类型的常量,需要先创建相应类型:
|
- If it is a constant of enumeration type, you need to create the corresponding type first:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Code defines an error code type.
|
// Code defines an error code type.
|
||||||
@@ -450,9 +443,9 @@ const (
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.8 Error的命名
|
### 2.8 Error naming
|
||||||
|
|
||||||
- Error类型应该写成FooError的形式。
|
- The Error type should be written in the form of FooError.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type ExitError struct {
|
type ExitError struct {
|
||||||
@@ -460,18 +453,18 @@ type ExitError struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- Error变量写成ErrFoo的形式。
|
- The Error variable is written in the form of ErrFoo.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var ErrFormat = errors. New("unknown format")
|
var ErrFormat = errors. New("unknown format")
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. 注释规范
|
## 3. Comment specification
|
||||||
|
|
||||||
- 每个可导出的名字都要有注释,该注释对导出的变量、函数、结构体、接口等进行简要介绍。
|
- Each exportable name must have a comment, which briefly introduces the exported variables, functions, structures, interfaces, etc.
|
||||||
- 全部使用单行注释,禁止使用多行注释。
|
- All single-line comments are used, and multi-line comments are prohibited.
|
||||||
- 和代码的规范一样,单行注释不要过长,禁止超过 120 字符,超过的请使用换行展示,尽量保持格式优雅。
|
- Same as the code specification, single-line comments should not be too long, and no more than 120 characters are allowed. If it exceeds, please use a new line to display, and try to keep the format elegant.
|
||||||
- 注释必须是完整的句子,以需要注释的内容作为开头,句点作为结尾,`格式为 // 名称 描述.`。例如:
|
- A comment must be a complete sentence, starting with the content to be commented and ending with a period, `the format is // name description.`. For example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -487,9 +480,9 @@ func PrintFlags(flags *pflag.FlagSet) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- 所有注释掉的代码在提交code review前都应该被删除,否则应该说明为什么不删除,并给出后续处理建议。
|
- All commented out code should be deleted before submitting code review, otherwise, it should explain why it is not deleted, and give follow-up processing suggestions.
|
||||||
|
|
||||||
- 在多段注释之间可以使用空行分隔加以区分,如下所示:
|
- Multiple comments can be separated by blank lines, as follows:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Package superman implements methods for saving the world.
|
// Package superman implements methods for saving the world.
|
||||||
@@ -499,10 +492,10 @@ func PrintFlags(flags *pflag.FlagSet) {
|
|||||||
package superman
|
package superman
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.1 包注释
|
### 3.1 Package Notes
|
||||||
|
|
||||||
- 每个包都有且仅有一个包级别的注释。
|
- Each package has one and only one package-level annotation.
|
||||||
- 包注释统一用 // 进行注释,格式为 `// Package 包名 包描述`,例如:
|
- Package comments are uniformly commented with // in the format of `// Package package name package description`, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Package genericclioptions contains flags which can be added to you command, bound, completed, and produce
|
// Package genericclioptions contains flags which can be added to you command, bound, completed, and produce
|
||||||
@@ -510,15 +503,15 @@ package superman
|
|||||||
package genericclioptions
|
package genericclioptions
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.2 变量/常量注释
|
### 3.2 Variable/Constant Comments
|
||||||
|
|
||||||
- 每个可导出的变量/常量都必须有注释说明,`格式为// 变量名 变量描述`,例如:
|
- Each variable/constant that can be exported must have a comment description, `the format is // variable name variable description`, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// ErrSigningMethod defines invalid signing method error.
|
// ErrSigningMethod defines invalid signing method error.
|
||||||
var ErrSigningMethod = errors. New("Invalid signing method")
|
var ErrSigningMethod = errors. New("Invalid signing method")
|
||||||
```
|
```
|
||||||
- 出现大块常量或变量定义时,可在前面注释一个总的说明,然后在每一行常量的前一行或末尾详细注释该常量的定义,例如:
|
- When there is a large block of constant or variable definition, you can comment a general description in front, and then comment the definition of the constant in detail before or at the end of each line of constant, for example:
|
||||||
```go
|
```go
|
||||||
// Code must start with 1xxxxx.
|
// Code must start with 1xxxxx.
|
||||||
const (
|
const (
|
||||||
@@ -535,10 +528,10 @@ const (
|
|||||||
ErrValidation
|
ErrValidation
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
### 3.3 结构体注释
|
### 3.3 Structure Annotation
|
||||||
|
|
||||||
- 每个需要导出的结构体或者接口都必须有注释说明,格式为 `// 结构体名 结构体描述.`。
|
- Each structure or interface that needs to be exported must have a comment description, the format is `// structure name structure description.`.
|
||||||
- 结构体内的可导出成员变量名,如果意义不明确,必须要给出注释,放在成员变量的前一行或同一行的末尾。例如:
|
- The name of the exportable member variable in the structure, if the meaning is not clear, a comment must be given and placed before the member variable or at the end of the same line. For example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// User represents a user restful resource. It is also used as gorm model.
|
// User represents a user restful resource. It is also used as gorm model.
|
||||||
@@ -554,9 +547,9 @@ type User struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.4 方法注释
|
### 3.4 Method Notes
|
||||||
|
|
||||||
每个需要导出的函数或者方法都必须有注释,格式为// 函数名 函数描述.,例如:
|
Each function or method that needs to be exported must have a comment, the format is // function name function description., for examplelike:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// BeforeUpdate run before update database record.
|
// BeforeUpdate run before update database record.
|
||||||
@@ -566,20 +559,20 @@ func (p *Policy) BeforeUpdate() (err error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.5 类型注释
|
### 3.5 Type annotations
|
||||||
|
|
||||||
- 每个需要导出的类型定义和类型别名都必须有注释说明,格式为 `// 类型名 类型描述.`,例如:
|
- Each type definition and type alias that needs to be exported must have a comment description, the format is `// type name type description.`, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Code defines an error code type.
|
// Code defines an error code type.
|
||||||
type Code int
|
type Code int
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4. 类型
|
## 4. Type
|
||||||
|
|
||||||
### 4.1 字符串
|
### 4.1 Strings
|
||||||
|
|
||||||
- 空字符串判断。
|
- Empty string judgment.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -593,7 +586,7 @@ if len(s) == 0 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `[]byte`/`string`相等比较。
|
- `[]byte`/`string` equality comparison.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -611,7 +604,7 @@ bytes.Compare(s1, s2) == 0
|
|||||||
bytes. Compare(s1, s2) != 0
|
bytes. Compare(s1, s2) != 0
|
||||||
```
|
```
|
||||||
|
|
||||||
- 复杂字符串使用raw字符串避免字符转义。
|
- Complex strings use raw strings to avoid character escaping.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -621,9 +614,9 @@ regexp.MustCompile("\\.")
|
|||||||
regexp.MustCompile(`\.`)
|
regexp.MustCompile(`\.`)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.2 切片
|
### 4.2 Slicing
|
||||||
|
|
||||||
- 空slice判断。
|
- Empty slice judgment.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -637,9 +630,9 @@ if slice != nil && len(slice) == 0 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
上面判断同样适用于map、channel。
|
The above judgment also applies to map and channel.
|
||||||
|
|
||||||
- 声明slice。
|
- Declare a slice.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -650,7 +643,7 @@ s := make([]string, 0)
|
|||||||
var s[]string
|
var s[]string
|
||||||
```
|
```
|
||||||
|
|
||||||
- slice复制。
|
- slice copy.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -666,7 +659,7 @@ for i := range b1 {
|
|||||||
copy(b2, b1)
|
copy(b2, b1)
|
||||||
```
|
```
|
||||||
|
|
||||||
- slice新增。
|
- slice added.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -680,16 +673,16 @@ var a, b []int
|
|||||||
b = append(b, a...)
|
b = append(b, a...)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.3 结构体
|
### 4.3 Structure
|
||||||
|
|
||||||
- struct初始化。
|
- struct initialization.
|
||||||
|
|
||||||
struct以多行格式初始化。
|
The struct is initialized in multi-line format.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type user struct {
|
type user struct {
|
||||||
Id int64
|
Id int64
|
||||||
Name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
u1 := user{100, "Colin"}
|
u1 := user{100, "Colin"}
|
||||||
@@ -700,11 +693,11 @@ u2 := user{
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 5. 控制结构
|
## 5. Control Structure
|
||||||
|
|
||||||
### 5.1 if
|
### 5.1 if
|
||||||
|
|
||||||
- if 接受初始化语句,约定如下方式建立局部变量。
|
- if accepts the initialization statement, the convention is to create local variables in the following way.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
if err := loadConfig(); err != nil {
|
if err := loadConfig(); err != nil {
|
||||||
@@ -713,7 +706,7 @@ if err := loadConfig(); err != nil {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- if 对于bool类型的变量,应直接进行真假判断。
|
- if For variables of bool type, true and false judgments should be made directly.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var isAllow bool
|
var isAllow bool
|
||||||
@@ -724,7 +717,7 @@ if isAllow {
|
|||||||
|
|
||||||
### 5.2 for
|
### 5.2 for
|
||||||
|
|
||||||
- 采用短声明建立局部变量。
|
- Create local variables using short declarations.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
sum := 0
|
sum := 0
|
||||||
@@ -733,7 +726,7 @@ for i := 0; i < 10; i++ {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- 不要在 for 循环里面使用 defer,defer只有在函数退出时才会执行。
|
- Don't use defer in for loop, defer will only be executed when the function exits.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// bad
|
// bad
|
||||||
@@ -761,7 +754,7 @@ for file := range files {
|
|||||||
|
|
||||||
### 5.3 range
|
### 5.3 range
|
||||||
|
|
||||||
- 如果只需要第一项(key),就丢弃第二个。
|
- If only the first item (key) is needed, discard the second.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
for key := range keys {
|
for key := range keys {
|
||||||
@@ -769,7 +762,7 @@ for key := range keys {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- 如果只需要第二项,则把第一项置为下划线。
|
- If only the second item is required, underline the first item.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
sum := 0
|
sum := 0
|
||||||
@@ -780,7 +773,7 @@ for _, value := range array {
|
|||||||
|
|
||||||
### 5.4 switch
|
### 5.4 switch
|
||||||
|
|
||||||
- 必须要有default。
|
- must have default.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
switch os := runtime.GOOS; os {
|
switch os := runtime.GOOS; os {
|
||||||
@@ -794,37 +787,37 @@ switch os := runtime.GOOS; os {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 5.5 goto
|
### 5.5 goto
|
||||||
- 业务代码禁止使用 goto 。
|
- Business code prohibits the use of goto.
|
||||||
- 框架或其他底层源码尽量不用。
|
- Try not to use frameworks or other low-level source code.
|
||||||
|
|
||||||
## 6. 函数
|
## 6. Functions
|
||||||
|
|
||||||
- 传入变量和返回变量以小写字母开头。
|
- Incoming variables and return variables start with a lowercase letter.
|
||||||
- 函数参数个数不能超过5个。
|
- The number of function parameters cannot exceed 5.
|
||||||
- 函数分组与顺序
|
- Function grouping and ordering
|
||||||
- 函数应按粗略的调用顺序排序。
|
- Functions should be sorted in rough calling order.
|
||||||
- 同一文件中的函数应按接收者分组。
|
- Functions in the same file should be grouped by receiver.
|
||||||
- 尽量采用值传递,而非指针传递。
|
- Try to use value transfer instead of pointer transfer.
|
||||||
- 传入参数是 map、slice、chan、interface ,不要传递指针。
|
- The incoming parameters are map, slice, chan, interface, do not pass pointers.
|
||||||
|
|
||||||
### 6.1 函数参数
|
### 6.1 Function parameters
|
||||||
|
|
||||||
- 如果函数返回相同类型的两个或三个参数,或者如果从上下文中不清楚结果的含义,使用命名返回,其他情况不建议使用命名返回,例如:
|
- If the function returns two or three arguments of the same type, or if the meaning of the result is not clear from the context, use named returns, otherwise it is not recommended to use named returns, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func coordinate() (x, y float64, err error) {
|
func coordinate() (x, y float64, err error) {
|
||||||
// normal code
|
// normal code
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- 传入变量和返回变量都以小写字母开头。
|
- Both incoming and returned variables start with a lowercase letter.
|
||||||
- 尽量用值传递,非指针传递。
|
- Try to pass by value instead of pointer.
|
||||||
- 参数数量均不能超过5个。
|
- The number of parameters cannot exceed 5.
|
||||||
- 多返回值最多返回三个,超过三个请使用 struct。
|
- Multiple return values can return up to three, and if there are more than three, please use struct.
|
||||||
|
|
||||||
### 6.2 defer
|
### 6.2 defer
|
||||||
|
|
||||||
- 当存在资源创建时,应紧跟defer释放资源(可以大胆使用defer,defer在Go1.14版本中,性能大幅提升,defer的性能损耗即使在性能敏感型的业务中,也可以忽略)。
|
- When resources are created, resources should be released immediately after defer (defer can be used boldly, the performance of defer is greatly improved in Go1.14 version, and the performance loss of defer can be ignored even in performance-sensitive businesses).
|
||||||
- 先判断是否错误,再defer释放资源,例如:
|
- First judge whether there is an error, and then defer to release resources, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
rep, err := http. Get(url)
|
rep, err := http. Get(url)
|
||||||
@@ -835,46 +828,46 @@ if err != nil {
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6.3 方法的接收器
|
### 6.3 Method Receiver
|
||||||
|
|
||||||
- 推荐以类名第一个英文首字母的小写作为接收器的命名。
|
- It is recommended to use the lowercase of the first English letter of the class name as the name of the receiver.
|
||||||
- 接收器的命名在函数超过20行的时候不要用单字符。
|
- Don't use a single character in the name of the receiver when the function exceeds 20 lines.
|
||||||
- 接收器的命名不能采用me、this、self这类易混淆名称。
|
- The name of the receiver cannot use confusing names such as me, this, and self.
|
||||||
|
|
||||||
### 6.4 嵌套
|
### 6.4 Nesting
|
||||||
- 嵌套深度不能超过4层。
|
- The nesting depth cannot exceed 4 levels.
|
||||||
|
|
||||||
### 6.5 变量命名
|
### 6.5 Variable Naming
|
||||||
- 变量声明尽量放在变量第一次使用的前面,遵循就近原则。
|
- The variable declaration should be placed before the first use of the variable as far as possible, following the principle of proximity.
|
||||||
- 如果魔法数字出现超过两次,则禁止使用,改用一个常量代替,例如:
|
- If the magic number appears more than twice, it is forbidden to use it and use a constant instead, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// PI...
|
// PI...
|
||||||
const Prise = 3.14
|
const Price = 3.14
|
||||||
|
|
||||||
func getAppleCost(n float64) float64 {
|
func getAppleCost(n float64) float64 {
|
||||||
return Prise * n
|
return Price * n
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOrangeCost(n float64) float64 {
|
func getOrangeCost(n float64) float64 {
|
||||||
return Prise * n
|
return Price * n
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 7. GOPATH 设置规范
|
## 7. GOPATH setting specification
|
||||||
- Go 1.11 之后,弱化了 GOPATH 规则,已有代码(很多库肯定是在1.11之前建立的)肯定符合这个规则,建议保留 GOPATH 规则,便于维护代码。
|
- After Go 1.11, the GOPATH rule has been weakened. Existing code (many libraries must have been created before 1.11) must conform to this rule. It is recommended to keep the GOPATH rule to facilitate code maintenance.
|
||||||
- 建议只使用一个 GOPATH,不建议使用多个 GOPATH。如果使用多个GOPATH,编译生效的 bin 目录是在第一个 GOPATH 下。
|
- Only one GOPATH is recommended, multiple GOPATHs are not recommended. If multiple GOPATHs are used, the bin directory where compilation takes effect is under the first GOPATH.
|
||||||
|
|
||||||
## 8. 依赖管理
|
## 8. Dependency Management
|
||||||
|
|
||||||
- Go 1.11 以上必须使用 Go Modules。
|
- Go 1.11 and above must use Go Modules.
|
||||||
- 使用Go Modules作为依赖管理的项目时,不建议提交vendor目录。
|
- When using Go Modules as a dependency management project, it is not recommended to submit the vendor directory.
|
||||||
- 使用Go Modules作为依赖管理的项目时,必须提交go.sum文件。
|
- When using Go Modules as a dependency management project, the go.sum file must be submitted.
|
||||||
|
|
||||||
### 9. 最佳实践
|
### 9. Best Practices
|
||||||
|
|
||||||
- 尽量少用全局变量,而是通过参数传递,使每个函数都是“无状态”的。这样可以减少耦合,也方便分工和单元测试。
|
- Minimize the use of global variables, but pass parameters, so that each function is "stateless". This reduces coupling and facilitates division of labor and unit testing.
|
||||||
- 在编译时验证接口的符合性,例如:
|
- Verify interface compliance at compile time, for example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type LogHandler struct {
|
type LogHandler struct {
|
||||||
@@ -883,19 +876,15 @@ type LogHandler struct {
|
|||||||
}
|
}
|
||||||
var_http.Handler = LogHandler{}
|
var_http.Handler = LogHandler{}
|
||||||
```
|
```
|
||||||
- 服务器处理请求时,应该创建一个context,保存该请求的相关信息(如requestID),并在函数调用链中传递。
|
- When the server processes a request, it should create a context, save the relevant information of the request (such as requestID), and pass it in the function call chain.
|
||||||
|
|
||||||
### 9.1 性能
|
### 9.1 Performance
|
||||||
- string 表示的是不可变的字符串变量,对 string 的修改是比较重的操作,基本上都需要重新申请内存。所以,如果没有特殊需要,需要修改时多使用 []byte。
|
- string represents an immutable string variable, modifying string is a relatively heavy operation, and basically needs to re-apply for memory. Therefore, if there is no special need, use []byte more when you need to modify.
|
||||||
- 优先使用 strconv 而不是 fmt。
|
- Prefer strconv over fmt.
|
||||||
|
|
||||||
### 9.2 注意事项
|
### 9.2 Precautions
|
||||||
|
|
||||||
- append 要小心自动分配内存,append 返回的可能是新分配的地址。
|
- append Be careful about automatically allocating memory, append may return a newly allocated address.
|
||||||
- 如果要直接修改 map 的 value 值,则 value 只能是指针,否则要覆盖原来的值。
|
- If you want to directly modify the value of the map, the value can only be a pointer, otherwise the original value must be overwritten.
|
||||||
- map 在并发中需要加锁。
|
- map needs to be locked during concurrency.
|
||||||
- 编译过程无法检查 interface{} 的转换,只能在运行时检查,小心引起 panic。
|
- The conversion of interface{} cannot be checked during compilation, it can only be checked at runtime, be careful to cause panic.
|
||||||
|
|
||||||
## 总结
|
|
||||||
|
|
||||||
这里向你介绍了九类常用的编码规范。但今天的最后,我要在这里提醒你一句:规范是人定的,你也可以根据需要,制定符合你项目的规范,但同时我也建议你采纳这些业界沉淀下来的规范,并通过工具来确保规范的执行。
|
|
||||||
|
|||||||
+65
-42
@@ -1,76 +1,88 @@
|
|||||||
# OpenIM Branch Management and Versioning
|
# OpenIM Branch Management and Versioning: A Blueprint for High-Grade Software Development
|
||||||
|
|
||||||
Our project, OpenIM, follows the [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/) standards.
|
[📚 **OpenIM TOC**](#openim-branch-management-and-versioning-a-blueprint-for-high-grade-software-development)
|
||||||
|
- [Unfolding the Mechanism of OpenIM Version Maintenance](#unfolding-the-mechanism-of-openim-version-maintenance)
|
||||||
|
- [Main Branch: The Heart of OpenIM Development](#main-branch-the-heart-of-openim-development)
|
||||||
|
- [Release Branch: The Beacon of Stability](#release-branch-the-beacon-of-stability)
|
||||||
|
- [Tag Management: The Cornerstone of Version Control](#tag-management-the-cornerstone-of-version-control)
|
||||||
|
- [Release Management: A Guided Tour](#release-management-a-guided-tour)
|
||||||
|
- [Milestones, Branching, and Addressing Major Bugs](#milestones-branching-and-addressing-major-bugs)
|
||||||
|
- [Applying Principles: A Git Workflow Example](#applying-principles-a-git-workflow-example)
|
||||||
|
- [Docker Images Version Management](#docker-images-version-management)
|
||||||
|
|
||||||
OpenIM, the open source project, employs a comprehensive version management system to ensure the reliability and traceability of our software. Our version management consists of three main components: the `main` branch, the `release` branch, and `tag` management.
|
|
||||||
|
|
||||||
## Main Branch
|
At OpenIM, we acknowledge the profound impact of implementing a robust and efficient version management system, hence we abide by the established standards of [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/).
|
||||||
|
|
||||||
The `main` branch is where all the latest code resides. It's the hub of activity, embodying all the cutting-edge features that are currently being developed or updated. However, since it's subject to frequent changes and updates, it may not always represent the most stable version of the software. Access the `main` branch [here](https://github.com/OpenIMSDK/Open-IM-Server/tree/main).
|
Our software blueprint orchestrates a tripartite version management system that integrates the `main` branch, the `release` branch, and `tag` management. These constituents operate in synchrony to preserve the reliability and traceability of our software across various stages of development.
|
||||||
|
|
||||||
## Release Branch
|
## Unfolding the Mechanism of OpenIM Version Maintenance
|
||||||
|
|
||||||
On the other hand, we have the `release` branch. For instance, in the context of version 3.1, we maintain a `release-v3.1` branch. Unlike the `main` branch, the release branch is designed to be a continuously stable and updated version of the software. This provides a reliable option for users who prefer stability over the latest, but potentially unstable, features. Access the `release-v3.1` branch [here](https://github.com/OpenIMSDK/Open-IM-Server/tree/release-v3.1).
|
Our version maintenance protocol revolves around two primary branches, namely: `main` and `release`. We resort to Semantic Versioning 2.0.0 for marking distinctive versions of our software, representing substantial milestones in its evolution.
|
||||||
|
|
||||||
## Tag Management
|
In the OpenIM repository, version identification strictly complies with the `MAJOR.MINOR.PATCH` protocol. Herein:
|
||||||
|
|
||||||
In addition to the `main` and `release` branches, `tag` also plays a pivotal role in version control. Tags are immutable, meaning once they're created, they remain unchanged. Therefore, if you need a specific version of the software, you can use the corresponding tag. All of our available tags can be viewed [here](https://github.com/OpenIMSDK/Open-IM-Server/tags).
|
- The `MAJOR` version indicates a shift arising from incompatible changes to the API.
|
||||||
|
- The `MINOR` version suggests the addition of features in a backward-compatible manner.
|
||||||
|
- The `PATCH` version flags backward-compatible bug fixes.
|
||||||
|
|
||||||
Moreover, our Docker image versions are closely tied with these three components. For example, a tag might correspond to the Docker image `ghcr.io/openimsdk/openim-server:v3.1.0`, a release might be represented as `ghcr.io/openimsdk/openim-server:release-v3.0`, and the main branch could be represented as `ghcr.io/openimsdk/openim-server:main` or `ghcr.io/openimsdk/openim-server:latest`.
|
## Main Branch: The Heart of OpenIM Development
|
||||||
|
|
||||||
Here is the specification of our version numbers:
|
The `main` branch is the operational heart of our development process. Housing the most recent and advanced features, this branch serves as the nerve center for all enhancements and updates. It encapsulates the freshest, though possibly unstable, facets of the software. Visit our `main` branch [here](https://github.com/OpenIMSDK/Open-IM-Server/tree/main).
|
||||||
|
|
||||||
- **Revision version number**: The third digit of the version number, representing bug fixes or code optimizations, usually no new features are added and it is backward compatible with older versions.
|
## Release Branch: The Beacon of Stability
|
||||||
|
|
||||||
- **Build version number**: Usually automatically generated by the system, every code submission will result in an automatic increment by 1.
|
For every major release, we curate a corresponding `release` branch, e.g., `release-v3.1`. This branch symbolizes an embodiment of stability and ensures an updated version of the software, providing a dependable option for users favoring stability over nascent, yet possibly unstable, features. Visit the `release-v3.1` branch [here](https://github.com/OpenIMSDK/Open-IM-Server/tree/release-v3.1).
|
||||||
|
|
||||||
- Version modifiers
|
## Tag Management: The Cornerstone of Version Control
|
||||||
|
|
||||||
: These can represent the development stage and stability of the software. Common ones include:
|
In OpenIM's version control system, the role of `tags` stands paramount. Owing to their immutable nature, tags can be effectively utilized to retrieve a specific version of the software. Explore our library of tags [here](https://github.com/OpenIMSDK/Open-IM-Server/tags).
|
||||||
|
|
||||||
- `alpha`: An internal testing version with many bugs, generally used for communication among developers.
|
Our Docker image versions are intimately entwined with these tripartite components. For instance, a Docker image tag may correspond to `ghcr.io/openimsdk/openim-server:v3.1.0`, a release to `ghcr.io/openimsdk/openim-server:release-v3.0`, and the main branch to `ghcr.io/openimsdk/openim-server:main` or `ghcr.io/openimsdk/openim-server:latest`.
|
||||||
- `beta`: A test version with many bugs, generally used for testing by eager community members, who provide feedback to the developers.
|
|
||||||
- `rc`: Release candidate, to be released as the official version, it's the last test version before the official version.
|
To further clarify, the semantics of our version numbers are as follows:
|
||||||
|
|
||||||
|
- **Revision version number**: This represents bug fixes or code optimizations. Typically, it entails no new feature additions and ensures backward compatibility.
|
||||||
|
- **Build version number**: Auto-generated by the system, each code submission prompts an automatic increment by 1.
|
||||||
|
- **Version modifiers**: These hint at the software's development stage and stability. Some commonly used modifiers are `alpha`, `beta`, `rc`, `ga`, `r/release/or nothing`, and `lts`.
|
||||||
|
- `alpha`: An internal testing version with numerous bugs, typically used for communication among developers.
|
||||||
|
- `beta`: A test version with numerous bugs, generally used for testing by eager community members, who provide feedback to the developers.
|
||||||
|
- `rc`: Release candidate, which is to be released as the official version. It's the last test version before the official version.
|
||||||
- `ga`: General Availability, the first stable release.
|
- `ga`: General Availability, the first stable release.
|
||||||
- `r/release/or nothing`: The final release version, intended for general users.
|
- `r/release/or nothing`: The final release version, intended for general users.
|
||||||
- `lts`: Long Term Support, the official will specify the maintenance year for this version and will fix all bugs found in this version.
|
- `lts`: Long Term Support, the official will specify the maintenance year for this version and will fix all bugs discovered in this version.
|
||||||
|
|
||||||
When adding partial functions to the project, the minor version number increases by 1, and the revision version number resets to 0. When there are major changes in the project, the major version number increases by 1. The build number is generally automatically generated by the compiler during the compilation process, only the format needs to be defined, and it does not need to be manually controlled.
|
Whenever a project undergoes a partial functional addition, the minor version number increments by 1, resetting the revision version number to 0. In contrast, any major project overhaul results in an increment by 1 in the major version number. The build number, typically auto-generated during the compilation process, only requires format definition, thereby eliminating manual control.
|
||||||
|
|
||||||
## OpenIM version
|
## Release Management: A Guided Tour
|
||||||
|
|
||||||
OpenIM manages two primary branches: `main` and `release`. The project uses Semantic Versioning 2.0.0 to tag different versions of the software, each indicating a significant milestone in the software's development.
|
Our GitHub repository at https://github.com/OpenIMSDK/Open-IM-Server/releases associates a release with each tag, with a distinction between Pre-release and Latest, determined by the branch source. Every significant feature launch prompts the issue of a `release` branch, such as `release-v3.2`, as a beacon of stability and Latest release.
|
||||||
|
|
||||||
In the OpenIM repository, the versioning adheres to the `MAJOR.MINOR.PATCH` format, where:
|
Pre-releases correspond to releases from the `main` branch, denoting tags with Version modifiers such as `v3.2.1-beta.0`, `v3.2.1-rc.1`, etc. If you are seeking the most recent, albeit possibly unstable, release with new features, these tags, originating from the latest `main` branch code, are your go-to.
|
||||||
|
|
||||||
- `MAJOR` version changes when there are incompatible changes to the API,
|
Conversely, if stability is your primary concern, you should opt for the release tagged Latest, denoted by tags without Version modifiers, such as `v3.2.1`, `v3.2.2` etc. These tags are linked to the latest stable maintenance branch, like `release-v3.2`.
|
||||||
- `MINOR` version changes when features are added in a backward-compatible manner, and
|
|
||||||
- `PATCH` version changes when backward-compatible bugs are fixed.
|
|
||||||
|
|
||||||
## Milestones and Branching
|
## Milestones, Branching, and Addressing Major Bugs
|
||||||
|
|
||||||
|
**About:**
|
||||||
|
|
||||||
+ [OpenIM Milestones](https://github.com/OpenIMSDK/Open-IM-Server/milestones)
|
+ [OpenIM Milestones](https://github.com/OpenIMSDK/Open-IM-Server/milestones)
|
||||||
+ [OpenIM Tags](https://github.com/OpenIMSDK/Open-IM-Server/tags)
|
+ [OpenIM Tags](https://github.com/OpenIMSDK/Open-IM-Server/tags)
|
||||||
+ [OpenIM Branches](https://github.com/OpenIMSDK/Open-IM-Server/branches)
|
+ [OpenIM Branches](https://github.com/OpenIMSDK/Open-IM-Server/branches)
|
||||||
|
|
||||||
When a significant milestone like v3.1.0 is achieved, a new branch `release-v3.1` is created. This branch contains all the code pertaining to this stable release. All bug fixes and features intended for the next version, v3.2.0, are merged into this branch.
|
We create a new branch, such as `release-v3.1`, for each significant milestone (e.g., v3.1.0), housing all relevant code for that release. All enhancements and bug fixes targeting the subsequent version (e.g., v3.2.0) are integrated into this branch.
|
||||||
|
|
||||||
The release of `PATCH` versions (Z in `X.Y.Z`) are driven by bug fixes, and these can be rolled out depending on the bug's priority or over a scheduled time. On the other hand, `MINOR` versions (Y in `X.Y.Z`) are released based on the project's roadmap, milestone completion, or on a scheduled timeline. Importantly, the API of minor versions is always backward-compatible.
|
`PATCH` versions (represented by Z in `X.Y.Z`) are primarily propelled by bug fixes, and their release may be either priority-driven or scheduled. In contrast, `MINOR` versions (represented by Y in `X.Y.Z`) are contingent upon the project's roadmap, milestone completion, or a pre-established timeline, always maintaining backward-compatible APIs.
|
||||||
|
|
||||||
## Dealing with Major Bugs
|
When dealing with major bugs, we selectively merge the fix into the affected version (e.g., v3.1 or the `release-v3.1` branch), as well as the `main` branch. This dual pronged strategy ensures that users on older versions receive crucial bug fixes, while also keeping the `main` branch updated.
|
||||||
|
|
||||||
In the event of a major bug discovery, the fix would selectively be merged into the previous version (e.g., v3.1 or the `release-v3.1` branch), as well as into the `main` branch. This is to ensure that users relying on the older version can still receive important bug fixes, while also keeping the main branch updated.
|
We reinforce our approach to branch management and versioning with stringent testing protocols. Automated tests and code review sessions form vital components of maintaining a robust and reliable codebase.
|
||||||
|
|
||||||
It's worth noting that a robust testing regime should be in place to ensure the integrity of all branches at any given time. Automated tests and code review sessions are crucial components of maintaining a healthy codebase.
|
## Applying Principles: A Git Workflow Example
|
||||||
|
|
||||||
To summarize, OpenIM's approach to branch management and versioning ensures a balance between introducing new features, fixing bugs, and maintaining backward compatibility. This strategy is vital for managing user expectations, supporting older versions, and paving the way for the project's continuous growth.
|
The workflow to address a bug fix might follow these steps:
|
||||||
|
|
||||||
## Git Workflow Example
|
```bash
|
||||||
|
bashCopy codebashCopy code# Checkout the branch for the version that needs the bug fix
|
||||||
To put the above principles into practice, here's a Git workflow example that you might follow when working on a bug fix:
|
|
||||||
|
|
||||||
```
|
|
||||||
bashCopy code# Checkout the branch for the version that needs the bug fix
|
|
||||||
git checkout release-v3.1
|
git checkout release-v3.1
|
||||||
|
|
||||||
# Create a new branch for the bug fix
|
# Create a new branch for the bug fix
|
||||||
@@ -92,10 +104,21 @@ git merge release-v3.1
|
|||||||
# Push the updates to the main branch
|
# Push the updates to the main branch
|
||||||
git push origin main
|
git push origin main
|
||||||
```
|
```
|
||||||
|
## Release Process
|
||||||
|
|
||||||
Remember, communication with your team is key throughout this process, keeping everyone up-to-date with the changes being made.
|
```
|
||||||
|
Publishing v3.2.0: A Step-by-Step Guide
|
||||||
|
(1) Create the tag v3.2.0-alpha.0 from the main branch.
|
||||||
|
(2) Bugs are fixed on the main branch. Once the bugs are resolved, tag the main branch as v3.2.0-rc.0.
|
||||||
|
(3) After further testing, if v3.2.0-rc.0 is deemed stable, create a branch named release-v3.2 from the tag v3.2.0-rc.0.
|
||||||
|
(4) From the release-v3.2 branch, create the tag v3.2.0. At this point, the official release of v3.2.0 is complete.
|
||||||
|
|
||||||
|
After the release of v3.2.0, if urgent bugs are discovered, fix them on the release-v3.2 branch. Then, submit two pull requests (PRs) to both the main and release-v3.2 branches. Tag the release-v3.2 branch as v3.2.1.
|
||||||
|
```
|
||||||
|
|
||||||
## Docker images version management
|
Throughout this process, active communication within the team is pivotal to maintaining transparency and consensus on changes.
|
||||||
|
|
||||||
|
## Docker Images Version Management
|
||||||
|
|
||||||
|
For more details on managing Docker image versions, visit [OpenIM Docker Images Administration](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md).
|
||||||
|
|
||||||
+ [OpenIM Docker Images Administration](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md)
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ require (
|
|||||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||||
github.com/dtm-labs/rockscache v0.1.1
|
github.com/dtm-labs/rockscache v0.1.1
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
github.com/go-playground/validator/v10 v10.14.1
|
github.com/go-playground/validator/v10 v10.15.0
|
||||||
github.com/gogo/protobuf v1.3.2
|
github.com/gogo/protobuf v1.3.2
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||||
github.com/golang/protobuf v1.5.3
|
github.com/golang/protobuf v1.5.3
|
||||||
@@ -25,19 +25,19 @@ require (
|
|||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
go.mongodb.org/mongo-driver v1.12.1
|
go.mongodb.org/mongo-driver v1.12.1
|
||||||
golang.org/x/image v0.9.0 // indirect
|
golang.org/x/image v0.11.0
|
||||||
google.golang.org/api v0.134.0
|
google.golang.org/api v0.136.0
|
||||||
google.golang.org/grpc v1.57.0
|
google.golang.org/grpc v1.57.0
|
||||||
google.golang.org/protobuf v1.31.0
|
google.golang.org/protobuf v1.31.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gorm.io/driver/mysql v1.5.1
|
gorm.io/driver/mysql v1.5.1
|
||||||
gorm.io/gorm v1.25.2
|
gorm.io/gorm v1.25.3
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/google/uuid v1.3.0
|
require github.com/google/uuid v1.3.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/OpenIMSDK/protocol v0.0.4
|
github.com/OpenIMSDK/protocol v0.0.14
|
||||||
github.com/OpenIMSDK/tools v0.0.13
|
github.com/OpenIMSDK/tools v0.0.13
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible
|
github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible
|
||||||
github.com/go-redis/redis v6.15.9+incompatible
|
github.com/go-redis/redis v6.15.9+incompatible
|
||||||
@@ -47,11 +47,11 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.110.4 // indirect
|
cloud.google.com/go v0.110.6 // indirect
|
||||||
cloud.google.com/go/compute v1.20.1 // indirect
|
cloud.google.com/go/compute v1.23.0 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
cloud.google.com/go/firestore v1.11.0 // indirect
|
cloud.google.com/go/firestore v1.11.0 // indirect
|
||||||
cloud.google.com/go/iam v1.1.0 // indirect
|
cloud.google.com/go/iam v1.1.1 // indirect
|
||||||
cloud.google.com/go/longrunning v0.5.1 // indirect
|
cloud.google.com/go/longrunning v0.5.1 // indirect
|
||||||
cloud.google.com/go/storage v1.30.1 // indirect
|
cloud.google.com/go/storage v1.30.1 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
@@ -117,16 +117,17 @@ require (
|
|||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
golang.org/x/net v0.12.0 // indirect
|
golang.org/x/net v0.14.0 // indirect
|
||||||
golang.org/x/oauth2 v0.10.0 // indirect
|
golang.org/x/oauth2 v0.11.0 // indirect
|
||||||
golang.org/x/sync v0.3.0 // indirect
|
golang.org/x/sync v0.3.0 // indirect
|
||||||
golang.org/x/sys v0.10.0 // indirect
|
golang.org/x/sys v0.11.0 // indirect
|
||||||
golang.org/x/text v0.11.0 // indirect
|
golang.org/x/text v0.12.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect
|
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230720185612-659f7aaaa771 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -137,7 +138,6 @@ require (
|
|||||||
github.com/spf13/cobra v1.7.0
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
go.uber.org/zap v1.24.0 // indirect
|
go.uber.org/zap v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.11.0 // indirect
|
golang.org/x/crypto v0.12.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
|
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk=
|
cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q=
|
||||||
cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||||
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
|
cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
|
||||||
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||||
cloud.google.com/go/firestore v1.11.0 h1:PPgtwcYUOXV2jFe1bV3nda3RCrOa8cvBjTOn2MQVfW8=
|
cloud.google.com/go/firestore v1.11.0 h1:PPgtwcYUOXV2jFe1bV3nda3RCrOa8cvBjTOn2MQVfW8=
|
||||||
cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4=
|
cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4=
|
||||||
cloud.google.com/go/iam v1.1.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94=
|
cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
|
||||||
cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk=
|
cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
|
||||||
cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI=
|
cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI=
|
||||||
cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
|
cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
|
||||||
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
|
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
|
||||||
@@ -17,8 +17,8 @@ cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7Biccwk
|
|||||||
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
|
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
|
||||||
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
|
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/OpenIMSDK/protocol v0.0.4 h1:zEEAi677nog+k4u3e5h36nvYeb1XAwcKQ3Uc2tzxHYs=
|
github.com/OpenIMSDK/protocol v0.0.14 h1:cvQ3f8MTcyYygAnZ7Exq6zIbvHGCEV0fWdpzjQEDDBQ=
|
||||||
github.com/OpenIMSDK/protocol v0.0.4/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
github.com/OpenIMSDK/protocol v0.0.14/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||||
github.com/OpenIMSDK/tools v0.0.13 h1:rcw4HS8S2DPZR9UOBxD8/ol9UBMzXBypzOVEytDRIMo=
|
github.com/OpenIMSDK/tools v0.0.13 h1:rcw4HS8S2DPZR9UOBxD8/ol9UBMzXBypzOVEytDRIMo=
|
||||||
github.com/OpenIMSDK/tools v0.0.13/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
github.com/OpenIMSDK/tools v0.0.13/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
||||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||||
@@ -100,8 +100,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
|||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
|
github.com/go-playground/validator/v10 v10.15.0 h1:nDU5XeOKtB3GEa+uB7GNYwhVKsgjAR7VgKoNB6ryXfw=
|
||||||
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
github.com/go-playground/validator/v10 v10.15.0/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 h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
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.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
@@ -361,11 +361,11 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
|
|||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/image v0.9.0 h1:QrzfX26snvCM20hIhBwuHI/ThTg18b/+kcKdXHvnR+g=
|
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||||
golang.org/x/image v0.9.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0=
|
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
@@ -394,12 +394,12 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT
|
|||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
|
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
|
||||||
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
|
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -430,8 +430,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.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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.11.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-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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
@@ -442,8 +442,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@@ -463,8 +463,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||||
google.golang.org/api v0.134.0 h1:ktL4Goua+UBgoP1eL1/60LwZJqa1sIzkLmvoR3hR6Gw=
|
google.golang.org/api v0.136.0 h1:e/6enzUE1s4tGPa6Q3ZYShKTtvRc+1Jq0rrafhppmOs=
|
||||||
google.golang.org/api v0.134.0/go.mod h1:sjRL3UnjTx5UqNQS9EWr9N8p7xbHpy1k0XGRLCf3Spk=
|
google.golang.org/api v0.136.0/go.mod h1:XtJfF+V2zgUxelOn5Zs3kECtluMxneJG8ZxUTlLNTPA=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
@@ -473,12 +473,12 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
|
|||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8=
|
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
|
||||||
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y=
|
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU=
|
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 h1:nIgk/EEq3/YlnmVVXVnm14rC2oxgs1o0ong4sD/rd44=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ=
|
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230720185612-659f7aaaa771 h1:Z8qdAF9GFsmcUuWQ5KVYIpP3PCKydn/YKORnghIalu4=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 h1:wukfNtZmZUurLN/atp2hiIeTKn7QJWIQdHzqmsOnAOk=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230720185612-659f7aaaa771/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
@@ -523,8 +523,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|||||||
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
|
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
|
||||||
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
|
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
|
||||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
|
gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8=
|
||||||
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
go 1.20
|
||||||
|
|
||||||
|
use (
|
||||||
|
.
|
||||||
|
./test/typecheck
|
||||||
|
./tools/changelog
|
||||||
|
./tools/imctl
|
||||||
|
./tools/infra
|
||||||
|
./tools/ncpu
|
||||||
|
./tools/yamlfmt
|
||||||
|
)
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright © 2023 OpenIM. All rights reserved.
|
# Copyright © 2023 OpenIM. All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|||||||
+1
-1
@@ -152,7 +152,7 @@ EOF
|
|||||||
cd ..;
|
cd ..;
|
||||||
docker-compose up -d;
|
docker-compose up -d;
|
||||||
cd scripts;
|
cd scripts;
|
||||||
./docker_check_service.sh;
|
./docker-check-service.sh;
|
||||||
}
|
}
|
||||||
|
|
||||||
read choice
|
read choice
|
||||||
|
|||||||
@@ -363,3 +363,6 @@ func (m *MessageApi) GetActiveGroup(c *gin.Context) {
|
|||||||
func (m *MessageApi) SearchMsg(c *gin.Context) {
|
func (m *MessageApi) SearchMsg(c *gin.Context) {
|
||||||
a2r.Call(msg.MsgClient.SearchMessage, m.Client, c)
|
a2r.Call(msg.MsgClient.SearchMessage, m.Client, c)
|
||||||
}
|
}
|
||||||
|
func (m *MessageApi) GetServerTime(c *gin.Context) {
|
||||||
|
a2r.Call(msg.MsgClient.GetServerTime, m.Client, c)
|
||||||
|
}
|
||||||
|
|||||||
@@ -82,9 +82,10 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
userRouterGroup.POST("/get_users", ParseToken, u.GetUsers)
|
userRouterGroup.POST("/get_users", ParseToken, u.GetUsers)
|
||||||
userRouterGroup.POST("/get_users_online_status", ParseToken, u.GetUsersOnlineStatus)
|
userRouterGroup.POST("/get_users_online_status", ParseToken, u.GetUsersOnlineStatus)
|
||||||
userRouterGroup.POST("/get_users_online_token_detail", ParseToken, u.GetUsersOnlineTokenDetail)
|
userRouterGroup.POST("/get_users_online_token_detail", ParseToken, u.GetUsersOnlineTokenDetail)
|
||||||
userRouterGroup.POST("/subscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
userRouterGroup.POST("/subscribe_users_status", ParseToken, u.SubscriberStatus)
|
||||||
userRouterGroup.POST("/unsubscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
userRouterGroup.POST("/unsubscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
||||||
userRouterGroup.POST("/get_users_status", ParseToken, u.GetUserStatus)
|
userRouterGroup.POST("/get_users_status", ParseToken, u.GetUserStatus)
|
||||||
|
userRouterGroup.POST("/get_subscribe_users_status", ParseToken, u.GetSubscribeUsersStatus)
|
||||||
}
|
}
|
||||||
// friend routing group
|
// friend routing group
|
||||||
friendRouterGroup := r.Group("/friend", ParseToken)
|
friendRouterGroup := r.Group("/friend", ParseToken)
|
||||||
@@ -186,6 +187,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
|
|
||||||
msgGroup.POST("/batch_send_msg", m.BatchSendMsg)
|
msgGroup.POST("/batch_send_msg", m.BatchSendMsg)
|
||||||
msgGroup.POST("/check_msg_is_send_success", m.CheckMsgIsSendSuccess)
|
msgGroup.POST("/check_msg_is_send_success", m.CheckMsgIsSendSuccess)
|
||||||
|
msgGroup.POST("/get_server_time", m.GetServerTime)
|
||||||
}
|
}
|
||||||
// Conversation
|
// Conversation
|
||||||
conversationGroup := r.Group("/conversation", ParseToken)
|
conversationGroup := r.Group("/conversation", ParseToken)
|
||||||
|
|||||||
@@ -83,7 +83,14 @@ func (o *ThirdApi) ObjectRedirect(c *gin.Context) {
|
|||||||
operationID = strconv.Itoa(rand.Int())
|
operationID = strconv.Itoa(rand.Int())
|
||||||
}
|
}
|
||||||
ctx := mcontext.SetOperationID(c, operationID)
|
ctx := mcontext.SetOperationID(c, operationID)
|
||||||
resp, err := o.Client.AccessURL(ctx, &third.AccessURLReq{Name: name})
|
query := make(map[string]string)
|
||||||
|
for key, values := range c.Request.URL.Query() {
|
||||||
|
if len(values) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
query[key] = values[0]
|
||||||
|
}
|
||||||
|
resp, err := o.Client.AccessURL(ctx, &third.AccessURLReq{Name: name, Query: query})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errs.ErrArgs.Is(err) {
|
if errs.ErrArgs.Is(err) {
|
||||||
c.String(http.StatusBadRequest, err.Error())
|
c.String(http.StatusBadRequest, err.Error())
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
|
|||||||
log.ZWarn(c, "GetUsersOnlineStatus rpc err", err)
|
log.ZWarn(c, "GetUsersOnlineStatus rpc err", err)
|
||||||
|
|
||||||
parseError := apiresp.ParseError(err)
|
parseError := apiresp.ParseError(err)
|
||||||
log.ZDebug(c, "errcode bantanger", "errcode", parseError.ErrCode)
|
|
||||||
if parseError.ErrCode == errs.NoPermissionError {
|
if parseError.ErrCode == errs.NoPermissionError {
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
@@ -196,6 +195,12 @@ func (u *UserApi) UnSubscriberStatus(c *gin.Context) {
|
|||||||
a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c)
|
a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUserStatus Get the online status of the user.
|
||||||
func (u *UserApi) GetUserStatus(c *gin.Context) {
|
func (u *UserApi) GetUserStatus(c *gin.Context) {
|
||||||
a2r.Call(user.UserClient.GetUserStatus, u.Client, c)
|
a2r.Call(user.UserClient.GetUserStatus, u.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSubscribeUsersStatus Get the online status of subscribers.
|
||||||
|
func (u *UserApi) GetSubscribeUsersStatus(c *gin.Context) {
|
||||||
|
a2r.Call(user.UserClient.GetSubscribeUsersStatus, u.Client, c)
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,7 +40,13 @@ type Req struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Req) String() string {
|
func (r *Req) String() string {
|
||||||
return utils.StructToJsonString(r)
|
var tReq Req
|
||||||
|
tReq.ReqIdentifier = r.ReqIdentifier
|
||||||
|
tReq.Token = r.Token
|
||||||
|
tReq.SendID = r.SendID
|
||||||
|
tReq.OperationID = r.OperationID
|
||||||
|
tReq.MsgIncr = r.MsgIncr
|
||||||
|
return utils.StructToJsonString(tReq)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Resp struct {
|
type Resp struct {
|
||||||
@@ -53,7 +59,13 @@ type Resp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resp) String() string {
|
func (r *Resp) String() string {
|
||||||
return utils.StructToJsonString(r)
|
var tResp Resp
|
||||||
|
tResp.ReqIdentifier = r.ReqIdentifier
|
||||||
|
tResp.MsgIncr = r.MsgIncr
|
||||||
|
tResp.OperationID = r.OperationID
|
||||||
|
tResp.ErrCode = r.ErrCode
|
||||||
|
tResp.ErrMsg = r.ErrMsg
|
||||||
|
return utils.StructToJsonString(tResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MessageHandler interface {
|
type MessageHandler interface {
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ func (och *OnlineHistoryRedisConsumerHandler) Run(channelID int) {
|
|||||||
len(modifyMsgList),
|
len(modifyMsgList),
|
||||||
)
|
)
|
||||||
conversationIDMsg := msgprocessor.GetChatConversationIDByMsg(ctxMsgList[0].message)
|
conversationIDMsg := msgprocessor.GetChatConversationIDByMsg(ctxMsgList[0].message)
|
||||||
conversationIDNotification := msgprocessor.GetNotificationConversationID(ctxMsgList[0].message)
|
conversationIDNotification := msgprocessor.GetNotificationConversationIDByMsg(ctxMsgList[0].message)
|
||||||
och.handleMsg(ctx, msgChannelValue.uniqueKey, conversationIDMsg, storageMsgList, notStorageMsgList)
|
och.handleMsg(ctx, msgChannelValue.uniqueKey, conversationIDMsg, storageMsgList, notStorageMsgList)
|
||||||
och.handleNotification(
|
och.handleNotification(
|
||||||
ctx,
|
ctx,
|
||||||
|
|||||||
+69
-14
@@ -16,6 +16,9 @@ package group
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@@ -73,20 +76,33 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
||||||
database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase())
|
var gs groupServer
|
||||||
pbGroup.RegisterGroupServer(server, &groupServer{
|
database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), gs.groupMemberHashCode)
|
||||||
GroupDatabase: database,
|
gs.GroupDatabase = database
|
||||||
User: userRpcClient,
|
gs.User = userRpcClient
|
||||||
Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
gs.Notification = notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
||||||
users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
|
return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
|
||||||
}),
|
|
||||||
conversationRpcClient: conversationRpcClient,
|
|
||||||
msgRpcClient: msgRpcClient,
|
|
||||||
})
|
})
|
||||||
|
gs.conversationRpcClient = conversationRpcClient
|
||||||
|
gs.msgRpcClient = msgRpcClient
|
||||||
|
pbGroup.RegisterGroupServer(server, &gs)
|
||||||
|
//pbGroup.RegisterGroupServer(server, &groupServer{
|
||||||
|
// GroupDatabase: database,
|
||||||
|
// User: userRpcClient,
|
||||||
|
// Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
||||||
|
// users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
|
||||||
|
// }),
|
||||||
|
// conversationRpcClient: conversationRpcClient,
|
||||||
|
// msgRpcClient: msgRpcClient,
|
||||||
|
//})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,6 +177,9 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR
|
|||||||
if req.OwnerUserID == "" {
|
if req.OwnerUserID == "" {
|
||||||
return nil, errs.ErrArgs.Wrap("no group owner")
|
return nil, errs.ErrArgs.Wrap("no group owner")
|
||||||
}
|
}
|
||||||
|
if req.GroupInfo.GroupType != constant.WorkingGroup {
|
||||||
|
return nil, errs.ErrArgs.Wrap(fmt.Sprintf("group type %d not support", req.GroupInfo.GroupType))
|
||||||
|
}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -690,8 +709,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup
|
|||||||
return nil, errs.ErrGroupRequestHandled.Wrap("group request already processed")
|
return nil, errs.ErrGroupRequestHandled.Wrap("group request already processed")
|
||||||
}
|
}
|
||||||
var inGroup bool
|
var inGroup bool
|
||||||
_, err = s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.FromUserID)
|
if _, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.FromUserID); err == nil {
|
||||||
if err == nil {
|
|
||||||
inGroup = true // 已经在群里了
|
inGroup = true // 已经在群里了
|
||||||
} else if !s.IsNotFound(err) {
|
} else if !s.IsNotFound(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -718,6 +736,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log.ZDebug(ctx, "GroupApplicationResponse", "inGroup", inGroup, "HandleResult", req.HandleResult, "member", member)
|
||||||
if err := s.GroupDatabase.HandlerGroupRequest(ctx, req.GroupID, req.FromUserID, req.HandledMsg, req.HandleResult, member); err != nil {
|
if err := s.GroupDatabase.HandlerGroupRequest(ctx, req.GroupID, req.FromUserID, req.HandledMsg, req.HandleResult, member); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -727,12 +746,14 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.GroupApplicationAcceptedNotification(ctx, req)
|
s.Notification.GroupApplicationAcceptedNotification(ctx, req)
|
||||||
|
if member == nil {
|
||||||
|
log.ZDebug(ctx, "GroupApplicationResponse", "member is nil")
|
||||||
|
} else {
|
||||||
|
s.Notification.MemberEnterNotification(ctx, req.GroupID, req.FromUserID)
|
||||||
|
}
|
||||||
case constant.GroupResponseRefuse:
|
case constant.GroupResponseRefuse:
|
||||||
s.Notification.GroupApplicationRejectedNotification(ctx, req)
|
s.Notification.GroupApplicationRejectedNotification(ctx, req)
|
||||||
}
|
}
|
||||||
if member != nil {
|
|
||||||
s.Notification.MemberEnterNotification(ctx, req)
|
|
||||||
}
|
|
||||||
return &pbGroup.GroupApplicationResponseResp{}, nil
|
return &pbGroup.GroupApplicationResponseResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,7 +799,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq)
|
|||||||
if err := s.conversationRpcClient.GroupChatFirstCreateConversation(ctx, req.GroupID, []string{req.InviterUserID}); err != nil {
|
if err := s.conversationRpcClient.GroupChatFirstCreateConversation(ctx, req.GroupID, []string{req.InviterUserID}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.MemberEnterDirectlyNotification(ctx, req.GroupID, req.InviterUserID)
|
s.Notification.MemberEnterNotification(ctx, req.GroupID, req.InviterUserID)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
groupRequest := relationTb.GroupRequestModel{
|
groupRequest := relationTb.GroupRequestModel{
|
||||||
@@ -1486,3 +1507,37 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req *
|
|||||||
resp.Total = total
|
resp.Total = total
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *groupServer) groupMemberHashCode(ctx context.Context, groupID string) (uint64, error) {
|
||||||
|
userIDs, err := s.GroupDatabase.FindGroupMemberUserID(ctx, groupID)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var members []*sdkws.GroupMemberFullInfo
|
||||||
|
if len(userIDs) > 0 {
|
||||||
|
resp, err := s.GetGroupMembersInfo(ctx, &pbGroup.GetGroupMembersInfoReq{GroupID: groupID, UserIDs: userIDs})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
members = resp.Members
|
||||||
|
utils.Sort(userIDs, true)
|
||||||
|
}
|
||||||
|
memberMap := utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string {
|
||||||
|
return e.UserID
|
||||||
|
})
|
||||||
|
res := make([]*sdkws.GroupMemberFullInfo, 0, len(members))
|
||||||
|
for _, userID := range userIDs {
|
||||||
|
member, ok := memberMap[userID]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
member.AppMangerLevel = 0
|
||||||
|
res = append(res, member)
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(res)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
sum := md5.Sum(data)
|
||||||
|
return binary.BigEndian.Uint64(sum[:]), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,11 +26,16 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (*msg.GetConversationsHasReadAndMaxSeqResp, error) {
|
func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (resp *msg.GetConversationsHasReadAndMaxSeqResp, err error) {
|
||||||
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
var conversationIDs []string
|
||||||
|
if len(req.ConversationIDs) == 0 {
|
||||||
|
conversationIDs, err = m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
conversationIDs = req.ConversationIDs
|
||||||
|
}
|
||||||
hasReadSeqs, err := m.MsgDatabase.GetHasReadSeqs(ctx, req.UserID, conversationIDs)
|
hasReadSeqs, err := m.MsgDatabase.GetHasReadSeqs(ctx, req.UserID, conversationIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -49,7 +54,7 @@ func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *m
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp := &msg.GetConversationsHasReadAndMaxSeqResp{Seqs: make(map[string]*msg.Seqs)}
|
resp = &msg.GetConversationsHasReadAndMaxSeqResp{Seqs: make(map[string]*msg.Seqs)}
|
||||||
for conversarionID, maxSeq := range maxSeqs {
|
for conversarionID, maxSeq := range maxSeqs {
|
||||||
resp.Seqs[conversarionID] = &msg.Seqs{
|
resp.Seqs[conversarionID] = &msg.Seqs{
|
||||||
HasReadSeq: hasReadSeqs[conversarionID],
|
HasReadSeq: hasReadSeqs[conversarionID],
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ import (
|
|||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||||
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -107,13 +109,15 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
revokerUserID := mcontext.GetOpUserID(ctx)
|
||||||
tips := sdkws.RevokeMsgTips{
|
tips := sdkws.RevokeMsgTips{
|
||||||
RevokerUserID: req.UserID,
|
RevokerUserID: revokerUserID,
|
||||||
ClientMsgID: msgs[0].ClientMsgID,
|
ClientMsgID: msgs[0].ClientMsgID,
|
||||||
RevokeTime: now,
|
RevokeTime: now,
|
||||||
Seq: req.Seq,
|
Seq: req.Seq,
|
||||||
SesstionType: msgs[0].SessionType,
|
SesstionType: msgs[0].SessionType,
|
||||||
ConversationID: req.ConversationID,
|
ConversationID: req.ConversationID,
|
||||||
|
IsAdminRevoke: utils.Contain(revokerUserID, config.Config.Manager.UserID...),
|
||||||
}
|
}
|
||||||
var recvID string
|
var recvID string
|
||||||
if msgs[0].SessionType == constant.SuperGroupChatType {
|
if msgs[0].SessionType == constant.SuperGroupChatType {
|
||||||
|
|||||||
@@ -116,41 +116,78 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq
|
|||||||
if total, chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil {
|
if total, chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
sendIDs []string
|
||||||
|
recvIDs []string
|
||||||
|
groupIDs []string
|
||||||
|
sendMap = make(map[string]string)
|
||||||
|
recvMap = make(map[string]string)
|
||||||
|
groupMap = make(map[string]*sdkws.GroupInfo)
|
||||||
|
)
|
||||||
|
for _, chatLog := range chatLogs {
|
||||||
|
if chatLog.SenderNickname == "" {
|
||||||
|
sendIDs = append(sendIDs, chatLog.SendID)
|
||||||
|
}
|
||||||
|
switch chatLog.SessionType {
|
||||||
|
case constant.SingleChatType:
|
||||||
|
recvIDs = append(recvIDs, chatLog.RecvID)
|
||||||
|
case constant.GroupChatType, constant.SuperGroupChatType:
|
||||||
|
groupIDs = append(groupIDs, chatLog.GroupID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(sendIDs) != 0 {
|
||||||
|
sendInfos, err := m.User.GetUsersInfo(ctx, sendIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, sendInfo := range sendInfos {
|
||||||
|
sendMap[sendInfo.UserID] = sendInfo.Nickname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(recvIDs) != 0 {
|
||||||
|
recvInfos, err := m.User.GetUsersInfo(ctx, recvIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, recvInfo := range recvInfos {
|
||||||
|
recvMap[recvInfo.UserID] = recvInfo.Nickname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(groupIDs) != 0 {
|
||||||
|
groupInfos, err := m.Group.GetGroupInfos(ctx, groupIDs, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, groupInfo := range groupInfos {
|
||||||
|
groupMap[groupInfo.GroupID] = groupInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, chatLog := range chatLogs {
|
for _, chatLog := range chatLogs {
|
||||||
pbChatLog := &msg.ChatLog{}
|
pbChatLog := &msg.ChatLog{}
|
||||||
utils.CopyStructFields(pbChatLog, chatLog)
|
utils.CopyStructFields(pbChatLog, chatLog)
|
||||||
pbChatLog.SendTime = chatLog.SendTime
|
pbChatLog.SendTime = chatLog.SendTime
|
||||||
pbChatLog.CreateTime = chatLog.CreateTime
|
pbChatLog.CreateTime = chatLog.CreateTime
|
||||||
if chatLog.SenderNickname == "" {
|
if chatLog.SenderNickname == "" {
|
||||||
sendUser, err := m.User.GetUserInfo(ctx, chatLog.SendID)
|
pbChatLog.SenderNickname = sendMap[chatLog.SendID]
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pbChatLog.SenderNickname = sendUser.Nickname
|
|
||||||
}
|
}
|
||||||
switch chatLog.SessionType {
|
switch chatLog.SessionType {
|
||||||
case constant.SingleChatType:
|
case constant.SingleChatType:
|
||||||
recvUser, err := m.User.GetUserInfo(ctx, chatLog.RecvID)
|
pbChatLog.RecvNickname = recvMap[chatLog.RecvID]
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pbChatLog.RecvNickname = recvUser.Nickname
|
|
||||||
|
|
||||||
case constant.GroupChatType, constant.SuperGroupChatType:
|
case constant.GroupChatType, constant.SuperGroupChatType:
|
||||||
group, err := m.Group.GetGroupInfo(ctx, chatLog.GroupID)
|
pbChatLog.SenderFaceURL = groupMap[chatLog.GroupID].FaceURL
|
||||||
if err != nil {
|
pbChatLog.GroupMemberCount = groupMap[chatLog.GroupID].MemberCount
|
||||||
return nil, err
|
pbChatLog.RecvID = groupMap[chatLog.GroupID].GroupID
|
||||||
}
|
pbChatLog.GroupName = groupMap[chatLog.GroupID].GroupName
|
||||||
pbChatLog.SenderFaceURL = group.FaceURL
|
pbChatLog.GroupOwner = groupMap[chatLog.GroupID].OwnerUserID
|
||||||
pbChatLog.GroupMemberCount = group.MemberCount
|
pbChatLog.GroupType = groupMap[chatLog.GroupID].GroupType
|
||||||
pbChatLog.RecvID = group.GroupID
|
|
||||||
pbChatLog.GroupName = group.GroupName
|
|
||||||
pbChatLog.GroupOwner = group.OwnerUserID
|
|
||||||
pbChatLog.GroupType = group.GroupType
|
|
||||||
}
|
}
|
||||||
resp.ChatLogs = append(resp.ChatLogs, pbChatLog)
|
resp.ChatLogs = append(resp.ChatLogs, pbChatLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.ChatLogsNum = total
|
resp.ChatLogsNum = total
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
func (m *msgServer) GetServerTime(ctx context.Context, _ *msg.GetServerTimeReq) (*msg.GetServerTimeResp, error) {
|
||||||
|
return &msg.GetServerTimeResp{ServerTime: utils.GetCurrentTimestampByMill()}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
|||||||
if groupMemberInfo.RoleLevel == constant.GroupOwner {
|
if groupMemberInfo.RoleLevel == constant.GroupOwner {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
if groupMemberInfo.MuteEndTime >= time.Now().Unix() {
|
if groupMemberInfo.MuteEndTime >= time.Now().UnixMilli() {
|
||||||
return errs.ErrMutedInGroup.Wrap()
|
return errs.ErrMutedInGroup.Wrap()
|
||||||
}
|
}
|
||||||
if groupInfo.Status == constant.GroupStatusMuted && groupMemberInfo.RoleLevel != constant.GroupAdmin {
|
if groupInfo.Status == constant.GroupStatusMuted && groupMemberInfo.RoleLevel != constant.GroupAdmin {
|
||||||
|
|||||||
@@ -16,8 +16,11 @@ package third
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/third"
|
"github.com/OpenIMSDK/protocol/third"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
@@ -152,7 +155,21 @@ func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *thirdServer) AccessURL(ctx context.Context, req *third.AccessURLReq) (*third.AccessURLResp, error) {
|
func (t *thirdServer) AccessURL(ctx context.Context, req *third.AccessURLReq) (*third.AccessURLResp, error) {
|
||||||
expireTime, rawURL, err := t.s3dataBase.AccessURL(ctx, req.Name, t.defaultExpire)
|
opt := &s3.AccessURLOption{}
|
||||||
|
if len(req.Query) > 0 {
|
||||||
|
switch req.Query["type"] {
|
||||||
|
case "":
|
||||||
|
case "image":
|
||||||
|
opt.Image = &s3.Image{}
|
||||||
|
opt.Image.Format = req.Query["format"]
|
||||||
|
opt.Image.Width, _ = strconv.Atoi(req.Query["width"])
|
||||||
|
opt.Image.Height, _ = strconv.Atoi(req.Query["height"])
|
||||||
|
log.ZDebug(ctx, "AccessURL image", "name", req.Name, "option", opt.Image)
|
||||||
|
default:
|
||||||
|
return nil, errs.ErrArgs.Wrap("invalid query type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expireTime, rawURL, err := t.s3dataBase.AccessURL(ctx, req.Name, t.defaultExpire, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
if apiURL[len(apiURL)-1] != '/' {
|
if apiURL[len(apiURL)-1] != '/' {
|
||||||
apiURL += "/"
|
apiURL += "/"
|
||||||
}
|
}
|
||||||
|
apiURL += "object/"
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+43
-12
@@ -20,17 +20,16 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/authverify"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/authverify"
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
|
||||||
pbuser "github.com/OpenIMSDK/protocol/user"
|
|
||||||
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
|
||||||
@@ -41,14 +40,15 @@ import (
|
|||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
pbuser "github.com/OpenIMSDK/protocol/user"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type userServer struct {
|
type userServer struct {
|
||||||
controller.UserDatabase
|
controller.UserDatabase
|
||||||
notificationSender *notification.FriendNotificationSender
|
friendNotificationSender *notification.FriendNotificationSender
|
||||||
|
userNotificationSender *notification.UserNotificationSender
|
||||||
friendRpcClient *rpcclient.FriendRpcClient
|
friendRpcClient *rpcclient.FriendRpcClient
|
||||||
RegisterCenter registry.SvcDiscoveryRegistry
|
RegisterCenter registry.SvcDiscoveryRegistry
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,8 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
|||||||
UserDatabase: database,
|
UserDatabase: database,
|
||||||
RegisterCenter: client,
|
RegisterCenter: client,
|
||||||
friendRpcClient: &friendRpcClient,
|
friendRpcClient: &friendRpcClient,
|
||||||
notificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)),
|
friendNotificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)),
|
||||||
|
userNotificationSender: notification.NewUserNotificationSender(&msgRpcClient, notification.WithUserFunc(database.FindWithError)),
|
||||||
}
|
}
|
||||||
pbuser.RegisterUserServer(server, u)
|
pbuser.RegisterUserServer(server, u)
|
||||||
return u.UserDatabase.InitOnce(context.Background(), users)
|
return u.UserDatabase.InitOnce(context.Background(), users)
|
||||||
@@ -119,13 +120,13 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_ = s.notificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID)
|
_ = s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID)
|
||||||
friends, err := s.friendRpcClient.GetFriendIDs(ctx, req.UserInfo.UserID)
|
friends, err := s.friendRpcClient.GetFriendIDs(ctx, req.UserInfo.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, friendID := range friends {
|
for _, friendID := range friends {
|
||||||
s.notificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
@@ -140,7 +141,7 @@ func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Se
|
|||||||
if err := s.UpdateByMap(ctx, req.UserID, m); err != nil {
|
if err := s.UpdateByMap(ctx, req.UserID, m); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.notificationSender.UserInfoUpdatedNotification(ctx, req.UserID)
|
s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserID)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,6 +274,7 @@ func (s *userServer) SubscribeOrCancelUsersStatus(ctx context.Context, req *pbus
|
|||||||
return &pbuser.SubscribeOrCancelUsersStatusResp{}, nil
|
return &pbuser.SubscribeOrCancelUsersStatusResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUserStatus Get the online status of the user.
|
||||||
func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatusReq) (resp *pbuser.GetUserStatusResp, err error) {
|
func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatusReq) (resp *pbuser.GetUserStatusResp, err error) {
|
||||||
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, req.UserIDs)
|
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, req.UserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -281,10 +283,39 @@ func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatu
|
|||||||
return &pbuser.GetUserStatusResp{StatusList: onlineStatusList}, nil
|
return &pbuser.GetUserStatusResp{StatusList: onlineStatusList}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetUserStatus Synchronize user's online status.
|
||||||
func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatusReq) (resp *pbuser.SetUserStatusResp, err error) {
|
func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatusReq) (resp *pbuser.SetUserStatusResp, err error) {
|
||||||
err = s.UserDatabase.SetUserStatus(ctx, req.StatusList)
|
err = s.UserDatabase.SetUserStatus(ctx, req.StatusList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
for _, value := range req.StatusList {
|
||||||
|
list, err := s.UserDatabase.GetSubscribedList(ctx, value.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, userID := range list {
|
||||||
|
tips := &sdkws.UserStatusChangeTips{
|
||||||
|
FromUserID: value.UserID,
|
||||||
|
ToUserID: userID,
|
||||||
|
Status: value.Status,
|
||||||
|
PlatformID: value.PlatformIDs[0],
|
||||||
|
}
|
||||||
|
s.userNotificationSender.UserStatusChangeNotification(ctx, tips)
|
||||||
|
}
|
||||||
|
}
|
||||||
return &pbuser.SetUserStatusResp{}, nil
|
return &pbuser.SetUserStatusResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSubscribeUsersStatus Get the online status of subscribers.
|
||||||
|
func (s *userServer) GetSubscribeUsersStatus(ctx context.Context, req *pbuser.GetSubscribeUsersStatusReq) (*pbuser.GetSubscribeUsersStatusResp, error) {
|
||||||
|
userList, err := s.UserDatabase.GetAllSubscribeList(ctx, req.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, userList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pbuser.GetSubscribeUsersStatusResp{StatusList: onlineStatusList}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,12 +26,13 @@ import (
|
|||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartCronTask() error {
|
func StartTask() error {
|
||||||
fmt.Println("cron task start, config", config.Config.ChatRecordsClearTime)
|
fmt.Println("cron task start, config", config.Config.ChatRecordsClearTime)
|
||||||
msgTool, err := InitMsgTool()
|
msgTool, err := InitMsgTool()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
msgTool.ConvertTools()
|
||||||
c := cron.New()
|
c := cron.New()
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func InitMsgTool() (*MsgTool, error) {
|
|||||||
tx.NewGorm(db),
|
tx.NewGorm(db),
|
||||||
userMongoDB,
|
userMongoDB,
|
||||||
)
|
)
|
||||||
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase())
|
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), nil)
|
||||||
conversationDatabase := controller.NewConversationDatabase(
|
conversationDatabase := controller.NewConversationDatabase(
|
||||||
relation.NewConversationGorm(db),
|
relation.NewConversationGorm(db),
|
||||||
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)),
|
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)),
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/msgprocessor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *MsgTool) ConvertTools() {
|
||||||
|
ctx := mcontext.NewCtx("convert")
|
||||||
|
conversationIDs, err := c.conversationDatabase.GetAllConversationIDs(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.ZError(ctx, "get all conversation ids failed", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, conversationID := range conversationIDs {
|
||||||
|
conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationIDByConversationID(conversationID))
|
||||||
|
}
|
||||||
|
userIDs, err := c.userDatabase.GetAllUserID(ctx, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
log.ZError(ctx, "get all user ids failed", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.ZDebug(ctx, "all userIDs", "len userIDs", len(userIDs))
|
||||||
|
for _, userID := range userIDs {
|
||||||
|
conversationIDs = append(conversationIDs, msgprocessor.GetConversationIDBySessionType(constant.SingleChatType, userID, userID))
|
||||||
|
conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationID(constant.SingleChatType, userID, userID))
|
||||||
|
}
|
||||||
|
log.ZDebug(ctx, "all conversationIDs", "len userIDs", len(conversationIDs))
|
||||||
|
c.msgDatabase.ConvertMsgsDocLen(ctx, conversationIDs)
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package apistruct // import "github.com/OpenIMSDK/Open-IM-Server/pkg/apistruct"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// 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 authverify // import "github.com/OpenIMSDK/Open-IM-Server/pkg/authverify"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// 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 callbackstruct // import "github.com/OpenIMSDK/Open-IM-Server/pkg/callbackstruct"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cmd // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/cmd"
|
||||||
@@ -120,6 +120,7 @@ type configStruct struct {
|
|||||||
AccessKeyID string `yaml:"accessKeyID"`
|
AccessKeyID string `yaml:"accessKeyID"`
|
||||||
SecretAccessKey string `yaml:"secretAccessKey"`
|
SecretAccessKey string `yaml:"secretAccessKey"`
|
||||||
SessionToken string `yaml:"sessionToken"`
|
SessionToken string `yaml:"sessionToken"`
|
||||||
|
SignEndpoint string `yaml:"signEndpoint"`
|
||||||
} `yaml:"minio"`
|
} `yaml:"minio"`
|
||||||
Cos struct {
|
Cos struct {
|
||||||
BucketURL string `yaml:"bucketURL"`
|
BucketURL string `yaml:"bucketURL"`
|
||||||
@@ -284,6 +285,7 @@ type notification struct {
|
|||||||
GroupInfoSetName NotificationConf `yaml:"groupInfoSetName"`
|
GroupInfoSetName NotificationConf `yaml:"groupInfoSetName"`
|
||||||
////////////////////////user///////////////////////
|
////////////////////////user///////////////////////
|
||||||
UserInfoUpdated NotificationConf `yaml:"userInfoUpdated"`
|
UserInfoUpdated NotificationConf `yaml:"userInfoUpdated"`
|
||||||
|
UserStatusChanged NotificationConf `yaml:"userStatusChanged"`
|
||||||
//////////////////////friend///////////////////////
|
//////////////////////friend///////////////////////
|
||||||
FriendApplicationAdded NotificationConf `yaml:"friendApplicationAdded"`
|
FriendApplicationAdded NotificationConf `yaml:"friendApplicationAdded"`
|
||||||
FriendApplicationApproved NotificationConf `yaml:"friendApplicationApproved"`
|
FriendApplicationApproved NotificationConf `yaml:"friendApplicationApproved"`
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user