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  }