Feat: Refactor project's references to shared modules (#672)
* fix: to start im or chat, ZooKeeper must be started first. * fix: msg gateway start output err info Signed-off-by: Gordon <1432970085@qq.com> * fix: msg gateway start output err info Signed-off-by: Gordon <1432970085@qq.com> * chore: package path changes Signed-off-by: withchao <993506633@qq.com> * fix: go mod update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * chore: package path changes Signed-off-by: withchao <993506633@qq.com> * chore: package path changes Signed-off-by: withchao <993506633@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> --------- Signed-off-by: Gordon <1432970085@qq.com> Signed-off-by: withchao <993506633@qq.com> Co-authored-by: withchao <993506633@qq.com>pull/678/head
parent
d7218dd5be
commit
5b85fa763a
@ -1,355 +0,0 @@
|
|||||||
// Copyright © 2023 OpenIM. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package tools
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
|
||||||
"github.com/OpenIMSDK/tools/constant"
|
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
|
||||||
|
|
||||||
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
|
||||||
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GenMsgDoc(startSeq, stopSeq, delSeq, index int64, conversationID string) *unRelationTb.MsgDocModel {
|
|
||||||
msgDoc := &unRelationTb.MsgDocModel{DocID: conversationID + strconv.Itoa(int(index))}
|
|
||||||
for i := 0; i < 5000; i++ {
|
|
||||||
msgDoc.Msg = append(msgDoc.Msg, &unRelationTb.MsgInfoModel{})
|
|
||||||
}
|
|
||||||
for i := startSeq; i <= stopSeq; i++ {
|
|
||||||
msg := &unRelationTb.MsgDataModel{
|
|
||||||
SendID: "sendID1",
|
|
||||||
RecvID: "recvID1",
|
|
||||||
GroupID: "",
|
|
||||||
ClientMsgID: "xxx",
|
|
||||||
ServerMsgID: "xxx",
|
|
||||||
SenderPlatformID: 1,
|
|
||||||
SenderNickname: "testNickName",
|
|
||||||
SenderFaceURL: "testFaceURL",
|
|
||||||
SessionType: 1,
|
|
||||||
MsgFrom: 100,
|
|
||||||
ContentType: 101,
|
|
||||||
Content: "testContent",
|
|
||||||
Seq: i,
|
|
||||||
CreateTime: time.Now().Unix(),
|
|
||||||
Status: 1,
|
|
||||||
}
|
|
||||||
if i <= delSeq {
|
|
||||||
msg.SendTime = 10000
|
|
||||||
} else {
|
|
||||||
msg.SendTime = utils.GetCurrentTimestampByMill()
|
|
||||||
}
|
|
||||||
msgDoc.Msg[i-1] = &unRelationTb.MsgInfoModel{Msg: msg}
|
|
||||||
}
|
|
||||||
return msgDoc
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeleteMongoMsgAndResetRedisSeq(t *testing.T) {
|
|
||||||
operationID := "test"
|
|
||||||
rdb, err := cache.NewRedis()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mgo, err := unrelation.NewMongo()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cacheModel := cache.NewMsgCacheModel(rdb)
|
|
||||||
mongoClient := mgo.GetDatabase().Collection(unRelationTb.MsgDocModel{}.TableName())
|
|
||||||
ctx := context.Background()
|
|
||||||
ctx = mcontext.SetOperationID(ctx, operationID)
|
|
||||||
|
|
||||||
testUID1 := "test_del_id1"
|
|
||||||
var conversationID string
|
|
||||||
conversationID = utils.GetConversationIDBySessionType(constant.SuperGroupChatType, testUID1)
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"doc_id": conversationID + ":" + strconv.Itoa(0)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("DeleteOne failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cacheModel.SetMaxSeq(ctx, conversationID, 600)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("SetUserMaxSeq failed")
|
|
||||||
}
|
|
||||||
msgDoc := GenMsgDoc(1, 600, 200, 0, conversationID)
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
|
|
||||||
t.Error("InsertOne failed", conversationID)
|
|
||||||
}
|
|
||||||
|
|
||||||
msgTools, err := InitMsgTool()
|
|
||||||
if err != nil {
|
|
||||||
t.Error("init failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
msgTools.ClearConversationsMsg(ctx, []string{conversationID})
|
|
||||||
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err := msgTools.msgDatabase.GetConversationMinMaxSeqInMongoAndCache(
|
|
||||||
ctx,
|
|
||||||
conversationID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if maxSeqCache != maxSeqMongo {
|
|
||||||
t.Error("checkMaxSeqWithMongo failed", conversationID)
|
|
||||||
}
|
|
||||||
if minSeqMongo != minSeqCache {
|
|
||||||
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
|
|
||||||
}
|
|
||||||
if minSeqCache != 201 {
|
|
||||||
t.Error("test1 is not the same", "minSeq:", minSeqCache, "targetSeq", 201)
|
|
||||||
}
|
|
||||||
|
|
||||||
/////// uid2
|
|
||||||
|
|
||||||
testUID2 := "test_del_id2"
|
|
||||||
conversationID = utils.GetConversationIDBySessionType(constant.SuperGroupChatType, testUID2)
|
|
||||||
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(0)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(1)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cacheModel.SetMaxSeq(ctx, conversationID, 7000)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("SetUserMaxSeq failed")
|
|
||||||
}
|
|
||||||
msgDoc = GenMsgDoc(1, 4999, 5000, 0, conversationID)
|
|
||||||
msgDoc2 := GenMsgDoc(5000, 7000, 6000, 1, conversationID)
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
|
|
||||||
t.Error("InsertOne failed", testUID1)
|
|
||||||
}
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc2); err != nil {
|
|
||||||
t.Error("InsertOne failed", testUID1)
|
|
||||||
}
|
|
||||||
|
|
||||||
msgTools.ClearConversationsMsg(ctx, []string{conversationID})
|
|
||||||
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetConversationMinMaxSeqInMongoAndCache(
|
|
||||||
ctx,
|
|
||||||
conversationID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if maxSeqCache != maxSeqMongo {
|
|
||||||
t.Error("checkMaxSeqWithMongo failed", conversationID)
|
|
||||||
}
|
|
||||||
if minSeqMongo != minSeqCache {
|
|
||||||
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
|
|
||||||
}
|
|
||||||
if minSeqCache != 6001 {
|
|
||||||
t.Error("test1 is not the same", "minSeq:", minSeqCache, "targetSeq", 201)
|
|
||||||
}
|
|
||||||
|
|
||||||
/////// uid3
|
|
||||||
testUID3 := "test_del_id3"
|
|
||||||
conversationID = utils.GetConversationIDBySessionType(constant.SuperGroupChatType, testUID3)
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(0)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
err = cacheModel.SetMaxSeq(ctx, conversationID, 4999)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("SetUserMaxSeq failed")
|
|
||||||
}
|
|
||||||
msgDoc = GenMsgDoc(1, 4999, 5000, 0, conversationID)
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
|
|
||||||
t.Error("InsertOne failed", conversationID)
|
|
||||||
}
|
|
||||||
|
|
||||||
msgTools.ClearConversationsMsg(ctx, []string{conversationID})
|
|
||||||
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetConversationMinMaxSeqInMongoAndCache(
|
|
||||||
ctx,
|
|
||||||
conversationID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if maxSeqCache != maxSeqMongo {
|
|
||||||
t.Error("checkMaxSeqWithMongo failed", conversationID)
|
|
||||||
}
|
|
||||||
if minSeqMongo != minSeqCache {
|
|
||||||
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
|
|
||||||
}
|
|
||||||
if minSeqCache != 5000 {
|
|
||||||
t.Error("test1 is not the same", "minSeq:", minSeqCache, "targetSeq", 201)
|
|
||||||
}
|
|
||||||
|
|
||||||
//// uid4
|
|
||||||
testUID4 := "test_del_id4"
|
|
||||||
conversationID = utils.GetConversationIDBySessionType(constant.SuperGroupChatType, testUID4)
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(0)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(1)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(2)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cacheModel.SetMaxSeq(ctx, conversationID, 12000)
|
|
||||||
msgDoc = GenMsgDoc(1, 4999, 5000, 0, conversationID)
|
|
||||||
msgDoc2 = GenMsgDoc(5000, 9999, 10000, 1, conversationID)
|
|
||||||
msgDoc3 := GenMsgDoc(10000, 12000, 11000, 2, conversationID)
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
|
|
||||||
t.Error("InsertOne failed", conversationID)
|
|
||||||
}
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc2); err != nil {
|
|
||||||
t.Error("InsertOne failed", conversationID)
|
|
||||||
}
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc3); err != nil {
|
|
||||||
t.Error("InsertOne failed", conversationID)
|
|
||||||
}
|
|
||||||
|
|
||||||
msgTools.ClearConversationsMsg(ctx, []string{conversationID})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetConversationMinMaxSeqInMongoAndCache(
|
|
||||||
ctx,
|
|
||||||
conversationID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if maxSeqCache != maxSeqMongo {
|
|
||||||
t.Error("checkMaxSeqWithMongo failed", conversationID)
|
|
||||||
}
|
|
||||||
if minSeqMongo != minSeqCache {
|
|
||||||
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
|
|
||||||
}
|
|
||||||
if minSeqCache != 5000 {
|
|
||||||
t.Error("test1 is not the same", "minSeq:", minSeqCache)
|
|
||||||
}
|
|
||||||
|
|
||||||
testUID5 := "test_del_id5"
|
|
||||||
conversationID = utils.GetConversationIDBySessionType(constant.SuperGroupChatType, testUID5)
|
|
||||||
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(0)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(1)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
err = cacheModel.SetMaxSeq(ctx, conversationID, 9999)
|
|
||||||
msgDoc = GenMsgDoc(1, 4999, 5000, 0, conversationID)
|
|
||||||
msgDoc2 = GenMsgDoc(5000, 9999, 10000, 1, conversationID)
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
|
|
||||||
t.Error("InsertOne failed", conversationID)
|
|
||||||
}
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc2); err != nil {
|
|
||||||
t.Error("InsertOne failed", conversationID)
|
|
||||||
}
|
|
||||||
|
|
||||||
msgTools.ClearConversationsMsg(ctx, []string{conversationID})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetConversationMinMaxSeqInMongoAndCache(
|
|
||||||
ctx,
|
|
||||||
conversationID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if maxSeqCache != maxSeqMongo {
|
|
||||||
t.Error("checkMaxSeqWithMongo failed", conversationID)
|
|
||||||
}
|
|
||||||
if minSeqMongo != minSeqCache {
|
|
||||||
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
|
|
||||||
}
|
|
||||||
if minSeqCache != 10000 {
|
|
||||||
t.Error("test1 is not the same", "minSeq:", minSeqCache)
|
|
||||||
}
|
|
||||||
|
|
||||||
testUID6 := "test_del_id6"
|
|
||||||
conversationID = utils.GetConversationIDBySessionType(constant.SuperGroupChatType, testUID6)
|
|
||||||
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(0)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(1)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(2)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": conversationID + ":" + strconv.Itoa(3)})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("delete failed")
|
|
||||||
}
|
|
||||||
msgDoc = GenMsgDoc(1, 4999, 5000, 0, conversationID)
|
|
||||||
msgDoc2 = GenMsgDoc(5000, 9999, 10000, 1, conversationID)
|
|
||||||
msgDoc3 = GenMsgDoc(10000, 14999, 13000, 2, conversationID)
|
|
||||||
msgDoc4 := GenMsgDoc(15000, 19999, 0, 3, conversationID)
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
|
|
||||||
t.Error("InsertOne failed", testUID4)
|
|
||||||
}
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc2); err != nil {
|
|
||||||
t.Error("InsertOne failed", testUID4)
|
|
||||||
}
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc3); err != nil {
|
|
||||||
t.Error("InsertOne failed", testUID4)
|
|
||||||
}
|
|
||||||
if _, err := mongoClient.InsertOne(ctx, msgDoc4); err != nil {
|
|
||||||
t.Error("InsertOne failed", testUID4)
|
|
||||||
}
|
|
||||||
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetConversationMinMaxSeqInMongoAndCache(
|
|
||||||
ctx,
|
|
||||||
conversationID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if maxSeqCache != maxSeqMongo {
|
|
||||||
t.Error("checkMaxSeqWithMongo failed", conversationID)
|
|
||||||
}
|
|
||||||
if minSeqMongo != minSeqCache {
|
|
||||||
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
|
|
||||||
}
|
|
||||||
if minSeqCache != 13001 {
|
|
||||||
t.Error("test1 is not the same", "minSeq:", minSeqCache)
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,62 @@
|
|||||||
|
package authverify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
|
"github.com/OpenIMSDK/tools/tokenverify"
|
||||||
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Secret() jwt.Keyfunc {
|
||||||
|
return func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte(config.Config.Secret), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) {
|
||||||
|
opUserID := mcontext.GetOpUserID(ctx)
|
||||||
|
if utils.IsContain(opUserID, config.Config.Manager.UserID) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if opUserID == ownerUserID {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errs.ErrNoPermission.Wrap(utils.GetSelfFuncName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsAppManagerUid(ctx context.Context) bool {
|
||||||
|
return utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckAdmin(ctx context.Context) error {
|
||||||
|
if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseRedisInterfaceToken(redisToken interface{}) (*tokenverify.Claims, error) {
|
||||||
|
return tokenverify.GetClaimFromToken(string(redisToken.([]uint8)), Secret())
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsManagerUserID(opUserID string) bool {
|
||||||
|
return utils.IsContain(opUserID, config.Config.Manager.UserID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WsVerifyToken(token, userID string, platformID int) error {
|
||||||
|
claim, err := tokenverify.GetClaimFromToken(token, Secret())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if claim.UserID != userID {
|
||||||
|
return errs.ErrTokenInvalid.Wrap(fmt.Sprintf("token uid %s != userID %s", claim.UserID, userID))
|
||||||
|
}
|
||||||
|
if claim.PlatformID != platformID {
|
||||||
|
return errs.ErrTokenInvalid.Wrap(fmt.Sprintf("token platform %d != %d", claim.PlatformID, platformID))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -0,0 +1,333 @@
|
|||||||
|
// 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 config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Config configStruct
|
||||||
|
|
||||||
|
const ConfKey = "conf"
|
||||||
|
|
||||||
|
type CallBackConfig struct {
|
||||||
|
Enable bool `yaml:"enable"`
|
||||||
|
CallbackTimeOut int `yaml:"timeout"`
|
||||||
|
CallbackFailedContinue *bool `yaml:"failedContinue"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NotificationConf struct {
|
||||||
|
IsSendMsg bool `yaml:"isSendMsg"`
|
||||||
|
ReliabilityLevel int `yaml:"reliabilityLevel"` // 1 online 2 persistent
|
||||||
|
UnreadCount bool `yaml:"unreadCount"`
|
||||||
|
OfflinePush POfflinePush `yaml:"offlinePush"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type POfflinePush struct {
|
||||||
|
Enable bool `yaml:"enable"`
|
||||||
|
Title string `yaml:"title"`
|
||||||
|
Desc string `yaml:"desc"`
|
||||||
|
Ext string `yaml:"ext"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type configStruct struct {
|
||||||
|
Zookeeper struct {
|
||||||
|
Schema string `yaml:"schema"`
|
||||||
|
ZkAddr []string `yaml:"address"`
|
||||||
|
Username string `yaml:"username"`
|
||||||
|
Password string `yaml:"password"`
|
||||||
|
} `yaml:"zookeeper"`
|
||||||
|
|
||||||
|
Mysql struct {
|
||||||
|
Address []string `yaml:"address"`
|
||||||
|
Username string `yaml:"username"`
|
||||||
|
Password string `yaml:"password"`
|
||||||
|
Database string `yaml:"database"`
|
||||||
|
MaxOpenConn int `yaml:"maxOpenConn"`
|
||||||
|
MaxIdleConn int `yaml:"maxIdleConn"`
|
||||||
|
MaxLifeTime int `yaml:"maxLifeTime"`
|
||||||
|
LogLevel int `yaml:"logLevel"`
|
||||||
|
SlowThreshold int `yaml:"slowThreshold"`
|
||||||
|
} `yaml:"mysql"`
|
||||||
|
|
||||||
|
Mongo struct {
|
||||||
|
Uri string `yaml:"uri"`
|
||||||
|
Address []string `yaml:"address"`
|
||||||
|
Database string `yaml:"database"`
|
||||||
|
Username string `yaml:"username"`
|
||||||
|
Password string `yaml:"password"`
|
||||||
|
MaxPoolSize int `yaml:"maxPoolSize"`
|
||||||
|
} `yaml:"mongo"`
|
||||||
|
|
||||||
|
Redis struct {
|
||||||
|
Address []string `yaml:"address"`
|
||||||
|
Username string `yaml:"username"`
|
||||||
|
Password string `yaml:"password"`
|
||||||
|
} `yaml:"redis"`
|
||||||
|
|
||||||
|
Kafka struct {
|
||||||
|
Username string `yaml:"username"`
|
||||||
|
Password string `yaml:"password"`
|
||||||
|
Addr []string `yaml:"addr"`
|
||||||
|
LatestMsgToRedis struct {
|
||||||
|
Topic string `yaml:"topic"`
|
||||||
|
} `yaml:"latestMsgToRedis"`
|
||||||
|
MsgToMongo struct {
|
||||||
|
Topic string `yaml:"topic"`
|
||||||
|
} `yaml:"offlineMsgToMongo"`
|
||||||
|
MsgToPush struct {
|
||||||
|
Topic string `yaml:"topic"`
|
||||||
|
} `yaml:"msgToPush"`
|
||||||
|
ConsumerGroupID struct {
|
||||||
|
MsgToRedis string `yaml:"msgToRedis"`
|
||||||
|
MsgToMongo string `yaml:"msgToMongo"`
|
||||||
|
MsgToMySql string `yaml:"msgToMySql"`
|
||||||
|
MsgToPush string `yaml:"msgToPush"`
|
||||||
|
} `yaml:"consumerGroupID"`
|
||||||
|
} `yaml:"kafka"`
|
||||||
|
|
||||||
|
Rpc struct {
|
||||||
|
RegisterIP string `yaml:"registerIP"`
|
||||||
|
ListenIP string `yaml:"listenIP"`
|
||||||
|
} `yaml:"rpc"`
|
||||||
|
|
||||||
|
Api struct {
|
||||||
|
OpenImApiPort []int `yaml:"openImApiPort"`
|
||||||
|
ListenIP string `yaml:"listenIP"`
|
||||||
|
} `yaml:"api"`
|
||||||
|
|
||||||
|
Object struct {
|
||||||
|
Enable string `yaml:"enable"`
|
||||||
|
ApiURL string `yaml:"apiURL"`
|
||||||
|
Minio struct {
|
||||||
|
Bucket string `yaml:"bucket"`
|
||||||
|
Endpoint string `yaml:"endpoint"`
|
||||||
|
AccessKeyID string `yaml:"accessKeyID"`
|
||||||
|
SecretAccessKey string `yaml:"secretAccessKey"`
|
||||||
|
SessionToken string `yaml:"sessionToken"`
|
||||||
|
} `yaml:"minio"`
|
||||||
|
Cos struct {
|
||||||
|
BucketURL string `yaml:"bucketURL"`
|
||||||
|
SecretID string `yaml:"secretID"`
|
||||||
|
SecretKey string `yaml:"secretKey"`
|
||||||
|
SessionToken string `yaml:"sessionToken"`
|
||||||
|
} `yaml:"cos"`
|
||||||
|
Oss struct {
|
||||||
|
Endpoint string `yaml:"endpoint"`
|
||||||
|
Bucket string `yaml:"bucket"`
|
||||||
|
BucketURL string `yaml:"bucketURL"`
|
||||||
|
AccessKeyID string `yaml:"accessKeyID"`
|
||||||
|
AccessKeySecret string `yaml:"accessKeySecret"`
|
||||||
|
SessionToken string `yaml:"sessionToken"`
|
||||||
|
} `yaml:"oss"`
|
||||||
|
} `yaml:"object"`
|
||||||
|
|
||||||
|
RpcPort struct {
|
||||||
|
OpenImUserPort []int `yaml:"openImUserPort"`
|
||||||
|
OpenImFriendPort []int `yaml:"openImFriendPort"`
|
||||||
|
OpenImMessagePort []int `yaml:"openImMessagePort"`
|
||||||
|
OpenImMessageGatewayPort []int `yaml:"openImMessageGatewayPort"`
|
||||||
|
OpenImGroupPort []int `yaml:"openImGroupPort"`
|
||||||
|
OpenImAuthPort []int `yaml:"openImAuthPort"`
|
||||||
|
OpenImPushPort []int `yaml:"openImPushPort"`
|
||||||
|
OpenImConversationPort []int `yaml:"openImConversationPort"`
|
||||||
|
OpenImRtcPort []int `yaml:"openImRtcPort"`
|
||||||
|
OpenImThirdPort []int `yaml:"openImThirdPort"`
|
||||||
|
} `yaml:"rpcPort"`
|
||||||
|
|
||||||
|
RpcRegisterName struct {
|
||||||
|
OpenImUserName string `yaml:"openImUserName"`
|
||||||
|
OpenImFriendName string `yaml:"openImFriendName"`
|
||||||
|
OpenImMsgName string `yaml:"openImMsgName"`
|
||||||
|
OpenImPushName string `yaml:"openImPushName"`
|
||||||
|
OpenImMessageGatewayName string `yaml:"openImMessageGatewayName"`
|
||||||
|
OpenImGroupName string `yaml:"openImGroupName"`
|
||||||
|
OpenImAuthName string `yaml:"openImAuthName"`
|
||||||
|
OpenImConversationName string `yaml:"openImConversationName"`
|
||||||
|
OpenImThirdName string `yaml:"openImThirdName"`
|
||||||
|
} `yaml:"rpcRegisterName"`
|
||||||
|
|
||||||
|
Log struct {
|
||||||
|
StorageLocation string `yaml:"storageLocation"`
|
||||||
|
RotationTime uint `yaml:"rotationTime"`
|
||||||
|
RemainRotationCount uint `yaml:"remainRotationCount"`
|
||||||
|
RemainLogLevel int `yaml:"remainLogLevel"`
|
||||||
|
IsStdout bool `yaml:"isStdout"`
|
||||||
|
IsJson bool `yaml:"isJson"`
|
||||||
|
WithStack bool `yaml:"withStack"`
|
||||||
|
} `yaml:"log"`
|
||||||
|
|
||||||
|
LongConnSvr struct {
|
||||||
|
OpenImWsPort []int `yaml:"openImWsPort"`
|
||||||
|
WebsocketMaxConnNum int `yaml:"websocketMaxConnNum"`
|
||||||
|
WebsocketMaxMsgLen int `yaml:"websocketMaxMsgLen"`
|
||||||
|
WebsocketTimeout int `yaml:"websocketTimeout"`
|
||||||
|
} `yaml:"longConnSvr"`
|
||||||
|
|
||||||
|
Push struct {
|
||||||
|
Enable string `yaml:"enable"`
|
||||||
|
GeTui struct {
|
||||||
|
PushUrl string `yaml:"pushUrl"`
|
||||||
|
AppKey string `yaml:"appKey"`
|
||||||
|
Intent string `yaml:"intent"`
|
||||||
|
MasterSecret string `yaml:"masterSecret"`
|
||||||
|
ChannelID string `yaml:"channelID"`
|
||||||
|
ChannelName string `yaml:"channelName"`
|
||||||
|
} `yaml:"geTui"`
|
||||||
|
Fcm struct {
|
||||||
|
ServiceAccount string `yaml:"serviceAccount"`
|
||||||
|
} `yaml:"fcm"`
|
||||||
|
Jpns struct {
|
||||||
|
AppKey string `yaml:"appKey"`
|
||||||
|
MasterSecret string `yaml:"masterSecret"`
|
||||||
|
PushUrl string `yaml:"pushUrl"`
|
||||||
|
PushIntent string `yaml:"pushIntent"`
|
||||||
|
} `yaml:"jpns"`
|
||||||
|
}
|
||||||
|
Manager struct {
|
||||||
|
UserID []string `yaml:"userID"`
|
||||||
|
Nickname []string `yaml:"nickname"`
|
||||||
|
} `yaml:"manager"`
|
||||||
|
|
||||||
|
MultiLoginPolicy int `yaml:"multiLoginPolicy"`
|
||||||
|
ChatPersistenceMysql bool `yaml:"chatPersistenceMysql"`
|
||||||
|
MsgCacheTimeout int `yaml:"msgCacheTimeout"`
|
||||||
|
GroupMessageHasReadReceiptEnable bool `yaml:"groupMessageHasReadReceiptEnable"`
|
||||||
|
SingleMessageHasReadReceiptEnable bool `yaml:"singleMessageHasReadReceiptEnable"`
|
||||||
|
RetainChatRecords int `yaml:"retainChatRecords"`
|
||||||
|
ChatRecordsClearTime string `yaml:"chatRecordsClearTime"`
|
||||||
|
MsgDestructTime string `yaml:"msgDestructTime"`
|
||||||
|
Secret string `yaml:"secret"`
|
||||||
|
TokenPolicy struct {
|
||||||
|
Expire int64 `yaml:"expire"`
|
||||||
|
} `yaml:"tokenPolicy"`
|
||||||
|
MessageVerify struct {
|
||||||
|
FriendVerify *bool `yaml:"friendVerify"`
|
||||||
|
} `yaml:"messageVerify"`
|
||||||
|
|
||||||
|
IOSPush struct {
|
||||||
|
PushSound string `yaml:"pushSound"`
|
||||||
|
BadgeCount bool `yaml:"badgeCount"`
|
||||||
|
Production bool `yaml:"production"`
|
||||||
|
} `yaml:"iosPush"`
|
||||||
|
Callback struct {
|
||||||
|
CallbackUrl string `yaml:"url"`
|
||||||
|
CallbackBeforeSendSingleMsg CallBackConfig `yaml:"beforeSendSingleMsg"`
|
||||||
|
CallbackAfterSendSingleMsg CallBackConfig `yaml:"afterSendSingleMsg"`
|
||||||
|
CallbackBeforeSendGroupMsg CallBackConfig `yaml:"beforeSendGroupMsg"`
|
||||||
|
CallbackAfterSendGroupMsg CallBackConfig `yaml:"afterSendGroupMsg"`
|
||||||
|
CallbackMsgModify CallBackConfig `yaml:"msgModify"`
|
||||||
|
CallbackUserOnline CallBackConfig `yaml:"userOnline"`
|
||||||
|
CallbackUserOffline CallBackConfig `yaml:"userOffline"`
|
||||||
|
CallbackUserKickOff CallBackConfig `yaml:"userKickOff"`
|
||||||
|
CallbackOfflinePush CallBackConfig `yaml:"offlinePush"`
|
||||||
|
CallbackOnlinePush CallBackConfig `yaml:"onlinePush"`
|
||||||
|
CallbackBeforeSuperGroupOnlinePush CallBackConfig `yaml:"superGroupOnlinePush"`
|
||||||
|
CallbackBeforeAddFriend CallBackConfig `yaml:"beforeAddFriend"`
|
||||||
|
CallbackBeforeCreateGroup CallBackConfig `yaml:"beforeCreateGroup"`
|
||||||
|
CallbackBeforeMemberJoinGroup CallBackConfig `yaml:"beforeMemberJoinGroup"`
|
||||||
|
CallbackBeforeSetGroupMemberInfo CallBackConfig `yaml:"beforeSetGroupMemberInfo"`
|
||||||
|
} `yaml:"callback"`
|
||||||
|
|
||||||
|
Prometheus struct {
|
||||||
|
Enable bool `yaml:"enable"`
|
||||||
|
UserPrometheusPort []int `yaml:"userPrometheusPort"`
|
||||||
|
FriendPrometheusPort []int `yaml:"friendPrometheusPort"`
|
||||||
|
MessagePrometheusPort []int `yaml:"messagePrometheusPort"`
|
||||||
|
MessageGatewayPrometheusPort []int `yaml:"messageGatewayPrometheusPort"`
|
||||||
|
GroupPrometheusPort []int `yaml:"groupPrometheusPort"`
|
||||||
|
AuthPrometheusPort []int `yaml:"authPrometheusPort"`
|
||||||
|
PushPrometheusPort []int `yaml:"pushPrometheusPort"`
|
||||||
|
ConversationPrometheusPort []int `yaml:"conversationPrometheusPort"`
|
||||||
|
RtcPrometheusPort []int `yaml:"rtcPrometheusPort"`
|
||||||
|
MessageTransferPrometheusPort []int `yaml:"messageTransferPrometheusPort"`
|
||||||
|
ThirdPrometheusPort []int `yaml:"thirdPrometheusPort"`
|
||||||
|
} `yaml:"prometheus"`
|
||||||
|
Notification notification `yaml:"notification"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type notification struct {
|
||||||
|
GroupCreated NotificationConf `yaml:"groupCreated"`
|
||||||
|
GroupInfoSet NotificationConf `yaml:"groupInfoSet"`
|
||||||
|
JoinGroupApplication NotificationConf `yaml:"joinGroupApplication"`
|
||||||
|
MemberQuit NotificationConf `yaml:"memberQuit"`
|
||||||
|
GroupApplicationAccepted NotificationConf `yaml:"groupApplicationAccepted"`
|
||||||
|
GroupApplicationRejected NotificationConf `yaml:"groupApplicationRejected"`
|
||||||
|
GroupOwnerTransferred NotificationConf `yaml:"groupOwnerTransferred"`
|
||||||
|
MemberKicked NotificationConf `yaml:"memberKicked"`
|
||||||
|
MemberInvited NotificationConf `yaml:"memberInvited"`
|
||||||
|
MemberEnter NotificationConf `yaml:"memberEnter"`
|
||||||
|
GroupDismissed NotificationConf `yaml:"groupDismissed"`
|
||||||
|
GroupMuted NotificationConf `yaml:"groupMuted"`
|
||||||
|
GroupCancelMuted NotificationConf `yaml:"groupCancelMuted"`
|
||||||
|
GroupMemberMuted NotificationConf `yaml:"groupMemberMuted"`
|
||||||
|
GroupMemberCancelMuted NotificationConf `yaml:"groupMemberCancelMuted"`
|
||||||
|
GroupMemberInfoSet NotificationConf `yaml:"groupMemberInfoSet"`
|
||||||
|
GroupMemberSetToAdmin NotificationConf `yaml:"groupMemberSetToAdmin"`
|
||||||
|
GroupMemberSetToOrdinary NotificationConf `yaml:"groupMemberSetToOrdinaryUser"`
|
||||||
|
GroupInfoSetAnnouncement NotificationConf `yaml:"groupInfoSetAnnouncement"`
|
||||||
|
GroupInfoSetName NotificationConf `yaml:"groupInfoSetName"`
|
||||||
|
////////////////////////user///////////////////////
|
||||||
|
UserInfoUpdated NotificationConf `yaml:"userInfoUpdated"`
|
||||||
|
//////////////////////friend///////////////////////
|
||||||
|
FriendApplicationAdded NotificationConf `yaml:"friendApplicationAdded"`
|
||||||
|
FriendApplicationApproved NotificationConf `yaml:"friendApplicationApproved"`
|
||||||
|
FriendApplicationRejected NotificationConf `yaml:"friendApplicationRejected"`
|
||||||
|
FriendAdded NotificationConf `yaml:"friendAdded"`
|
||||||
|
FriendDeleted NotificationConf `yaml:"friendDeleted"`
|
||||||
|
FriendRemarkSet NotificationConf `yaml:"friendRemarkSet"`
|
||||||
|
BlackAdded NotificationConf `yaml:"blackAdded"`
|
||||||
|
BlackDeleted NotificationConf `yaml:"blackDeleted"`
|
||||||
|
FriendInfoUpdated NotificationConf `yaml:"friendInfoUpdated"`
|
||||||
|
//////////////////////conversation///////////////////////
|
||||||
|
ConversationChanged NotificationConf `yaml:"conversationChanged"`
|
||||||
|
ConversationSetPrivate NotificationConf `yaml:"conversationSetPrivate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *configStruct) GetServiceNames() []string {
|
||||||
|
return []string{
|
||||||
|
c.RpcRegisterName.OpenImUserName,
|
||||||
|
c.RpcRegisterName.OpenImFriendName,
|
||||||
|
c.RpcRegisterName.OpenImMsgName,
|
||||||
|
c.RpcRegisterName.OpenImPushName,
|
||||||
|
c.RpcRegisterName.OpenImMessageGatewayName,
|
||||||
|
c.RpcRegisterName.OpenImGroupName,
|
||||||
|
c.RpcRegisterName.OpenImAuthName,
|
||||||
|
c.RpcRegisterName.OpenImConversationName,
|
||||||
|
c.RpcRegisterName.OpenImThirdName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *configStruct) RegisterConf2Registry(registry discoveryregistry.SvcDiscoveryRegistry) error {
|
||||||
|
data, err := yaml.Marshal(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return registry.RegisterConf2Registry(ConfKey, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *configStruct) GetConfFromRegistry(registry discoveryregistry.SvcDiscoveryRegistry) ([]byte, error) {
|
||||||
|
return registry.GetConfFromRegistry(ConfKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *configStruct) EncodeConfig() []byte {
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
if err := yaml.NewEncoder(buf).Encode(c); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
// 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 startrpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry/zookeeper"
|
||||||
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/mw"
|
||||||
|
"github.com/OpenIMSDK/tools/network"
|
||||||
|
"github.com/OpenIMSDK/tools/prome"
|
||||||
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Start(
|
||||||
|
rpcPort int,
|
||||||
|
rpcRegisterName string,
|
||||||
|
prometheusPort int,
|
||||||
|
rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error,
|
||||||
|
options ...grpc.ServerOption,
|
||||||
|
) error {
|
||||||
|
fmt.Println(
|
||||||
|
"start",
|
||||||
|
rpcRegisterName,
|
||||||
|
"server, port: ",
|
||||||
|
rpcPort,
|
||||||
|
"prometheusPort:",
|
||||||
|
prometheusPort,
|
||||||
|
", OpenIM version: ",
|
||||||
|
config.Version,
|
||||||
|
)
|
||||||
|
listener, err := net.Listen(
|
||||||
|
"tcp",
|
||||||
|
net.JoinHostPort(network.GetListenIP(config.Config.Rpc.ListenIP), strconv.Itoa(rpcPort)),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer listener.Close()
|
||||||
|
zkClient, err := zookeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
|
||||||
|
zookeeper.WithFreq(time.Hour), zookeeper.WithUserNameAndPassword(
|
||||||
|
config.Config.Zookeeper.Username,
|
||||||
|
config.Config.Zookeeper.Password,
|
||||||
|
), zookeeper.WithRoundRobin(), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))
|
||||||
|
if err != nil {
|
||||||
|
return utils.Wrap1(err)
|
||||||
|
}
|
||||||
|
defer zkClient.CloseZK()
|
||||||
|
zkClient.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||||
|
registerIP, err := network.GetRpcRegisterIP(config.Config.Rpc.RegisterIP)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// ctx 中间件
|
||||||
|
if config.Config.Prometheus.Enable {
|
||||||
|
prome.NewGrpcRequestCounter()
|
||||||
|
prome.NewGrpcRequestFailedCounter()
|
||||||
|
prome.NewGrpcRequestSuccessCounter()
|
||||||
|
unaryInterceptor := mw.InterceptChain(grpcPrometheus.UnaryServerInterceptor, mw.RpcServerInterceptor)
|
||||||
|
options = append(options, []grpc.ServerOption{
|
||||||
|
grpc.StreamInterceptor(grpcPrometheus.StreamServerInterceptor),
|
||||||
|
grpc.UnaryInterceptor(unaryInterceptor),
|
||||||
|
}...)
|
||||||
|
} else {
|
||||||
|
options = append(options, mw.GrpcServer())
|
||||||
|
}
|
||||||
|
srv := grpc.NewServer(options...)
|
||||||
|
defer srv.GracefulStop()
|
||||||
|
err = rpcFn(zkClient, srv)
|
||||||
|
if err != nil {
|
||||||
|
return utils.Wrap1(err)
|
||||||
|
}
|
||||||
|
err = zkClient.Register(
|
||||||
|
rpcRegisterName,
|
||||||
|
registerIP,
|
||||||
|
rpcPort,
|
||||||
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return utils.Wrap1(err)
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
if config.Config.Prometheus.Enable && prometheusPort != 0 {
|
||||||
|
if err := prome.StartPrometheusSrv(prometheusPort); err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return utils.Wrap1(srv.Serve(listener))
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
package msgprocessor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetNotificationConversationID(msg *sdkws.MsgData) string {
|
||||||
|
switch msg.SessionType {
|
||||||
|
case constant.SingleChatType:
|
||||||
|
l := []string{msg.SendID, msg.RecvID}
|
||||||
|
sort.Strings(l)
|
||||||
|
return "n_" + strings.Join(l, "_")
|
||||||
|
case constant.GroupChatType:
|
||||||
|
return "n_" + msg.GroupID
|
||||||
|
case constant.SuperGroupChatType:
|
||||||
|
return "n_" + msg.GroupID
|
||||||
|
case constant.NotificationChatType:
|
||||||
|
return "n_" + msg.SendID + "_" + msg.RecvID
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetChatConversationIDByMsg(msg *sdkws.MsgData) string {
|
||||||
|
switch msg.SessionType {
|
||||||
|
case constant.SingleChatType:
|
||||||
|
l := []string{msg.SendID, msg.RecvID}
|
||||||
|
sort.Strings(l)
|
||||||
|
return "si_" + strings.Join(l, "_")
|
||||||
|
case constant.GroupChatType:
|
||||||
|
return "g_" + msg.GroupID
|
||||||
|
case constant.SuperGroupChatType:
|
||||||
|
return "sg_" + msg.GroupID
|
||||||
|
case constant.NotificationChatType:
|
||||||
|
return "sn_" + msg.SendID + "_" + msg.RecvID
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenConversationUniqueKey(msg *sdkws.MsgData) string {
|
||||||
|
switch msg.SessionType {
|
||||||
|
case constant.SingleChatType, constant.NotificationChatType:
|
||||||
|
l := []string{msg.SendID, msg.RecvID}
|
||||||
|
sort.Strings(l)
|
||||||
|
return strings.Join(l, "_")
|
||||||
|
case constant.SuperGroupChatType:
|
||||||
|
return msg.GroupID
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConversationIDByMsg(msg *sdkws.MsgData) string {
|
||||||
|
options := Options(msg.Options)
|
||||||
|
switch msg.SessionType {
|
||||||
|
case constant.SingleChatType:
|
||||||
|
l := []string{msg.SendID, msg.RecvID}
|
||||||
|
sort.Strings(l)
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return "n_" + strings.Join(l, "_")
|
||||||
|
}
|
||||||
|
return "si_" + strings.Join(l, "_") // single chat
|
||||||
|
case constant.GroupChatType:
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return "n_" + msg.GroupID // group chat
|
||||||
|
}
|
||||||
|
return "g_" + msg.GroupID // group chat
|
||||||
|
case constant.SuperGroupChatType:
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return "n_" + msg.GroupID // super group chat
|
||||||
|
}
|
||||||
|
return "sg_" + msg.GroupID // super group chat
|
||||||
|
case constant.NotificationChatType:
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return "n_" + msg.SendID + "_" + msg.RecvID // super group chat
|
||||||
|
}
|
||||||
|
return "sn_" + msg.SendID + "_" + msg.RecvID // server notification chat
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConversationIDBySessionType(sessionType int, ids ...string) string {
|
||||||
|
sort.Strings(ids)
|
||||||
|
if len(ids) > 2 || len(ids) < 1 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
switch sessionType {
|
||||||
|
case constant.SingleChatType:
|
||||||
|
return "si_" + strings.Join(ids, "_") // single chat
|
||||||
|
case constant.GroupChatType:
|
||||||
|
return "g_" + ids[0] // group chat
|
||||||
|
case constant.SuperGroupChatType:
|
||||||
|
return "sg_" + ids[0] // super group chat
|
||||||
|
case constant.NotificationChatType:
|
||||||
|
return "sn_" + ids[0] // server notification chat
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsNotification(conversationID string) bool {
|
||||||
|
return strings.HasPrefix(conversationID, "n_")
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsNotificationByMsg(msg *sdkws.MsgData) bool {
|
||||||
|
return !Options(msg.Options).IsNotNotification()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseConversationID(msg *sdkws.MsgData) (isNotification bool, conversationID string) {
|
||||||
|
options := Options(msg.Options)
|
||||||
|
switch msg.SessionType {
|
||||||
|
case constant.SingleChatType:
|
||||||
|
l := []string{msg.SendID, msg.RecvID}
|
||||||
|
sort.Strings(l)
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return true, "n_" + strings.Join(l, "_")
|
||||||
|
}
|
||||||
|
return false, "si_" + strings.Join(l, "_") // single chat
|
||||||
|
case constant.SuperGroupChatType:
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return true, "n_" + msg.GroupID // super group chat
|
||||||
|
}
|
||||||
|
return false, "sg_" + msg.GroupID // super group chat
|
||||||
|
case constant.NotificationChatType:
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return true, "n_" + msg.SendID + "_" + msg.RecvID // super group chat
|
||||||
|
}
|
||||||
|
return false, "sn_" + msg.SendID + "_" + msg.RecvID // server notification chat
|
||||||
|
}
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type MsgBySeq []*sdkws.MsgData
|
||||||
|
|
||||||
|
func (s MsgBySeq) Len() int {
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s MsgBySeq) Less(i, j int) bool {
|
||||||
|
return s[i].Seq < s[j].Seq
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s MsgBySeq) Swap(i, j int) {
|
||||||
|
s[i], s[j] = s[j], s[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pb2String(pb proto.Message) (string, error) {
|
||||||
|
s, err := proto.Marshal(pb)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(s), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func String2Pb(s string, pb proto.Message) error {
|
||||||
|
return proto.Unmarshal([]byte(s), pb)
|
||||||
|
}
|
@ -0,0 +1,181 @@
|
|||||||
|
// 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 msgprocessor
|
||||||
|
|
||||||
|
import "github.com/OpenIMSDK/protocol/constant"
|
||||||
|
|
||||||
|
type Options map[string]bool
|
||||||
|
type OptionsOpt func(Options)
|
||||||
|
|
||||||
|
func NewOptions(opts ...OptionsOpt) Options {
|
||||||
|
options := make(map[string]bool, 11)
|
||||||
|
options[constant.IsNotNotification] = false
|
||||||
|
options[constant.IsSendMsg] = false
|
||||||
|
options[constant.IsHistory] = false
|
||||||
|
options[constant.IsPersistent] = false
|
||||||
|
options[constant.IsOfflinePush] = false
|
||||||
|
options[constant.IsUnreadCount] = false
|
||||||
|
options[constant.IsConversationUpdate] = false
|
||||||
|
options[constant.IsSenderSync] = false
|
||||||
|
options[constant.IsNotPrivate] = false
|
||||||
|
options[constant.IsSenderConversationUpdate] = false
|
||||||
|
options[constant.IsSenderNotificationPush] = false
|
||||||
|
options[constant.IsReactionFromCache] = false
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(options)
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMsgOptions() Options {
|
||||||
|
options := make(map[string]bool, 11)
|
||||||
|
options[constant.IsOfflinePush] = false
|
||||||
|
return make(map[string]bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithOptions(options Options, opts ...OptionsOpt) Options {
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(options)
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithNotNotification(b bool) OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsNotNotification] = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSendMsg(b bool) OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsSendMsg] = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithHistory(b bool) OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsHistory] = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithPersistent() OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsPersistent] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithOfflinePush(b bool) OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsOfflinePush] = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithUnreadCount(b bool) OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsUnreadCount] = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithConversationUpdate() OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsConversationUpdate] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSenderSync() OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsSenderSync] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithNotPrivate() OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsNotPrivate] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSenderConversationUpdate() OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsSenderConversationUpdate] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSenderNotificationPush() OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsSenderNotificationPush] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithReactionFromCache() OptionsOpt {
|
||||||
|
return func(options Options) {
|
||||||
|
options[constant.IsReactionFromCache] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) Is(notification string) bool {
|
||||||
|
v, ok := o[notification]
|
||||||
|
if !ok || v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsNotNotification() bool {
|
||||||
|
return o.Is(constant.IsNotNotification)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsSendMsg() bool {
|
||||||
|
return o.Is(constant.IsSendMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsHistory() bool {
|
||||||
|
return o.Is(constant.IsHistory)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsPersistent() bool {
|
||||||
|
return o.Is(constant.IsPersistent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsOfflinePush() bool {
|
||||||
|
return o.Is(constant.IsOfflinePush)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsUnreadCount() bool {
|
||||||
|
return o.Is(constant.IsUnreadCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsConversationUpdate() bool {
|
||||||
|
return o.Is(constant.IsConversationUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsSenderSync() bool {
|
||||||
|
return o.Is(constant.IsSenderSync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsNotPrivate() bool {
|
||||||
|
return o.Is(constant.IsNotPrivate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsSenderConversationUpdate() bool {
|
||||||
|
return o.Is(constant.IsSenderConversationUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsSenderNotificationPush() bool {
|
||||||
|
return o.Is(constant.IsSenderNotificationPush)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Options) IsReactionFromCache() bool {
|
||||||
|
return o.Is(constant.IsReactionFromCache)
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue