diff --git a/internal/api/msg.go b/internal/api/msg.go index d8a3c292b..8ad7943e9 100644 --- a/internal/api/msg.go +++ b/internal/api/msg.go @@ -214,6 +214,7 @@ func (m *MessageApi) SendMessage(c *gin.Context) { if err != nil { log.ZError(c, "decodeData failed", err) apiresp.GinError(c, err) + return } sendMsgReq.MsgData.RecvID = req.RecvID var status int @@ -260,6 +261,7 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) { if err != nil { log.ZError(c, "GetAllUserIDs failed", err) apiresp.GinError(c, err) + return } if len(recvIDsPart) < showNumber { recvIDs = append(recvIDs, recvIDsPart...) @@ -275,6 +277,7 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) { if err != nil { log.ZError(c, "decodeData failed", err) apiresp.GinError(c, err) + return } for _, recvID := range recvIDs { sendMsgReq.MsgData.RecvID = recvID diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 5b756bf92..6d852515c 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -176,13 +176,12 @@ func (s *Server) KickUserOffline( if clients, _, ok := s.LongConnServer.GetUserPlatformCons(v, int(req.PlatformID)); ok { for _, client := range clients { log.ZDebug(ctx, "kick user offline", "userID", v, "platformID", req.PlatformID, "client", client) - err := client.KickOnlineMessage() - if err != nil { - return nil, err + if err := client.longConnServer.KickUserConn(client); err != nil { + log.ZWarn(ctx, "kick user offline failed", err, "userID", v, "platformID", req.PlatformID) } } } else { - log.ZWarn(ctx, "conn not exist", nil, "userID", v, "platformID", req.PlatformID) + log.ZInfo(ctx, "conn not exist", "userID", v, "platformID", req.PlatformID) } } return &msggateway.KickUserOfflineResp{}, nil diff --git a/internal/msggateway/n_ws_server.go b/internal/msggateway/n_ws_server.go index 2988e2c08..c2b46cf1f 100644 --- a/internal/msggateway/n_ws_server.go +++ b/internal/msggateway/n_ws_server.go @@ -47,6 +47,7 @@ type LongConnServer interface { Validate(s interface{}) error SetCacheHandler(cache cache.MsgModel) SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry) + KickUserConn(client *Client) error UnRegister(c *Client) Compressor Encoder @@ -145,7 +146,7 @@ func (ws *WsServer) Run() error { case client = <-ws.unregisterChan: ws.unregisterClient(client) case onlineInfo := <-ws.kickHandlerChan: - ws.multiTerminalLoginChecker(onlineInfo) + ws.multiTerminalLoginChecker(onlineInfo.clientOK, onlineInfo.oldClients, onlineInfo.newClient) } } }() @@ -207,80 +208,77 @@ func getRemoteAdders(client []*Client) string { return ret } -func (ws *WsServer) multiTerminalLoginChecker(info *kickHandler) { +func (ws *WsServer) KickUserConn(client *Client) error { + ws.clients.deleteClients(client.UserID, []*Client{client}) + return client.KickOnlineMessage() +} + +func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) { switch config.Config.MultiLoginPolicy { case constant.DefalutNotKick: case constant.PCAndOther: - if constant.PlatformIDToClass(info.newClient.PlatformID) == constant.TerminalPC { + if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC { return } fallthrough case constant.AllLoginButSameTermKick: - if info.clientOK { - ws.clients.deleteClients(info.newClient.UserID, info.oldClients) - for _, c := range info.oldClients { + if clientOK { + ws.clients.deleteClients(newClient.UserID, oldClients) + for _, c := range oldClients { err := c.KickOnlineMessage() if err != nil { log.ZWarn(c.ctx, "KickOnlineMessage", err) } } m, err := ws.cache.GetTokensWithoutError( - info.newClient.ctx, - info.newClient.UserID, - info.newClient.PlatformID, + newClient.ctx, + newClient.UserID, + newClient.PlatformID, ) if err != nil && err != redis.Nil { log.ZWarn( - info.newClient.ctx, + newClient.ctx, "get token from redis err", err, "userID", - info.newClient.UserID, + newClient.UserID, "platformID", - info.newClient.PlatformID, + newClient.PlatformID, ) return } if m == nil { log.ZWarn( - info.newClient.ctx, + newClient.ctx, "m is nil", errors.New("m is nil"), "userID", - info.newClient.UserID, + newClient.UserID, "platformID", - info.newClient.PlatformID, + newClient.PlatformID, ) return } log.ZDebug( - info.newClient.ctx, + newClient.ctx, "get token from redis", "userID", - info.newClient.UserID, + newClient.UserID, "platformID", - info.newClient.PlatformID, + newClient.PlatformID, "tokenMap", m, ) for k := range m { - if k != info.newClient.ctx.GetToken() { + if k != newClient.ctx.GetToken() { m[k] = constant.KickedToken } } - log.ZDebug(info.newClient.ctx, "set token map is ", "token map", m, "userID", info.newClient.UserID) - err = ws.cache.SetTokenMapByUidPid(info.newClient.ctx, info.newClient.UserID, info.newClient.PlatformID, m) + log.ZDebug(newClient.ctx, "set token map is ", "token map", m, "userID", newClient.UserID) + err = ws.cache.SetTokenMapByUidPid(newClient.ctx, newClient.UserID, newClient.PlatformID, m) if err != nil { - log.ZWarn( - info.newClient.ctx, - "SetTokenMapByUidPid err", - err, - "userID", - info.newClient.UserID, - "platformID", - info.newClient.PlatformID, - ) + log.ZWarn(newClient.ctx, "SetTokenMapByUidPid err", err, "userID", newClient.UserID, "platformID", newClient.PlatformID) return } } diff --git a/internal/rpc/auth/auth.go b/internal/rpc/auth/auth.go index 48e21fbce..317754743 100644 --- a/internal/rpc/auth/auth.go +++ b/internal/rpc/auth/auth.go @@ -23,6 +23,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" @@ -129,11 +130,16 @@ func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID if err != nil { return err } + for _, v := range conns { + log.ZDebug(ctx, "forceKickOff", "conn", v.(*grpc.ClientConn).Target()) + } for _, v := range conns { client := msggateway.NewMsgGatewayClient(v) kickReq := &msggateway.KickUserOfflineReq{KickUserIDList: []string{userID}, PlatformID: platformID} _, err := client.KickUserOffline(ctx, kickReq) - return utils.Wrap(err, "") + if err != nil { + log.ZError(ctx, "forceKickOff", err, "kickReq", kickReq) + } } return nil } diff --git a/internal/rpc/msg/server.go b/internal/rpc/msg/server.go index 1a152b7be..5e2cf925f 100644 --- a/internal/rpc/msg/server.go +++ b/internal/rpc/msg/server.go @@ -17,9 +17,6 @@ package msg import ( "context" - - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation" - "google.golang.org/grpc" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" diff --git a/internal/rpc/msg/sync_msg.go b/internal/rpc/msg/sync_msg.go index 8cfac93bd..70967a1ba 100644 --- a/internal/rpc/msg/sync_msg.go +++ b/internal/rpc/msg/sync_msg.go @@ -108,11 +108,11 @@ func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sd func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (resp *msg.SearchMessageResp, err error) { var chatLogs []*sdkws.MsgData + var total int32 resp = &msg.SearchMessageResp{} - if chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil { + if total, chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil { return nil, err } - var num int for _, chatLog := range chatLogs { pbChatLog := &msg.ChatLog{} utils.CopyStructFields(pbChatLog, chatLog) @@ -146,9 +146,8 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq pbChatLog.GroupType = group.GroupType } resp.ChatLogs = append(resp.ChatLogs, pbChatLog) - num++ } - resp.ChatLogsNum = int32(num) + resp.ChatLogsNum = total return resp, nil } diff --git a/internal/tools/cron_task.go b/internal/tools/cron_task.go index 5e4183615..82343157b 100644 --- a/internal/tools/cron_task.go +++ b/internal/tools/cron_task.go @@ -41,11 +41,11 @@ func StartCronTask() error { panic(err) } log.ZInfo(context.Background(), "start msgDestruct cron task", "cron config", config.Config.MsgDestructTime) - _, err = c.AddFunc(config.Config.MsgDestructTime, msgTool.ConversationsDestructMsgs) - if err != nil { - fmt.Println("start conversationsDestructMsgs cron failed", err.Error(), config.Config.ChatRecordsClearTime) - panic(err) - } + // _, err = c.AddFunc(config.Config.MsgDestructTime, msgTool.ConversationsDestructMsgs) + // if err != nil { + // fmt.Println("start conversationsDestructMsgs cron failed", err.Error(), config.Config.ChatRecordsClearTime) + // panic(err) + // } c.Start() wg.Wait() return nil diff --git a/pkg/common/db/controller/msg.go b/pkg/common/db/controller/msg.go index fe72396ce..37a71bafa 100644 --- a/pkg/common/db/controller/msg.go +++ b/pkg/common/db/controller/msg.go @@ -15,16 +15,10 @@ package controller import ( - "context" "errors" "time" - "gorm.io/gorm" - - relation2 "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation" - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation" - "github.com/redis/go-redis/v9" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" @@ -98,7 +92,7 @@ type CommonMsgDatabase interface { GetConversationMinMaxSeqInMongoAndCache(ctx context.Context, conversationID string) (minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache int64, err error) SetSendMsgStatus(ctx context.Context, id string, status int32) error GetSendMsgStatus(ctx context.Context, id string) (int32, error) - SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (msgData []*sdkws.MsgData, err error) + SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (total int32, msgData []*sdkws.MsgData, err error) // to mq MsgToMQ(ctx context.Context, key string, msg2mq *sdkws.MsgData) error @@ -946,14 +940,14 @@ func (db *commonMsgDatabase) RangeGroupSendCount( return db.msgDocDatabase.RangeGroupSendCount(ctx, start, end, ase, pageNumber, showNumber) } -func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (msgData []*sdkws.MsgData, err error) { +func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (total int32, msgData []*sdkws.MsgData, err error) { var totalMsgs []*sdkws.MsgData - msgs, err := db.msgDocDatabase.SearchMessage(ctx, req) + total, msgs, err := db.msgDocDatabase.SearchMessage(ctx, req) if err != nil { - return nil, err + return 0, nil, err } for _, msg := range msgs { totalMsgs = append(totalMsgs, convert.MsgDB2Pb(msg.Msg)) } - return totalMsgs, nil + return total, totalMsgs, nil } diff --git a/pkg/common/db/table/unrelation/msg.go b/pkg/common/db/table/unrelation/msg.go index ac4602d35..dc16613ed 100644 --- a/pkg/common/db/table/unrelation/msg.go +++ b/pkg/common/db/table/unrelation/msg.go @@ -110,7 +110,7 @@ type MsgDocModelInterface interface { GetMsgDocModelByIndex(ctx context.Context, conversationID string, index, sort int64) (*MsgDocModel, error) DeleteMsgsInOneDocByIndex(ctx context.Context, docID string, indexes []int) error MarkSingleChatMsgsAsRead(ctx context.Context, userID string, docID string, indexes []int64) error - SearchMessage(ctx context.Context, req *msg.SearchMessageReq) ([]*MsgInfoModel, error) + SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*MsgInfoModel, error) RangeUserSendCount( ctx context.Context, start time.Time, diff --git a/pkg/common/db/unrelation/msg.go b/pkg/common/db/unrelation/msg.go index 222b70190..b7403ebde 100644 --- a/pkg/common/db/unrelation/msg.go +++ b/pkg/common/db/unrelation/msg.go @@ -1067,20 +1067,20 @@ func (m *MsgMongoDriver) RangeGroupSendCount( return result[0].MsgCount, result[0].UserCount, groups, dateCount, nil } -func (m *MsgMongoDriver) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) ([]*table.MsgInfoModel, error) { - msgs, err := m.searchMessage(ctx, req) +func (m *MsgMongoDriver) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*table.MsgInfoModel, error) { + total, msgs, err := m.searchMessage(ctx, req) if err != nil { - return nil, err + return 0, nil, err } for _, msg1 := range msgs { if msg1.IsRead { msg1.Msg.IsRead = true } } - return msgs, nil + return total, msgs, nil } -func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessageReq) ([]*table.MsgInfoModel, error) { +func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*table.MsgInfoModel, error) { var pipe mongo.Pipeline condition := bson.A{} if req.SendTime != "" { @@ -1153,16 +1153,16 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa } cursor, err := m.MsgCollection.Aggregate(ctx, pipe) if err != nil { - return nil, err + return 0, nil, err } var msgsDocs []table.MsgDocModel err = cursor.All(ctx, &msgsDocs) if err != nil { - return nil, err + return 0, nil, err } if len(msgsDocs) == 0 { - return nil, errs.Wrap(mongo.ErrNoDocuments) + return 0, nil, errs.Wrap(mongo.ErrNoDocuments) } msgs := make([]*table.MsgInfoModel, 0) for index := range msgsDocs { @@ -1187,14 +1187,14 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa } data, err := json.Marshal(&revokeContent) if err != nil { - return nil, err + return 0, nil, err } elem := sdkws.NotificationElem{ Detail: string(data), } content, err := json.Marshal(&elem) if err != nil { - return nil, err + return 0, nil, err } msg.Msg.ContentType = constant.MsgRevokeNotification msg.Msg.Content = string(content) @@ -1209,5 +1209,5 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa } else { msgs = msgs[start:] } - return msgs, nil + return n, msgs, nil } diff --git a/pkg/proto/msg/msg.go b/pkg/proto/msg/msg.go index 62b776856..03c9da915 100644 --- a/pkg/proto/msg/msg.go +++ b/pkg/proto/msg/msg.go @@ -126,6 +126,11 @@ func (x *MarkMsgsAsReadReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + for _, seq := range x.Seqs { + if seq == 0 { + return errs.ErrArgs.Wrap("seqs has 0 value is invalid") + } + } return nil } @@ -139,6 +144,11 @@ func (x *MarkConversationAsReadReq) Check() error { if x.HasReadSeq < 1 { return errs.ErrArgs.Wrap("hasReadSeq is invalid") } + for _, seq := range x.Seqs { + if seq == 0 { + return errs.ErrArgs.Wrap("seqs has 0 value is invalid") + } + } return nil }