github.com/glide-im/glide@v1.6.0/internal/message_handler/offline_handler.go (about)

     1  package message_handler
     2  
     3  import (
     4  	messages2 "github.com/glide-im/glide/im_service/messages"
     5  	"github.com/glide-im/glide/internal/pkg/db"
     6  	"github.com/glide-im/glide/pkg/gate"
     7  	"github.com/glide-im/glide/pkg/logger"
     8  	"github.com/glide-im/glide/pkg/messages"
     9  	"github.com/glide-im/glide/pkg/messaging"
    10  	"time"
    11  )
    12  
    13  const (
    14  	KeyRedisOfflineMsgPrefix = "im:msg:offline:"
    15  )
    16  
    17  var Enable = false
    18  
    19  func GetHandleFn() func(h *MessageHandler, ci *gate.Info, m *messages.GlideMessage) {
    20  	return handler
    21  }
    22  
    23  func handler(_ *MessageHandler, _ *gate.Info, m *messages.GlideMessage) {
    24  	if !Enable {
    25  		return
    26  	}
    27  	if m.GetAction() == messages2.ActionChatMessage || m.GetAction() == messages2.ActionChatMessageResend {
    28  		c := messages.ChatMessage{}
    29  		err := m.Data.Deserialize(&c)
    30  		if err != nil {
    31  			logger.E("deserialize chat message error: %v", err)
    32  			return
    33  		}
    34  		bytes, err := messages.JsonCodec.Encode(m)
    35  		if err != nil {
    36  			logger.E("deserialize chat message error: %v", err)
    37  			return
    38  		}
    39  		storeOfflineMessage(m.To, string(bytes))
    40  	}
    41  }
    42  
    43  func storeOfflineMessage(to string, msg string) {
    44  	key := KeyRedisOfflineMsgPrefix + to
    45  	db.Redis.SAdd(key, msg)
    46  	// TODO 2022-6-22 16:56:57 do not reset expire on new offline message arrived
    47  	// use fixed time segment save offline msg reset segment only.
    48  	db.Redis.Expire(key, time.Hour*24*2)
    49  }
    50  
    51  func PushOfflineMessage(h *messaging.MessageInterfaceImpl, id string) {
    52  	key := KeyRedisOfflineMsgPrefix + id
    53  	members, err := db.Redis.SMembers(key).Result()
    54  	if err != nil {
    55  		logger.ErrE("push offline msg error", err)
    56  		return
    57  	}
    58  	for _, member := range members {
    59  		msg := messages.NewEmptyMessage()
    60  		err := messages.JsonCodec.Decode([]byte(member), msg)
    61  		if err != nil {
    62  			logger.ErrE("deserialize redis offline msg error", err)
    63  			continue
    64  		}
    65  		id2 := gate.NewID2(id)
    66  		_ = h.GetClientInterface().EnqueueMessage(id2, msg)
    67  	}
    68  
    69  	// AckOfflineMessage(id)
    70  }
    71  
    72  func AckOfflineMessage(id string) {
    73  	key := KeyRedisOfflineMsgPrefix + id
    74  	result, err := db.Redis.Del(key).Result()
    75  	if err != nil {
    76  		logger.ErrE("remove offline message error", err)
    77  	}
    78  	logger.I("user %s ack %d offline messages", id, result)
    79  }