Skip to content

Commit 01d2791

Browse files
authored
Rejoin peers into lobbies based on timeoutmanager (#62)
1 parent acd7e42 commit 01d2791

File tree

8 files changed

+32
-24
lines changed

8 files changed

+32
-24
lines changed

internal/signaling/handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func Handler(ctx context.Context, store stores.Store, cloudflare *cloudflare.Cre
6060
retrievedIDCallback: manager.Reconnected,
6161
}
6262
defer func() {
63-
logger.Info("peer websocket closed", zap.String("peer", peer.ID))
63+
logger.Info("peer websocket closed", zap.String("peer", peer.ID), zap.String("game", peer.Game), zap.String("origin", r.Header.Get("Origin")))
6464
conn.Close(websocket.StatusInternalError, "unexpceted closure")
6565

6666
if !peer.closedPacketReceived {

internal/signaling/peer.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type Peer struct {
2121

2222
closedPacketReceived bool
2323

24-
retrievedIDCallback func(context.Context, *Peer) (bool, error)
24+
retrievedIDCallback func(context.Context, *Peer) (bool, []string, error)
2525

2626
ID string
2727
Secret string
@@ -209,19 +209,20 @@ func (p *Peer) HandleHelloPacket(ctx context.Context, packet HelloPacket) error
209209

210210
hasReconnected := false
211211
clientIsReconnecting := false
212+
var reconnectingLobbies []string
212213
if packet.ID != "" && packet.Secret != "" {
213214
clientIsReconnecting = true
214215
p.ID = packet.ID
215216
p.Secret = packet.Secret
216-
logger.Info("peer reconnecting", zap.String("game", p.Game), zap.String("peer", p.ID), zap.String("lobby_in_packet", packet.Lobby))
217+
logger.Info("peer reconnecting", zap.String("game", p.Game), zap.String("peer", p.ID))
217218
} else {
218219
p.ID = util.GeneratePeerID(ctx)
219220
p.Secret = util.GenerateSecret(ctx)
220221
logger.Info("peer connecting", zap.String("game", p.Game), zap.String("peer", p.ID))
221222
}
222223
if clientIsReconnecting {
223224
var err error
224-
hasReconnected, err = p.retrievedIDCallback(ctx, p)
225+
hasReconnected, reconnectingLobbies, err = p.retrievedIDCallback(ctx, p)
225226
if err != nil {
226227
return fmt.Errorf("unable to reconnect: %w", err)
227228
}
@@ -230,20 +231,21 @@ func (p *Peer) HandleHelloPacket(ctx context.Context, packet HelloPacket) error
230231
}
231232
}
232233

233-
if packet.Lobby != "" {
234-
inLobby, err := p.store.IsPeerInLobby(ctx, p.Game, packet.Lobby, p.ID)
234+
if hasReconnected && len(reconnectingLobbies) > 0 && reconnectingLobbies[0] != "" {
235+
lobby := reconnectingLobbies[0]
236+
inLobby, err := p.store.IsPeerInLobby(ctx, p.Game, lobby, p.ID)
235237
if err != nil {
236238
return err
237239
}
238-
if hasReconnected && inLobby {
240+
if inLobby {
239241
logger.Info("peer rejoining lobby", zap.String("game", p.Game), zap.String("peer", p.ID), zap.String("lobby", p.Lobby))
240-
p.Lobby = packet.Lobby
242+
p.Lobby = lobby
241243
p.store.Subscribe(ctx, p.Game+p.Lobby+p.ID, p.ForwardMessage)
242244
go metrics.Record(ctx, "lobby", "reconnected", p.Game, p.ID, p.Lobby)
243245
} else {
244246
fakeJoinPacket := JoinPacket{
245247
Type: "join",
246-
Lobby: packet.Lobby,
248+
Lobby: lobby,
247249
}
248250
err := p.HandleJoinPacket(ctx, fakeJoinPacket)
249251
if err != nil {

internal/signaling/stores/postgres.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -330,20 +330,25 @@ func (s *PostgresStore) TimeoutPeer(ctx context.Context, peerID, secret, gameID
330330
return nil
331331
}
332332

333-
func (s *PostgresStore) ReconnectPeer(ctx context.Context, peerID, secret, gameID string) (bool, error) {
334-
res, err := s.DB.Exec(ctx, `
333+
func (s *PostgresStore) ReconnectPeer(ctx context.Context, peerID, secret, gameID string) (bool, []string, error) {
334+
var lobbies []string
335+
err := s.DB.QueryRow(ctx, `
335336
DELETE FROM timeouts
336337
WHERE peer = $1
337338
AND secret = $2
338339
AND game = $3
339-
`, peerID, secret, gameID)
340+
RETURNING lobbies
341+
`, peerID, secret, gameID).Scan(&lobbies)
340342
if err != nil {
341-
return false, err
343+
if errors.Is(err, pgx.ErrNoRows) {
344+
return false, nil, nil
345+
}
346+
return false, nil, err
342347
}
343-
if res.RowsAffected() == 0 {
344-
return false, nil
348+
if len(lobbies) == 0 {
349+
lobbies = nil
345350
}
346-
return true, nil
351+
return true, lobbies, nil
347352
}
348353

349354
func (s *PostgresStore) ClaimNextTimedOutPeer(ctx context.Context, threshold time.Duration, callback func(peerID, gameID string, lobbies []string) error) (more bool, err error) {

internal/signaling/stores/shared.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type Store interface {
2727
Publish(ctx context.Context, topic string, data []byte) error
2828

2929
TimeoutPeer(ctx context.Context, peerID, secret, gameID string, lobbies []string) error
30-
ReconnectPeer(ctx context.Context, peerID, secret, gameID string) (bool, error)
30+
ReconnectPeer(ctx context.Context, peerID, secret, gameID string) (bool, []string, error)
3131
ClaimNextTimedOutPeer(ctx context.Context, threshold time.Duration, callback func(peerID, gameID string, lobbies []string) error) (bool, error)
3232
}
3333

internal/signaling/timeout_manager.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,18 @@ func (i *TimeoutManager) Disconnected(ctx context.Context, p *Peer) {
8383
return
8484
}
8585

86-
logger.Debug("peer marked as disconnected", zap.String("id", p.ID))
87-
err := i.Store.TimeoutPeer(ctx, p.ID, p.Secret, p.Game, []string{p.Lobby})
86+
logger.Debug("peer marked as disconnected", zap.String("id", p.ID), zap.String("lobby", p.Lobby))
87+
lobbies := []string{}
88+
if p.Lobby != "" {
89+
lobbies = []string{p.Lobby}
90+
}
91+
err := i.Store.TimeoutPeer(ctx, p.ID, p.Secret, p.Game, lobbies)
8892
if err != nil {
8993
logger.Error("failed to record timeout peer", zap.Error(err))
9094
}
9195
}
9296

93-
func (i *TimeoutManager) Reconnected(ctx context.Context, p *Peer) (bool, error) {
97+
func (i *TimeoutManager) Reconnected(ctx context.Context, p *Peer) (bool, []string, error) {
9498
logger := logging.GetLogger(ctx)
9599

96100
logger.Debug("peer marked as reconnected", zap.String("id", p.ID))

internal/signaling/types.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ type HelloPacket struct {
1818
Game string `json:"game"`
1919
ID string `json:"id"`
2020
Secret string `json:"secret"`
21-
Lobby string `json:"lobby"`
2221
}
2322

2423
type WelcomePacket struct {

lib/signaling.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ export default class Signaling extends EventEmitter<SignalingListeners> {
4141
type: 'hello',
4242
game: this.network.gameID,
4343
id: this.receivedID,
44-
secret: this.receivedSecret,
45-
lobby: this.currentLobby
44+
secret: this.receivedSecret
4645
})
4746
}
4847
const onError = (e: Event): void => {

lib/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export interface HelloPacket extends Base {
6161
game: string
6262
id?: string
6363
secret?: string
64-
lobby?: string
6564
}
6665

6766
export interface WelcomePacket extends Base {

0 commit comments

Comments
 (0)