@@ -99,6 +99,23 @@ func setupRouter() *gin.Engine {
9999 protected := r .Group ("/" )
100100 protected .Use (protectedMiddleware ())
101101 {
102+
103+ /*
104+ * Legacy WebRTC session endpoint
105+ *
106+ * This endpoint is maintained for backward compatibility when users upgrade from a version
107+ * using the legacy HTTP-based signaling method to the new WebSocket-based signaling method.
108+ *
109+ * During the upgrade process, when the "Rebooting device after update..." message appears,
110+ * the browser still runs the previous JavaScript code which polls this endpoint to establish
111+ * a new WebRTC session. Once the session is established, the page will automatically reload
112+ * with the updated code.
113+ *
114+ * Without this endpoint, the stale JavaScript would fail to establish a connection,
115+ * causing users to see the "Rebooting device after update..." message indefinitely
116+ * until they manually refresh the page, leading to a confusing user experience.
117+ */
118+ protected .POST ("/webrtc/session" , handleWebRTCSession )
102119 protected .GET ("/webrtc/signaling/client" , handleLocalWebRTCSignal )
103120 protected .POST ("/cloud/register" , handleCloudRegister )
104121 protected .GET ("/cloud/state" , handleCloudState )
@@ -126,6 +143,37 @@ func setupRouter() *gin.Engine {
126143// TODO: support multiple sessions?
127144var currentSession * Session
128145
146+ func handleWebRTCSession (c * gin.Context ) {
147+ var req WebRTCSessionRequest
148+
149+ if err := c .ShouldBindJSON (& req ); err != nil {
150+ c .JSON (http .StatusBadRequest , gin.H {"error" : err .Error ()})
151+ return
152+ }
153+
154+ session , err := newSession (SessionConfig {})
155+ if err != nil {
156+ c .JSON (http .StatusInternalServerError , gin.H {"error" : err })
157+ return
158+ }
159+
160+ sd , err := session .ExchangeOffer (req .Sd )
161+ if err != nil {
162+ c .JSON (http .StatusInternalServerError , gin.H {"error" : err })
163+ return
164+ }
165+ if currentSession != nil {
166+ writeJSONRPCEvent ("otherSessionConnected" , nil , currentSession )
167+ peerConn := currentSession .peerConnection
168+ go func () {
169+ time .Sleep (1 * time .Second )
170+ _ = peerConn .Close ()
171+ }()
172+ }
173+ currentSession = session
174+ c .JSON (http .StatusOK , gin.H {"sd" : sd })
175+ }
176+
129177func handleLocalWebRTCSignal (c * gin.Context ) {
130178 cloudLogger .Infof ("new websocket connection established" )
131179 // Create WebSocket options with InsecureSkipVerify to bypass origin check
0 commit comments