From 5f905e7eee007cdb91b83c3266d8565d859c3fca Mon Sep 17 00:00:00 2001 From: Alex P Date: Thu, 7 Aug 2025 10:12:50 +0000 Subject: [PATCH] Fix: session duplication detection, dev_deploy.sh script --- cloud.go | 66 +++++++++++++++++++++++---------------------------- dev_deploy.sh | 35 +++++++++++++++++++++++++-- web.go | 54 +++++++++++++++++++---------------------- 3 files changed, 87 insertions(+), 68 deletions(-) diff --git a/cloud.go b/cloud.go index e2f1cd8..cddf055 100644 --- a/cloud.go +++ b/cloud.go @@ -451,46 +451,40 @@ func handleSessionRequest( var err error var sd string - // Check if we have an existing session and handle renegotiation + // Check if we have an existing session if currentSession != nil { - scopedLogger.Info().Msg("handling renegotiation for existing session") + scopedLogger.Info().Msg("existing session detected, creating new session and notifying old session") - // Handle renegotiation with existing session - sd, err = currentSession.ExchangeOffer(req.Sd) + // Always create a new session when there's an existing one + // This ensures the "otherSessionConnected" prompt is shown + session, err = newSession(SessionConfig{ + ws: c, + IsCloud: isCloudConnection, + LocalIP: req.IP, + ICEServers: req.ICEServers, + Logger: scopedLogger, + }) if err != nil { - scopedLogger.Warn().Err(err).Msg("renegotiation failed, creating new session") - // If renegotiation fails, fall back to creating a new session - session, err = newSession(SessionConfig{ - ws: c, - IsCloud: isCloudConnection, - LocalIP: req.IP, - ICEServers: req.ICEServers, - Logger: scopedLogger, - }) - if err != nil { - _ = wsjson.Write(context.Background(), c, gin.H{"error": err}) - return err - } - - sd, err = session.ExchangeOffer(req.Sd) - if err != nil { - _ = wsjson.Write(context.Background(), c, gin.H{"error": err}) - return err - } - - // Close the old session - writeJSONRPCEvent("otherSessionConnected", nil, currentSession) - peerConn := currentSession.peerConnection - go func() { - time.Sleep(1 * time.Second) - _ = peerConn.Close() - }() - - currentSession = session - cloudLogger.Info().Interface("session", session).Msg("new session created after renegotiation failure") - } else { - scopedLogger.Info().Msg("renegotiation successful") + _ = wsjson.Write(context.Background(), c, gin.H{"error": err}) + return err } + + sd, err = session.ExchangeOffer(req.Sd) + if err != nil { + _ = wsjson.Write(context.Background(), c, gin.H{"error": err}) + return err + } + + // Notify the old session about the takeover + writeJSONRPCEvent("otherSessionConnected", nil, currentSession) + peerConn := currentSession.peerConnection + go func() { + time.Sleep(1 * time.Second) + _ = peerConn.Close() + }() + + currentSession = session + scopedLogger.Info().Interface("session", session).Msg("new session created, old session notified") } else { // No existing session, create a new one scopedLogger.Info().Msg("creating new session") diff --git a/dev_deploy.sh b/dev_deploy.sh index aac9acb..7a79e97 100755 --- a/dev_deploy.sh +++ b/dev_deploy.sh @@ -180,8 +180,17 @@ set -e # Set the library path to include the directory where librockit.so is located export LD_LIBRARY_PATH=/oem/usr/lib:\$LD_LIBRARY_PATH +# Check if production jetkvm_app is running and save its state +PROD_APP_RUNNING=false +if pgrep -f "/userdata/jetkvm/bin/jetkvm_app" > /dev/null; then + PROD_APP_RUNNING=true + echo "Production jetkvm_app is running, will restore after development session" +else + echo "No production jetkvm_app detected" +fi + # Kill any existing instances of the application -killall jetkvm_app || true +pkill -f "/userdata/jetkvm/bin/jetkvm_app" || true killall jetkvm_app_debug || true # Navigate to the directory where the binary will be stored @@ -190,7 +199,29 @@ cd "${REMOTE_PATH}" # Make the new binary executable chmod +x jetkvm_app_debug -# Run the application in the background +# Create a cleanup script that will restore the production app +cat > /tmp/restore_jetkvm.sh << RESTORE_EOF +#!/bin/ash +set -e +export LD_LIBRARY_PATH=/oem/usr/lib:\$LD_LIBRARY_PATH +cd ${REMOTE_PATH} +if [ "$PROD_APP_RUNNING" = "true" ]; then + echo "Restoring production jetkvm_app..." + killall jetkvm_app_debug || true + nohup /userdata/jetkvm/bin/jetkvm_app > /tmp/jetkvm_app.log 2>&1 & + echo "Production jetkvm_app restored" +else + echo "No production app was running before, not restoring" +fi +RESTORE_EOF + +chmod +x /tmp/restore_jetkvm.sh + +# Set up signal handler to restore production app on exit +trap '/tmp/restore_jetkvm.sh' EXIT INT TERM + +# Run the application in the foreground +echo "Starting development jetkvm_app_debug..." PION_LOG_TRACE=${LOG_TRACE_SCOPES} ./jetkvm_app_debug | tee -a /tmp/jetkvm_app_debug.log EOF fi diff --git a/web.go b/web.go index b019168..c0541aa 100644 --- a/web.go +++ b/web.go @@ -456,40 +456,34 @@ func handleWebRTCSession(c *gin.Context) { var err error var sd string - // Check if we have an existing session and handle renegotiation + // Check if we have an existing session if currentSession != nil { - logger.Info().Msg("handling renegotiation for existing session") + logger.Info().Msg("existing session detected, creating new session and notifying old session") - // Handle renegotiation with existing session - sd, err = currentSession.ExchangeOffer(req.Sd) + // Always create a new session when there's an existing one + // This ensures the "otherSessionConnected" prompt is shown + session, err = newSession(SessionConfig{}) if err != nil { - logger.Warn().Err(err).Msg("renegotiation failed, creating new session") - // If renegotiation fails, fall back to creating a new session - session, err = newSession(SessionConfig{}) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err}) - return - } - - sd, err = session.ExchangeOffer(req.Sd) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err}) - return - } - - // Close the old session - writeJSONRPCEvent("otherSessionConnected", nil, currentSession) - peerConn := currentSession.peerConnection - go func() { - time.Sleep(1 * time.Second) - _ = peerConn.Close() - }() - - currentSession = session - logger.Info().Interface("session", session).Msg("new session created after renegotiation failure") - } else { - logger.Info().Msg("renegotiation successful") + c.JSON(http.StatusInternalServerError, gin.H{"error": err}) + return } + + sd, err = session.ExchangeOffer(req.Sd) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err}) + return + } + + // Notify the old session about the takeover + writeJSONRPCEvent("otherSessionConnected", nil, currentSession) + peerConn := currentSession.peerConnection + go func() { + time.Sleep(1 * time.Second) + _ = peerConn.Close() + }() + + currentSession = session + logger.Info().Interface("session", session).Msg("new session created, old session notified") } else { // No existing session, create a new one logger.Info().Msg("creating new session")