fix: route call accept across pods

This commit is contained in:
richjohnrambo
2026-09-18 11:15:19 +08:00
parent 4c809129eb
commit 192bdede33
5 changed files with 122 additions and 13 deletions
+59
View File
@@ -10,6 +10,8 @@ import (
"time"
rtctokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2"
"github.com/tinode/chat/server/auth"
"github.com/tinode/chat/server/logs"
"github.com/tinode/chat/server/store"
"github.com/tinode/chat/server/store/types"
)
@@ -110,6 +112,9 @@ func serveIMCallRTCJoin(wrt http.ResponseWriter, req *http.Request) {
writeIMError(wrt, req, http.StatusConflict, 30064, imReasonCallStateInvalid, "call state invalid", map[string]any{"status": record.Status})
return
}
if body.Role == "callee" && record.Status == types.CallStatusStarted {
acceptIMCallFromRTCJoin(principal, record)
}
channelName := config.ChannelPrefix + record.CallID
uid, err := agoraUIDForUser(config, principal.Uid)
if err != nil {
@@ -267,6 +272,60 @@ func callStateAllowsRTCJoin(status string) bool {
}
}
func acceptIMCallFromRTCJoin(principal *imPrincipal, record *types.CallRecord) {
if principal == nil || record == nil || record.Status != types.CallStatusStarted || record.CalleeID != principal.Uid {
return
}
now := types.TimeNow()
if store.Calls != nil {
if err := store.Calls.Accept(principal.TenantID, record.CallID, record.SeqID, now); err != nil {
logs.Warn.Printf("rtc join: failed to mark call accepted tenant=%d topic=%s seq=%d call_id=%s: %v",
principal.TenantID, record.Topic, record.SeqID, record.CallID, err)
}
}
if globals.hub == nil {
return
}
payload, _ := json.Marshal(map[string]any{"callId": record.CallID})
msg := &ClientComMessage{
Note: &MsgClientNote{
Topic: record.Topic,
What: "call",
Event: constCallEventAccept,
SeqId: record.SeqID,
Payload: payload,
},
Original: record.Topic,
RcptTo: record.Topic,
AsUser: principal.Uid.UserId(),
AuthLvl: int(auth.LevelAuth),
Timestamp: now,
TenantID: principal.TenantID,
sess: &Session{
proto: NONE,
sid: "rtc-join:" + principal.Uid.UserId(),
uid: principal.Uid,
tenantID: principal.TenantID,
authLvl: auth.LevelAuth,
lastAction: now.UnixNano(),
},
init: true,
}
if globals.cluster != nil && globals.cluster.isRemoteTopic(types.TopicKey{TenantID: principal.TenantID, Topic: record.Topic}) {
if err := globals.cluster.routeToTopicMaster(ProxyReqCall, msg, record.Topic, msg.sess); err != nil {
logs.Warn.Printf("rtc join: failed to route call accept tenant=%d topic=%s seq=%d call_id=%s: %v",
principal.TenantID, record.Topic, record.SeqID, record.CallID, err)
}
return
}
select {
case globals.hub.routeCli <- msg:
default:
logs.Err.Printf("rtc join: hub route queue full tenant=%d topic=%s seq=%d call_id=%s",
principal.TenantID, record.Topic, record.SeqID, record.CallID)
}
}
func agoraUIDForUser(config imAgoraConfig, uid types.Uid) (any, error) {
switch config.UIDMode {
case "int":