Browse Source

Merge branch 'release-0.23'

pull/222/merge v0.23.8
Simon Eisenmann 10 years ago
parent
commit
b8838e509b
  1. 8
      debian/changelog
  2. 18
      src/app/spreed-webrtc-server/client.go
  3. 8
      src/app/spreed-webrtc-server/hub.go
  4. 78
      src/app/spreed-webrtc-server/session.go
  5. 36
      static/js/directives/chat.js

8
debian/changelog vendored

@ -1,3 +1,11 @@
spreed-webrtc-server (0.23.8) precise; urgency=low
* Session subscriptions now notify close both ways.
* Reenable chat rooms on certain conditions related to peer connectivity.
* Fixed an issue where replaced sessions cannot receive data from contacts in other rooms.
-- Simon Eisenmann <simon@struktur.de> Wed, 08 Apr 2015 17:24:59 +0200
spreed-webrtc-server (0.23.7) precise; urgency=low spreed-webrtc-server (0.23.7) precise; urgency=low
* Updated SCSS to match coding style. * Updated SCSS to match coding style.

18
src/app/spreed-webrtc-server/client.go

@ -43,7 +43,7 @@ type Client interface {
Session() *Session Session() *Session
Index() uint64 Index() uint64
Close() Close()
ReplaceAndClose() ReplaceAndClose(Client)
} }
type client struct { type client struct {
@ -87,9 +87,15 @@ func (client *client) Session() *Session {
return client.session return client.session
} }
func (client *client) ReplaceAndClose() { func (client *client) ReplaceAndClose(oldClient Client) {
client.session.Close() oldSession := oldClient.Session()
if client.Connection != nil { client.session.Replace(oldSession)
client.Connection.Close() go func() {
} // Close old session and client in another go routine,
// to avoid blocking the new client if the old one hangs or
// whatever.
log.Printf("Closing obsolete client %d (replaced with %d) with id %s\n", oldClient.Index(), client.Index(), oldSession.Id)
oldSession.Close()
oldClient.Close()
}()
} }

8
src/app/spreed-webrtc-server/hub.go

@ -154,12 +154,8 @@ func (h *hub) OnConnect(client Client, session *Session) {
log.Printf("Created client %d with id %s\n", client.Index(), session.Id) log.Printf("Created client %d with id %s\n", client.Index(), session.Id)
// Register connection or replace existing one. // Register connection or replace existing one.
if ec, ok := h.clients[session.Id]; ok { if ec, ok := h.clients[session.Id]; ok {
// Clean up old client at the end and make sure to run this in another go routine, // Clean up old client at the end outside the hub lock.
// to avoid blocking the new client if the old one hangs or whatever. defer client.ReplaceAndClose(ec)
go func() {
log.Printf("Closing obsolete client %d (replaced with %d) with id %s\n", ec.Index(), client.Index(), session.Id)
ec.ReplaceAndClose()
}()
} }
h.clients[session.Id] = client h.clients[session.Id] = client
h.mutex.Unlock() h.mutex.Unlock()

78
src/app/spreed-webrtc-server/session.go

@ -56,6 +56,7 @@ type Session struct {
subscriptions map[string]*Session subscriptions map[string]*Session
subscribers map[string]*Session subscribers map[string]*Session
disconnected bool disconnected bool
replaced bool
} }
func NewSession(manager SessionManager, unicaster Unicaster, broadcaster Broadcaster, rooms RoomStatusManager, buddyImages ImageCache, attestations *securecookie.SecureCookie, id, sid string) *Session { func NewSession(manager SessionManager, unicaster Unicaster, broadcaster Broadcaster, rooms RoomStatusManager, buddyImages ImageCache, attestations *securecookie.SecureCookie, id, sid string) *Session {
@ -85,16 +86,13 @@ func (s *Session) authenticated() (authenticated bool) {
} }
func (s *Session) Subscribe(session *Session) { func (s *Session) Subscribe(session *Session) {
s.mutex.Lock() s.mutex.Lock()
s.subscriptions[session.Id] = session s.subscriptions[session.Id] = session
s.mutex.Unlock() s.mutex.Unlock()
session.AddSubscriber(s) session.AddSubscriber(s)
} }
func (s *Session) Unsubscribe(id string) { func (s *Session) Unsubscribe(id string) {
s.mutex.Lock() s.mutex.Lock()
if session, ok := s.subscriptions[id]; ok { if session, ok := s.subscriptions[id]; ok {
delete(s.subscriptions, id) delete(s.subscriptions, id)
@ -103,7 +101,6 @@ func (s *Session) Unsubscribe(id string) {
} else { } else {
s.mutex.Unlock() s.mutex.Unlock()
} }
} }
func (s *Session) AddSubscriber(session *Session) { func (s *Session) AddSubscriber(session *Session) {
@ -209,33 +206,39 @@ func (s *Session) Close() {
return return
} }
outgoing := &DataOutgoing{ // TODO(longsleep): Verify that it is ok to not do all this when replaced is true.
From: s.Id, if !s.replaced {
A: s.attestation.Token(),
Data: &DataSession{
Type: "Left",
Id: s.Id,
Status: "hard",
},
}
if s.Hello { outgoing := &DataOutgoing{
// NOTE(lcooper): If we don't check for Hello here, we could deadlock From: s.Id,
// when implicitly creating a room while a user is reconnecting. A: s.attestation.Token(),
s.Broadcaster.Broadcast(s.Id, s.Roomid, outgoing) Data: &DataSession{
s.RoomStatusManager.LeaveRoom(s.Roomid, s.Id) Type: "Left",
} Id: s.Id,
Status: "hard",
},
}
for _, session := range s.subscribers { if s.Hello {
s.Unicaster.Unicast(session.Id, outgoing) // NOTE(lcooper): If we don't check for Hello here, we could deadlock
} // when implicitly creating a room while a user is reconnecting.
s.Broadcaster.Broadcast(s.Id, s.Roomid, outgoing)
s.RoomStatusManager.LeaveRoom(s.Roomid, s.Id)
}
for _, session := range s.subscriptions { for _, session := range s.subscribers {
session.RemoveSubscriber(s.Id) s.Unicaster.Unicast(session.Id, outgoing)
} }
for _, session := range s.subscriptions {
session.RemoveSubscriber(s.Id)
s.Unicaster.Unicast(session.Id, outgoing)
}
s.SessionManager.DestroySession(s.Id, s.userid) s.SessionManager.DestroySession(s.Id, s.userid)
s.buddyImages.Delete(s.Id) s.buddyImages.Delete(s.Id)
}
s.subscriptions = make(map[string]*Session) s.subscriptions = make(map[string]*Session)
s.subscribers = make(map[string]*Session) s.subscribers = make(map[string]*Session)
@ -244,6 +247,27 @@ func (s *Session) Close() {
s.mutex.Unlock() s.mutex.Unlock()
} }
func (s *Session) Replace(oldSession *Session) {
oldSession.mutex.Lock()
if oldSession.disconnected {
oldSession.mutex.Unlock()
return
}
s.mutex.Lock()
s.subscriptions = oldSession.subscriptions
s.subscribers = oldSession.subscribers
s.mutex.Unlock()
// Mark old session as replaced.
oldSession.replaced = true
oldSession.mutex.Unlock()
}
func (s *Session) Update(update *SessionUpdate) uint64 { func (s *Session) Update(update *SessionUpdate) uint64 {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()

36
static/js/directives/chat.js

@ -78,7 +78,7 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
if (!with_message) { if (!with_message) {
return; return;
} }
// No room with this id, get one with the from id // No room with this id, get one with the from id.
$scope.$emit("startchat", from, { $scope.$emit("startchat", from, {
restore: with_message restore: with_message
}); });
@ -90,14 +90,19 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
room.peerIsTyping = "no"; room.peerIsTyping = "no";
room.p2p( !! p2p); room.p2p( !! p2p);
if (room.firstmessage) { if (room.firstmessage) {
// Auto show when this is the first message.
$scope.showRoom(room.id, null, { $scope.showRoom(room.id, null, {
restore: with_message restore: with_message
}); });
} }
if (!room.enabled) {
// Reenable chat room when receiving messages again.
room.enabled = true;
}
} }
room.$broadcast("received", from, data);
safeApply(room); safeApply(room);
room.$broadcast("received", from, data);
}); });
@ -108,10 +113,6 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
case "Left": case "Left":
if (data.Status !== "soft") { if (data.Status !== "soft") {
room.enabled = false; room.enabled = false;
room.$broadcast("received", data.Id, {
Type: "LeftOrJoined",
"LeftOrJoined": "left"
});
safeApply(room); safeApply(room);
} }
break; break;
@ -119,10 +120,6 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
if (!room.enabled) { if (!room.enabled) {
room.enabled = true; room.enabled = true;
_.delay(function() { _.delay(function() {
room.$broadcast("received", data.Id, {
Type: "LeftOrJoined",
"LeftOrJoined": "joined"
});
safeApply(room); safeApply(room);
}, 1000); }, 1000);
} }
@ -398,6 +395,22 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
} }
} }
}); });
subscope.$watch("enabled", function(enabled, old) {
if (enabled === old) {
return;
}
//console.log("enabled", enabled, old);
var value;
if (enabled) {
value = "resumed";
} else {
value = "left";
}
subscope.$broadcast("received", subscope.id, {
Type: "LeftOrJoined",
"LeftOrJoined": value
});
});
chat(subscope, function(clonedElement, $scope) { chat(subscope, function(clonedElement, $scope) {
pane.append(clonedElement); pane.append(clonedElement);
@ -445,6 +458,9 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
subscope.index = index; subscope.index = index;
subscope.visible = true; subscope.visible = true;
} }
if (!subscope.enabled) {
subscope.enabled = true;
}
} }
if (options.autofocus && subscope.visible) { if (options.autofocus && subscope.visible) {
subscope.$broadcast("focus"); subscope.$broadcast("focus");

Loading…
Cancel
Save