github.com/glide-im/glide@v1.6.0/pkg/messaging/handlers.go (about) 1 package messaging 2 3 import ( 4 "errors" 5 "github.com/glide-im/glide/pkg/gate" 6 "github.com/glide-im/glide/pkg/messages" 7 ) 8 9 // MessageValidator is used to validate message. 10 // if error is not nil, this message will be handled by MessageValidationHandler 11 // the second return value is the reply message, if not nil, the message will be sent to 12 // the client, if nil, the MessageValidationHandler will return the error message 13 type MessageValidator = func(msg *messages.GlideMessage) (error, *messages.GlideMessage) 14 15 // MessageValidationHandler validates message before handling 16 type MessageValidationHandler struct { 17 validators []MessageValidator 18 } 19 20 func NewMessageValidationHandler(validators ...MessageValidator) *MessageValidationHandler { 21 return &MessageValidationHandler{ 22 validators: validators, 23 } 24 } 25 26 func (m *MessageValidationHandler) Handle(h *MessageInterfaceImpl, cliInfo *gate.Info, message *messages.GlideMessage) bool { 27 28 for _, v := range m.validators { 29 err, reply := v(message) 30 if err != nil { 31 if reply == nil { 32 reply = messages.NewMessage(message.GetSeq(), messages.ActionNotifyError, err.Error()) 33 } 34 _ = h.GetClientInterface().EnqueueMessage(cliInfo.ID, reply) 35 return true 36 } 37 } 38 39 return false 40 } 41 42 func DefaultMessageValidator(msg *messages.GlideMessage) (error, *messages.GlideMessage) { 43 if msg.To == "" { 44 return errors.New("message.To is empty"), nil 45 } 46 if msg.Action == "" { 47 return errors.New("message.Action is empty"), nil 48 } 49 return nil, nil 50 } 51 52 // HandlerFunc is used to handle message with specified action in ActionHandler 53 type HandlerFunc func(cliInfo *gate.Info, message *messages.GlideMessage) error 54 55 // ActionHandler is a handler for a specific message action. 56 type ActionHandler struct { 57 action messages.Action 58 fn HandlerFunc 59 } 60 61 func NewActionHandler(action messages.Action, fn HandlerFunc) *ActionHandler { 62 return &ActionHandler{ 63 action: action, 64 fn: fn, 65 } 66 } 67 68 func (a *ActionHandler) Handle(h *MessageInterfaceImpl, cliInfo *gate.Info, message *messages.GlideMessage) bool { 69 if message.GetAction() == a.action { 70 err := a.fn(cliInfo, message) 71 if err != nil { 72 h.OnHandleMessageError(cliInfo, message, err) 73 } 74 return true 75 } 76 return false 77 } 78 79 type ReplyHandlerFunc func(cliInfo *gate.Info, message *messages.GlideMessage) (*messages.GlideMessage, error) 80 81 // ActionWithReplyHandler is a handler for a specific message action, this handler will return a reply message. 82 type ActionWithReplyHandler struct { 83 action messages.Action 84 fn ReplyHandlerFunc 85 } 86 87 func NewActionWithReplyHandler(action messages.Action, fn ReplyHandlerFunc) *ActionWithReplyHandler { 88 return &ActionWithReplyHandler{ 89 action: action, 90 fn: fn, 91 } 92 } 93 94 func (rh *ActionWithReplyHandler) Handle(h *MessageInterfaceImpl, cInfo *gate.Info, msg *messages.GlideMessage) bool { 95 if msg.GetAction() == rh.action { 96 r, err := rh.fn(cInfo, msg) 97 if err != nil { 98 h.OnHandleMessageError(cInfo, msg, err) 99 } 100 _ = h.GetClientInterface().EnqueueMessage(cInfo.ID, r) 101 return true 102 } 103 return false 104 }