github.com/glide-im/glide@v1.6.0/pkg/messaging/default_impl.go (about) 1 package messaging 2 3 import ( 4 "github.com/glide-im/glide/pkg/gate" 5 "github.com/glide-im/glide/pkg/logger" 6 "github.com/glide-im/glide/pkg/messages" 7 "github.com/glide-im/glide/pkg/subscription" 8 "github.com/panjf2000/ants/v2" 9 ) 10 11 type Options struct { 12 NotifyServerError bool 13 MaxMessageConcurrency int 14 } 15 16 func onMessageHandlerPanic(i interface{}) { 17 logger.E("MessageInterfaceImpl panic: %v", i) 18 } 19 20 // MessageInterfaceImpl default implementation of the messaging interface. 21 type MessageInterfaceImpl struct { 22 23 // execPool 100 capacity goroutine pool, 假设每个消息处理需要10ms, 一个协程则每秒能处理100条消息 24 execPool *ants.Pool 25 26 // hc message handler chain 27 hc *handlerChain 28 29 subscription subscription.Interface 30 gate gate.Gateway 31 32 // notifyOnSrvErr notify client on server error 33 notifyOnSrvErr bool 34 } 35 36 func NewDefaultImpl(options *Options) (*MessageInterfaceImpl, error) { 37 38 ret := MessageInterfaceImpl{ 39 notifyOnSrvErr: options.NotifyServerError, 40 hc: &handlerChain{}, 41 } 42 43 var err error 44 ret.execPool, err = ants.NewPool( 45 options.MaxMessageConcurrency, 46 ants.WithNonblocking(true), 47 ants.WithPanicHandler(onMessageHandlerPanic), 48 ants.WithPreAlloc(false), 49 ) 50 if err != nil { 51 return nil, err 52 } 53 return &ret, nil 54 } 55 56 func (d *MessageInterfaceImpl) Handle(cInfo *gate.Info, msg *messages.GlideMessage) error { 57 58 if !msg.GetAction().IsInternal() { 59 msg.From = cInfo.ID.UID() 60 } 61 logger.D("handle message: %s", msg) 62 err := d.execPool.Submit(func() { 63 handled := d.hc.handle(d, cInfo, msg) 64 if !handled { 65 if !msg.GetAction().IsInternal() { 66 r := messages.NewMessage(msg.GetSeq(), messages.ActionNotifyUnknownAction, msg.GetAction()) 67 _ = d.gate.EnqueueMessage(cInfo.ID, r) 68 } 69 logger.W("action is not handled: %s", msg.GetAction()) 70 } 71 }) 72 if err != nil { 73 d.OnHandleMessageError(cInfo, msg, err) 74 return err 75 } 76 return nil 77 } 78 79 func (d *MessageInterfaceImpl) AddHandler(i MessageHandler) { 80 d.hc.add(i) 81 } 82 83 func (d *MessageInterfaceImpl) SetGate(g gate.Gateway) { 84 d.gate = g 85 } 86 87 func (d *MessageInterfaceImpl) SetSubscription(g subscription.Interface) { 88 d.subscription = g 89 } 90 91 func (d *MessageInterfaceImpl) SetNotifyErrorOnServer(enable bool) { 92 d.notifyOnSrvErr = enable 93 } 94 95 func (d *MessageInterfaceImpl) GetClientInterface() gate.Gateway { 96 return d.gate 97 } 98 99 func (d *MessageInterfaceImpl) GetGroupInterface() subscription.Interface { 100 return d.subscription 101 } 102 103 func (d *MessageInterfaceImpl) OnHandleMessageError(cInfo *gate.Info, msg *messages.GlideMessage, err error) { 104 if d.notifyOnSrvErr { 105 _ = d.gate.EnqueueMessage(cInfo.ID, messages.NewMessage(-1, messages.ActionNotifyError, err.Error())) 106 } 107 } 108 109 // handlerChain is a chain of MessageHandlers. 110 type handlerChain struct { 111 h MessageHandler 112 next *handlerChain 113 } 114 115 func (hc *handlerChain) add(i MessageHandler) { 116 if hc.next == nil { 117 hc.next = &handlerChain{ 118 h: i, 119 } 120 } else { 121 hc.next.add(i) 122 } 123 } 124 125 func (hc handlerChain) handle(h2 *MessageInterfaceImpl, cliInfo *gate.Info, message *messages.GlideMessage) bool { 126 if hc.h != nil && hc.h.Handle(h2, cliInfo, message) { 127 return true 128 } 129 if hc.next != nil { 130 return hc.next.handle(h2, cliInfo, message) 131 } 132 return false 133 }