register_strategy.go 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package MessageHandlers
  2. import (
  3. "context"
  4. "time"
  5. "github.com/zeromicro/go-zero/core/logx"
  6. "wechat-api/internal/pkg/wechat_ws"
  7. "wechat-api/internal/svc"
  8. )
  9. // MessageHandlerStrategy 消息处理策略接口
  10. type MessageHandlerStrategy interface {
  11. Handle(ctx context.Context, msg *wechat_ws.MsgJsonObject, svcCtx *svc.ServiceContext) error
  12. }
  13. type MessageHandler struct {
  14. strategies map[string]MessageHandlerStrategy
  15. svcCtx *svc.ServiceContext
  16. }
  17. // NewMessageHandler 创建新的消息调度器
  18. func NewMessageHandler(svcCtx *svc.ServiceContext) *MessageHandler {
  19. return &MessageHandler{
  20. strategies: make(map[string]MessageHandlerStrategy),
  21. svcCtx: svcCtx,
  22. }
  23. }
  24. // GetWrappedHandler 返回适配后的 handler,可直接用于 ws.RegisterMessageHandler
  25. func (h *MessageHandler) GetWrappedHandler() func(msg *wechat_ws.MsgJsonObject) error {
  26. return WrapToSimpleHandler(h.Handle)
  27. }
  28. // RegisterStrategy 注册单个消息处理策略
  29. func (h *MessageHandler) RegisterStrategy(msgType string, strategy MessageHandlerStrategy) {
  30. h.strategies[msgType] = strategy
  31. }
  32. // RegisterStrategies 批量注册消息处理策略
  33. func (h *MessageHandler) RegisterStrategies() {
  34. strategyMap := map[string]func(*svc.ServiceContext) MessageHandlerStrategy{
  35. "FriendPushNotice": toStrategy(NewFriendPushNoticeTypeHandler),
  36. //"ChatroomPushNotice": toStrategy(NewChatroomPushNoticeTypeHandler),
  37. "ContactLabelInfoNotice": toStrategy(NewContactLabelInfoNotice),
  38. "FindContactTaskResultNotice": toStrategy(NewFindContactTaskResultNoticeHandler),
  39. "TaskResultNotice": toStrategy(NewTaskResultNoticeHandler),
  40. }
  41. for msgType, strategyFunc := range strategyMap {
  42. h.RegisterStrategy(msgType, strategyFunc(h.svcCtx))
  43. logx.Infof("已注册消息处理策略: %s", msgType)
  44. }
  45. }
  46. // Handle 消息分发逻辑,带 recover 容错
  47. func (h *MessageHandler) Handle(ctx context.Context, msg *wechat_ws.MsgJsonObject) (err error) {
  48. defer func() {
  49. if r := recover(); r != nil {
  50. logx.Errorf("处理消息 msgType=%s 时 panic: %v", msg.MsgType, r)
  51. err = nil // 防止 panic 向上冒泡
  52. }
  53. }()
  54. strategy, exists := h.strategies[msg.MsgType]
  55. if !exists {
  56. logx.Infof("未注册处理器的消息类型: %s,跳过处理", msg.MsgType)
  57. return nil
  58. }
  59. return strategy.Handle(ctx, msg, h.svcCtx)
  60. }
  61. // toStrategy 泛型辅助转换
  62. func toStrategy[T MessageHandlerStrategy](fn func(*svc.ServiceContext) T) func(*svc.ServiceContext) MessageHandlerStrategy {
  63. return func(svcCtx *svc.ServiceContext) MessageHandlerStrategy {
  64. return fn(svcCtx)
  65. }
  66. }
  67. // WrapToSimpleHandler 将带 context 的 handler 包装成简洁 MessageHandler 函数
  68. func WrapToSimpleHandler(handler func(ctx context.Context, msg *wechat_ws.MsgJsonObject) error) func(msg *wechat_ws.MsgJsonObject) error {
  69. return func(msg *wechat_ws.MsgJsonObject) error {
  70. // 创建默认上下文(支持自定义扩展)
  71. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  72. defer cancel()
  73. return handler(ctx, msg)
  74. }
  75. }