mirror of
https://github.com/strukturag/nextcloud-spreed-signaling
synced 2024-05-04 06:43:11 +02:00
Merge pull request #55 from strukturag/mcu-messages-session
Send MCU messages through the session.
This commit is contained in:
commit
18c1874333
|
@ -79,7 +79,9 @@ type ClientSession struct {
|
||||||
publishers map[string]McuPublisher
|
publishers map[string]McuPublisher
|
||||||
subscribers map[string]McuSubscriber
|
subscribers map[string]McuSubscriber
|
||||||
|
|
||||||
pendingClientMessages []*NatsMessage
|
pendingClientMessages []*ServerMessage
|
||||||
|
hasPendingChat bool
|
||||||
|
hasPendingParticipantsUpdate bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClientSession(hub *Hub, privateId string, publicId string, data *SessionIdData, backend *Backend, hello *HelloClientMessage, auth *BackendClientAuthResponse) (*ClientSession, error) {
|
func NewClientSession(hub *Hub, privateId string, publicId string, data *SessionIdData, backend *Backend, hello *HelloClientMessage, auth *BackendClientAuthResponse) (*ClientSession, error) {
|
||||||
|
@ -490,12 +492,35 @@ func (s *ClientSession) sendCandidate(client McuClient, sender string, streamTyp
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if c := s.client; c != nil {
|
s.sendMessageUnlocked(response_message)
|
||||||
c.SendMessage(response_message)
|
|
||||||
} else {
|
|
||||||
// TODO(jojo): Should we store the candidate and send when a client is connected again?
|
|
||||||
log.Printf("Session %s received candidate %+v while no client was connected", s.PublicId(), candidate)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ClientSession) sendMessageUnlocked(message *ServerMessage) bool {
|
||||||
|
if c := s.getClientUnlocked(); c != nil {
|
||||||
|
if c.SendMessage(message) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.storePendingMessage(message)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ClientSession) SendMessage(message *ServerMessage) bool {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
return s.sendMessageUnlocked(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ClientSession) SendMessages(messages []*ServerMessage) bool {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
for _, message := range messages {
|
||||||
|
s.sendMessageUnlocked(message)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ClientSession) OnIceCandidate(client McuClient, candidate interface{}) {
|
func (s *ClientSession) OnIceCandidate(client McuClient, candidate interface{}) {
|
||||||
|
@ -654,26 +679,38 @@ func (s *ClientSession) processClientMessage(msg *nats.Msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.mu.Lock()
|
serverMessage := s.processNatsMessage(&message)
|
||||||
defer s.mu.Unlock()
|
if serverMessage == nil {
|
||||||
client := s.client
|
|
||||||
if client == nil {
|
|
||||||
s.pendingClientMessages = append(s.pendingClientMessages, &message)
|
|
||||||
if len(s.pendingClientMessages) >= warnPendingMessagesCount {
|
|
||||||
log.Printf("Session %s has %d pending messages", s.PublicId(), len(s.pendingClientMessages))
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.processNatsMessage(client, &message)
|
s.SendMessage(serverMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ClientSession) processNatsMessage(client *Client, msg *NatsMessage) bool {
|
func (s *ClientSession) storePendingMessage(message *ServerMessage) {
|
||||||
|
if message.IsChatRefresh() {
|
||||||
|
if s.hasPendingChat {
|
||||||
|
// Only send a single "chat-refresh" message on resume.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.hasPendingChat = true
|
||||||
|
}
|
||||||
|
if !s.hasPendingParticipantsUpdate && message.IsParticipantsUpdate() {
|
||||||
|
s.hasPendingParticipantsUpdate = true
|
||||||
|
}
|
||||||
|
s.pendingClientMessages = append(s.pendingClientMessages, message)
|
||||||
|
if len(s.pendingClientMessages) >= warnPendingMessagesCount {
|
||||||
|
log.Printf("Session %s has %d pending messages", s.PublicId(), len(s.pendingClientMessages))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ClientSession) processNatsMessage(msg *NatsMessage) *ServerMessage {
|
||||||
switch msg.Type {
|
switch msg.Type {
|
||||||
case "message":
|
case "message":
|
||||||
if msg.Message == nil {
|
if msg.Message == nil {
|
||||||
log.Printf("Received NATS message without payload: %+v\n", msg)
|
log.Printf("Received NATS message without payload: %+v\n", msg)
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch msg.Message.Type {
|
switch msg.Message.Type {
|
||||||
|
@ -682,14 +719,14 @@ func (s *ClientSession) processNatsMessage(client *Client, msg *NatsMessage) boo
|
||||||
msg.Message.Message.Sender != nil &&
|
msg.Message.Message.Sender != nil &&
|
||||||
msg.Message.Message.Sender.SessionId == s.PublicId() {
|
msg.Message.Message.Sender.SessionId == s.PublicId() {
|
||||||
// Don't send message back to sender (can happen if sent to user or room)
|
// Don't send message back to sender (can happen if sent to user or room)
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
case "control":
|
case "control":
|
||||||
if msg.Message.Control != nil &&
|
if msg.Message.Control != nil &&
|
||||||
msg.Message.Control.Sender != nil &&
|
msg.Message.Control.Sender != nil &&
|
||||||
msg.Message.Control.Sender.SessionId == s.PublicId() {
|
msg.Message.Control.Sender.SessionId == s.PublicId() {
|
||||||
// Don't send message back to sender (can happen if sent to user or room)
|
// Don't send message back to sender (can happen if sent to user or room)
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
case "event":
|
case "event":
|
||||||
if msg.Message.Event.Target == "participants" &&
|
if msg.Message.Event.Target == "participants" &&
|
||||||
|
@ -711,31 +748,13 @@ func (s *ClientSession) processNatsMessage(client *Client, msg *NatsMessage) boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return client.writeMessage(msg.Message)
|
return msg.Message
|
||||||
default:
|
default:
|
||||||
log.Printf("Received NATS message with unsupported type %s: %+v\n", msg.Type, msg)
|
log.Printf("Received NATS message with unsupported type %s: %+v\n", msg.Type, msg)
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ClientSession) combinePendingMessages(messages []*NatsMessage) ([]*NatsMessage, error) {
|
|
||||||
var result []*NatsMessage
|
|
||||||
has_chat := false
|
|
||||||
for _, message := range messages {
|
|
||||||
if message.Type == "message" && message.Message != nil && message.Message.IsChatRefresh() {
|
|
||||||
if has_chat {
|
|
||||||
// Only send a single chat refresh message to the client.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
has_chat = true
|
|
||||||
}
|
|
||||||
|
|
||||||
result = append(result, message)
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ClientSession) NotifySessionResumed(client *Client) {
|
func (s *ClientSession) NotifySessionResumed(client *Client) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
if len(s.pendingClientMessages) == 0 {
|
if len(s.pendingClientMessages) == 0 {
|
||||||
|
@ -746,27 +765,18 @@ func (s *ClientSession) NotifySessionResumed(client *Client) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
messages, err := s.combinePendingMessages(s.pendingClientMessages)
|
messages := s.pendingClientMessages
|
||||||
|
hasPendingParticipantsUpdate := s.hasPendingParticipantsUpdate
|
||||||
s.pendingClientMessages = nil
|
s.pendingClientMessages = nil
|
||||||
|
s.hasPendingChat = false
|
||||||
|
s.hasPendingParticipantsUpdate = false
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
if err != nil {
|
|
||||||
client.writeError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("Send %d pending messages to session %s", len(messages), s.PublicId())
|
log.Printf("Send %d pending messages to session %s", len(messages), s.PublicId())
|
||||||
had_participants_update := false
|
// Send through session to handle connection interruptions.
|
||||||
for _, message := range messages {
|
s.SendMessages(messages)
|
||||||
if !s.processNatsMessage(client, message) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if !had_participants_update {
|
if !hasPendingParticipantsUpdate {
|
||||||
had_participants_update = message.Type == "message" && message.Message.IsParticipantsUpdate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !had_participants_update {
|
|
||||||
// Only need to send initial participants list update if none was part of the pending messages.
|
// Only need to send initial participants list update if none was part of the pending messages.
|
||||||
if room := s.GetRoom(); room != nil {
|
if room := s.GetRoom(); room != nil {
|
||||||
room.NotifySessionResumed(client)
|
room.NotifySessionResumed(client)
|
||||||
|
|
|
@ -1517,7 +1517,7 @@ func (h *Hub) sendMcuMessageResponse(client *Client, session *ClientSession, mes
|
||||||
}
|
}
|
||||||
|
|
||||||
if response_message != nil {
|
if response_message != nil {
|
||||||
client.SendMessage(response_message)
|
session.SendMessage(response_message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue