Say 在 Room 中发送消息 - 如果消息包含 @mention,则发送给被提及的成员 (点对点) - 否则广播给除发送者外的所有成员
(ctx context.Context, from string, text string)
| 89 | // - 如果消息包含 @mention,则发送给被提及的成员 (点对点) |
| 90 | // - 否则广播给除发送者外的所有成员 |
| 91 | func (r *Room) Say(ctx context.Context, from string, text string) error { |
| 92 | r.mu.RLock() |
| 93 | |
| 94 | // 检查发送者是否是成员 |
| 95 | if _, exists := r.members[from]; !exists { |
| 96 | r.mu.RUnlock() |
| 97 | return fmt.Errorf("sender is not a member: %s", from) |
| 98 | } |
| 99 | |
| 100 | // 提取提及的成员 |
| 101 | mentions := r.extractMentions(text) |
| 102 | |
| 103 | // 记录消息 |
| 104 | msg := RoomMessage{ |
| 105 | From: from, |
| 106 | Text: text, |
| 107 | Sent: nowTimestamp(), |
| 108 | } |
| 109 | |
| 110 | var recipients []string |
| 111 | var targets map[string]string |
| 112 | |
| 113 | if len(mentions) > 0 { |
| 114 | // 定向消息 |
| 115 | msg.To = mentions |
| 116 | targets = make(map[string]string) |
| 117 | for _, mention := range mentions { |
| 118 | if agentID, exists := r.members[mention]; exists { |
| 119 | targets[mention] = agentID |
| 120 | recipients = append(recipients, mention) |
| 121 | } |
| 122 | } |
| 123 | } else { |
| 124 | // 广播消息 |
| 125 | targets = make(map[string]string) |
| 126 | for name, agentID := range r.members { |
| 127 | if name != from { |
| 128 | targets[name] = agentID |
| 129 | recipients = append(recipients, name) |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | r.mu.RUnlock() |
| 135 | |
| 136 | // 记录到历史 |
| 137 | r.mu.Lock() |
| 138 | r.history = append(r.history, msg) |
| 139 | r.mu.Unlock() |
| 140 | |
| 141 | // 发送消息 |
| 142 | for name, agentID := range targets { |
| 143 | ag, exists := r.pool.Get(agentID) |
| 144 | if !exists { |
| 145 | continue |
| 146 | } |
| 147 | |
| 148 | // 格式化消息: [from:sender] message |