From 0a44f596bf73052aa2b3110822e1a7dbcb9ede97 Mon Sep 17 00:00:00 2001 From: Simon Eisenmann Date: Sun, 19 Apr 2015 14:02:17 +0200 Subject: [PATCH] Implemented room types. --- src/app/spreed-webrtc-server/channelling.go | 8 ++-- .../spreed-webrtc-server/channelling_api.go | 8 +++- src/app/spreed-webrtc-server/room_manager.go | 40 +++++++++++++------ src/app/spreed-webrtc-server/roomworker.go | 24 +++++++---- src/app/spreed-webrtc-server/session.go | 5 ++- 5 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/app/spreed-webrtc-server/channelling.go b/src/app/spreed-webrtc-server/channelling.go index 5099b114..c05dcf8e 100644 --- a/src/app/spreed-webrtc-server/channelling.go +++ b/src/app/spreed-webrtc-server/channelling.go @@ -42,7 +42,9 @@ type DataRoomCredentials struct { type DataHello struct { Version string Ua string - Id string + Id string // Compatibility with old clients. + Name string // Room name. + Type string // Room type. Credentials *DataRoomCredentials } @@ -53,8 +55,8 @@ type DataWelcome struct { } type DataRoom struct { - Type string - Name string + Type string // Room type. + Name string // Room name. Credentials *DataRoomCredentials } diff --git a/src/app/spreed-webrtc-server/channelling_api.go b/src/app/spreed-webrtc-server/channelling_api.go index 9fccf764..958e9a9b 100644 --- a/src/app/spreed-webrtc-server/channelling_api.go +++ b/src/app/spreed-webrtc-server/channelling_api.go @@ -189,7 +189,13 @@ func (api *channellingAPI) HandleHello(session *Session, hello *DataHello, sende // TODO(longsleep): Filter room id and user agent. session.Update(&SessionUpdate{Types: []string{"Ua"}, Ua: hello.Ua}) - room, err := session.JoinRoom(hello.Id, hello.Credentials, sender) + // Compatibily for old clients. + roomName := hello.Name + if roomName == "" { + roomName = hello.Id + } + + room, err := session.JoinRoom(roomName, hello.Type, hello.Credentials, sender) if err != nil { return nil, err } diff --git a/src/app/spreed-webrtc-server/room_manager.go b/src/app/spreed-webrtc-server/room_manager.go index 01bd9094..1d221c2c 100644 --- a/src/app/spreed-webrtc-server/room_manager.go +++ b/src/app/spreed-webrtc-server/room_manager.go @@ -22,15 +22,17 @@ package main import ( + "fmt" "log" "sync" ) type RoomStatusManager interface { RoomUsers(*Session) []*DataSession - JoinRoom(roomID string, credentials *DataRoomCredentials, session *Session, sessionAuthenticated bool, sender Sender) (*DataRoom, error) + JoinRoom(roomID, roomName, roomType string, credentials *DataRoomCredentials, session *Session, sessionAuthenticated bool, sender Sender) (*DataRoom, error) LeaveRoom(roomID, sessionID string) UpdateRoom(*Session, *DataRoom) (*DataRoom, error) + MakeRoomID(roomName, roomType string) string } type Broadcaster interface { @@ -51,16 +53,25 @@ type roomManager struct { sync.RWMutex *Config OutgoingEncoder - roomTable map[string]RoomWorker + roomTable map[string]RoomWorker + globalRoomID string + defaultRoomID string + roomTypeDefault string } func NewRoomManager(config *Config, encoder OutgoingEncoder) RoomManager { - return &roomManager{ + rm := &roomManager{ sync.RWMutex{}, config, encoder, make(map[string]RoomWorker), + "", + "", + "Room", } + rm.globalRoomID = rm.MakeRoomID(config.globalRoomID, "") + rm.defaultRoomID = rm.MakeRoomID("", "") + return rm } func (rooms *roomManager) RoomUsers(session *Session) []*DataSession { @@ -71,12 +82,12 @@ func (rooms *roomManager) RoomUsers(session *Session) []*DataSession { return []*DataSession{} } -func (rooms *roomManager) JoinRoom(roomID string, credentials *DataRoomCredentials, session *Session, sessionAuthenticated bool, sender Sender) (*DataRoom, error) { - if roomID == "" && !rooms.DefaultRoomEnabled { +func (rooms *roomManager) JoinRoom(roomID, roomName, roomType string, credentials *DataRoomCredentials, session *Session, sessionAuthenticated bool, sender Sender) (*DataRoom, error) { + if roomID == rooms.defaultRoomID && !rooms.DefaultRoomEnabled { return nil, NewDataError("default_room_disabled", "The default room is not enabled") } - roomWorker, err := rooms.GetOrCreate(roomID, credentials, sessionAuthenticated) + roomWorker, err := rooms.GetOrCreate(roomID, roomName, roomType, credentials, sessionAuthenticated) if err != nil { return nil, err } @@ -91,12 +102,10 @@ func (rooms *roomManager) LeaveRoom(roomID, sessionID string) { } func (rooms *roomManager) UpdateRoom(session *Session, room *DataRoom) (*DataRoom, error) { - if !session.Hello || session.Roomid != room.Name { + roomID := rooms.MakeRoomID(room.Name, room.Type) + if !session.Hello || session.Roomid != roomID { return nil, NewDataError("not_in_room", "Cannot update other rooms") } - // XXX(lcooper): We'll process and send documents without this field - // correctly, however clients cannot not handle it currently. - room.Type = "Room" if roomWorker, ok := rooms.Get(session.Roomid); ok { return room, roomWorker.Update(room) } @@ -145,7 +154,7 @@ func (rooms *roomManager) Get(roomID string) (room RoomWorker, ok bool) { return } -func (rooms *roomManager) GetOrCreate(roomID string, credentials *DataRoomCredentials, sessionAuthenticated bool) (RoomWorker, error) { +func (rooms *roomManager) GetOrCreate(roomID, roomName, roomType string, credentials *DataRoomCredentials, sessionAuthenticated bool) (RoomWorker, error) { if rooms.AuthorizeRoomJoin && rooms.UsersEnabled && !sessionAuthenticated { return nil, NewDataError("room_join_requires_account", "Room join requires a user account") } @@ -167,7 +176,7 @@ func (rooms *roomManager) GetOrCreate(roomID string, credentials *DataRoomCreden return nil, NewDataError("room_join_requires_account", "Room creation requires a user account") } - room := NewRoomWorker(rooms, roomID, credentials) + room := NewRoomWorker(rooms, roomID, roomName, roomType, credentials) rooms.roomTable[roomID] = room rooms.Unlock() go func() { @@ -196,3 +205,10 @@ func (rooms *roomManager) GlobalUsers() []*roomUser { rooms.RUnlock() return make([]*roomUser, 0) } + +func (rooms *roomManager) MakeRoomID(roomName, roomType string) string { + if roomType == "" { + roomType = rooms.roomTypeDefault + } + return fmt.Sprintf("%s:%s", roomType, roomName) +} diff --git a/src/app/spreed-webrtc-server/roomworker.go b/src/app/spreed-webrtc-server/roomworker.go index f0dea820..a0d24661 100644 --- a/src/app/spreed-webrtc-server/roomworker.go +++ b/src/app/spreed-webrtc-server/roomworker.go @@ -56,7 +56,9 @@ type roomWorker struct { mutex sync.RWMutex // Metadata. - Id string + id string + Name string + Type string credentials *DataRoomCredentials } @@ -65,13 +67,15 @@ type roomUser struct { Sender } -func NewRoomWorker(manager *roomManager, id string, credentials *DataRoomCredentials) RoomWorker { +func NewRoomWorker(manager *roomManager, roomID, roomName, roomType string, credentials *DataRoomCredentials) RoomWorker { - log.Printf("Creating worker for room '%s'\n", id) + log.Printf("Creating worker for room '%s'\n", roomID) r := &roomWorker{ manager: manager, - Id: id, + id: roomID, + Name: roomName, + Type: roomType, workers: make(chan func(), roomMaxWorkers), expired: make(chan bool), users: make(map[string]*roomUser), @@ -107,7 +111,7 @@ L: if len(r.users) == 0 { // Cleanup room when it is empty. r.mutex.RUnlock() - log.Printf("Room worker not in use - cleaning up '%s'\n", r.Id) + log.Printf("Room worker not in use - cleaning up '%s'\n", r.id) break L } else { r.mutex.RUnlock() @@ -149,7 +153,7 @@ func (r *roomWorker) Run(f func()) bool { case r.workers <- f: return true default: - log.Printf("Room worker channel full or closed '%s'\n", r.Id) + log.Printf("Room worker channel full or closed '%s'\n", r.id) return false } @@ -159,6 +163,10 @@ func (r *roomWorker) Update(room *DataRoom) error { fault := make(chan error, 1) worker := func() { r.mutex.Lock() + // Enforce room type and name. + room.Type = r.Type + room.Name = r.Name + // Update credentials. if room.Credentials != nil { if len(room.Credentials.PIN) > 0 { r.credentials = room.Credentials @@ -184,7 +192,7 @@ func (r *roomWorker) GetUsers() []*DataSession { session.Type = "Online" sl = append(sl, session) if len(sl) > maxUsersLength { - log.Println("Limiting users response length in channel", r.Id) + log.Println("Limiting users response length in channel", r.id) return false } } @@ -264,7 +272,7 @@ func (r *roomWorker) Join(credentials *DataRoomCredentials, session *Session, se r.users[session.Id] = &roomUser{session, sender} // NOTE(lcooper): Needs to be a copy, else we risk races with // a subsequent modification of room properties. - result := joinResult{&DataRoom{Name: r.Id}, nil} + result := joinResult{&DataRoom{Name: r.Name, Type: r.Type}, nil} r.mutex.Unlock() results <- result } diff --git a/src/app/spreed-webrtc-server/session.go b/src/app/spreed-webrtc-server/session.go index aa07e332..427564b0 100644 --- a/src/app/spreed-webrtc-server/session.go +++ b/src/app/spreed-webrtc-server/session.go @@ -116,7 +116,8 @@ func (s *Session) RemoveSubscriber(id string) { s.mutex.Unlock() } -func (s *Session) JoinRoom(roomID string, credentials *DataRoomCredentials, sender Sender) (*DataRoom, error) { +func (s *Session) JoinRoom(roomName, roomType string, credentials *DataRoomCredentials, sender Sender) (*DataRoom, error) { + roomID := s.RoomStatusManager.MakeRoomID(roomName, roomType) s.mutex.Lock() defer s.mutex.Unlock() @@ -133,7 +134,7 @@ func (s *Session) JoinRoom(roomID string, credentials *DataRoomCredentials, send }) } - room, err := s.RoomStatusManager.JoinRoom(roomID, credentials, s, s.authenticated(), sender) + room, err := s.RoomStatusManager.JoinRoom(roomID, roomName, roomType, credentials, s, s.authenticated(), sender) if err == nil { s.Hello = true s.Roomid = roomID