mirror of
https://github.com/screego/server.git
synced 2025-12-24 12:57:51 +08:00
In client.go
if room, ok := message.(outgoing.Room); ok {
c.info.RoomID = room.ID
}
this part isn't thread safe. It could happen that user disconnected but
wasn't removed from a room, because the disconnecting go routine
couldn't see the roomID yet.
78 lines
1.5 KiB
Go
78 lines
1.5 KiB
Go
package ws
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/gorilla/websocket"
|
|
"github.com/screego/server/ws/outgoing"
|
|
)
|
|
|
|
type Disconnected struct {
|
|
Code int
|
|
Reason string
|
|
}
|
|
|
|
func (e *Disconnected) Execute(rooms *Rooms, current ClientInfo) error {
|
|
e.executeNoError(rooms, current)
|
|
return nil
|
|
}
|
|
|
|
func (e *Disconnected) executeNoError(rooms *Rooms, current ClientInfo) {
|
|
roomID := rooms.connected[current.ID]
|
|
delete(rooms.connected, current.ID)
|
|
current.Write <- outgoing.CloseWriter{Code: e.Code, Reason: e.Reason}
|
|
|
|
if roomID == "" {
|
|
return
|
|
}
|
|
|
|
room, ok := rooms.Rooms[roomID]
|
|
if !ok {
|
|
// room may already be removed
|
|
return
|
|
}
|
|
|
|
user, ok := room.Users[current.ID]
|
|
|
|
if !ok {
|
|
// room may already be removed
|
|
return
|
|
}
|
|
|
|
delete(room.Users, current.ID)
|
|
usersLeftTotal.Inc()
|
|
|
|
for id, session := range room.Sessions {
|
|
if bytes.Equal(session.Client.Bytes(), current.ID.Bytes()) {
|
|
host, ok := room.Users[session.Host]
|
|
if ok {
|
|
host.Write <- outgoing.EndShare(id)
|
|
}
|
|
room.closeSession(rooms, id)
|
|
}
|
|
if bytes.Equal(session.Host.Bytes(), current.ID.Bytes()) {
|
|
client, ok := room.Users[session.Client]
|
|
if ok {
|
|
client.Write <- outgoing.EndShare(id)
|
|
}
|
|
room.closeSession(rooms, id)
|
|
}
|
|
}
|
|
|
|
if user.Owner && room.CloseOnOwnerLeave {
|
|
for _, member := range room.Users {
|
|
delete(rooms.connected, member.ID)
|
|
member.Write <- outgoing.CloseWriter{Code: websocket.CloseNormalClosure, Reason: CloseOwnerLeft}
|
|
}
|
|
rooms.closeRoom(roomID)
|
|
return
|
|
}
|
|
|
|
if len(room.Users) == 0 {
|
|
rooms.closeRoom(roomID)
|
|
return
|
|
}
|
|
|
|
room.notifyInfoChanged()
|
|
}
|