Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: "could not find participant" when a participant quickly reconnects #451

Open
denis-obukhov opened this issue Apr 23, 2024 · 7 comments

Comments

@denis-obukhov
Copy link

denis-obukhov commented Apr 23, 2024

I have an instance of the Go Server SDK that monitors a room. Also, I have iOS client apps that connects to a LiveKit media server.

If an iOS client force disconnects from LiveKit server (like by force killing client app process) and reconnects after a few seconds before LiveKit media server emits a "participant disconnected" message due to timeout then Go LiveKit Server SDK fails with error like: "msg"="could not find participant" "error"=null "participantID"="PA_2rjapiiKp9hi" on media track publication by this iOS client.
The error message comes from room.go: handleMediaTrack function.

Probably, it's because of no "participant connected" event is fired when the client reconnects for the second time before the timeout ends.

@davidzhao
Copy link
Member

which version of the SDK are you using? Can you share specific steps to reproduce the issue?

@denis-obukhov
Copy link
Author

denis-obukhov commented Apr 25, 2024

@davidzhao
I'm using v2.1.1

Here's code example for Go Server:


package main

import (
	"context"
	"fmt"
	"github.com/livekit/protocol/livekit"
	lksdk "github.com/livekit/server-sdk-go/v2"
	"log"
	"os"
	"os/signal"
	"syscall"
)

var roomClient *lksdk.RoomServiceClient
var liveKitServerURL = "http://127.0.0.1:6880"
var apiKey = "devkey"
var apiSecret = "secret"
var roomName = "test"

func main() {
	roomClient = lksdk.NewRoomServiceClient(liveKitServerURL, apiKey, apiSecret)
	createRoom()
	connectToRoom()

	// This will block the main function indefinitely
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT)
	<-sigChan
}

func createRoom() {
	_, err := roomClient.CreateRoom(context.Background(), &livekit.CreateRoomRequest{
		Name: roomName,
	})
	if err != nil {
		log.Fatalf("❌ Error creating %v room: %v", roomName, err)
		return
	}
	fmt.Println("Room created: ", roomName)
}

func connectToRoom() {
	roomCB := &lksdk.RoomCallback{
		OnParticipantConnected: func(participant *lksdk.RemoteParticipant) {
			fmt.Println("❇️onParticipantConnected: ", participant.Name(), participant.SID(), participant.Identity())
		},
		OnParticipantDisconnected: func(participant *lksdk.RemoteParticipant) {
			fmt.Println("⭕️Participant disconnected: ", participant.Identity())
		},
		ParticipantCallback: lksdk.ParticipantCallback{
			OnTrackPublished: func(publication *lksdk.RemoteTrackPublication, rp *lksdk.RemoteParticipant) {
				fmt.Println("🔔Track published by ", rp.Identity(), rp.SID())
			},
			OnTrackUnpublished: func(publication *lksdk.RemoteTrackPublication, rp *lksdk.RemoteParticipant) {
				fmt.Println("🔕Track unpublished by ", rp.Identity(), rp.SID())
			},
		},
	}

	// Connect to a room
	_, err := lksdk.ConnectToRoom(liveKitServerURL, lksdk.ConnectInfo{
		APIKey:              apiKey,
		APISecret:           apiSecret,
		RoomName:            roomName,
		ParticipantIdentity: "go-server-agent",
	}, roomCB)

	if err != nil {
		log.Fatalf("❌ Error connecting to speaking room: %w", err)
		return
	}
}

I also can provide code for iOS client. But the steps are:

  1. Start Go Server.
  2. Connect to the "test" room from any client (iOS client for my case)
  3. Publish an audio track and stop publishing (turning on and off mic for iOS device)
  4. Force close iOS client app
  5. Relaunch the client
  6. Publish an audio track again
  7. Observe "level"=0 "msg"="could not find participant, deferring track update" "participantID"="PA_PokmPNgaNuvs" message and no "Track published/unpublished" events in Go Server

Here's log I get for the code above:

Room created:  test
❇️onParticipantConnected:   PA_ZbZP56Y9LXdh DenisIphone
🔔Track published by  DenisIphone PA_ZbZP56Y9LXdh
2024/04/25 18:39:50 "level"=0 "msg"="track subscribed" "participant"="DenisIphone" "track"="TR_AMaWYeWpNAXDZK" "kind"="audio"
🔕Track unpublished by  DenisIphone PA_ZbZP56Y9LXdh
// < Here I force killed the client app, relaunched it and published audio again >
2024/04/25 18:40:01 "level"=0 "msg"="could not find participant, deferring track update" "participantID"="PA_Hdxd6K5aDkkq"
2024/04/25 18:40:05 "level"=0 "msg"="participant sid update" "sid-old"="PA_ZbZP56Y9LXdh" "sid-new"="PA_Hdxd6K5aDkkq" "identity"="DenisIphone"
2024/04/25 18:40:05 "level"=0 "msg"="running deferred updates for participant" "participantID"="PA_Hdxd6K5aDkkq" "updates"=1

@denis-obukhov
Copy link
Author

I think it could be related to this PR #447 by @dennwc

@dennwc
Copy link
Contributor

dennwc commented Apr 25, 2024

As long as it prints running deferred updates for participant, that PR likely works as intended. Without it it will be just participant not found and audio will be lost. Now it at least attempts to re-attach audio.

Probably what's missing is a call to OnTrackPublished when the track reconnects. I need to reproduce it on my side.

@denis-obukhov
Copy link
Author

@dennwc Hi! Do you have any progress on this?

@dennwc
Copy link
Contributor

dennwc commented May 20, 2024

Thank you for the ping, I didn't check it yet. I'll try testing it this week.

@denis-obukhov
Copy link
Author

@dennwc Could I help you with something to reproduce the issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants