Skip to content

Commit 4137b82

Browse files
authored
feat(websocket): handle ping messages sent from react and add logging (#346)
1 parent 929e3a6 commit 4137b82

File tree

4 files changed

+46
-15
lines changed

4 files changed

+46
-15
lines changed

cloud.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@ func runWebsocketClient() error {
275275
defer cancelDial()
276276
c, _, err := websocket.Dial(dialCtx, wsURL.String(), &websocket.DialOptions{
277277
HTTPHeader: header,
278+
OnPingReceived: func(ctx context.Context, payload []byte) bool {
279+
websocketLogger.Infof("ping frame received: %v, source: %s, sourceType: cloud", payload, wsURL.Host)
280+
return true
281+
},
278282
})
279283
if err != nil {
280284
return err

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ toolchain go1.21.1
77
require (
88
github.com/Masterminds/semver/v3 v3.3.0
99
github.com/beevik/ntp v1.3.1
10-
github.com/coder/websocket v1.8.12
10+
github.com/coder/websocket v1.8.13
1111
github.com/coreos/go-oidc/v3 v3.11.0
1212
github.com/creack/pty v1.1.23
1313
github.com/gin-gonic/gin v1.9.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
1818
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
1919
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
2020
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
21+
github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE=
22+
github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
2123
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
2224
github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
2325
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=

web.go

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package kvm
22

33
import (
4+
"bytes"
45
"context"
56
"embed"
67
"encoding/json"
@@ -173,11 +174,24 @@ func handleWebRTCSession(c *gin.Context) {
173174
c.JSON(http.StatusOK, gin.H{"sd": sd})
174175
}
175176

177+
var (
178+
pingMessage = []byte("ping")
179+
pongMessage = []byte("pong")
180+
)
181+
176182
func handleLocalWebRTCSignal(c *gin.Context) {
177183
cloudLogger.Infof("new websocket connection established")
184+
185+
// get the source from the request
186+
source := c.ClientIP()
187+
178188
// Create WebSocket options with InsecureSkipVerify to bypass origin check
179189
wsOptions := &websocket.AcceptOptions{
180190
InsecureSkipVerify: true, // Allow connections from any origin
191+
OnPingReceived: func(ctx context.Context, payload []byte) bool {
192+
websocketLogger.Infof("ping frame received: %v, source: %s, sourceType: local", payload, source)
193+
return true
194+
},
181195
}
182196

183197
wsCon, err := websocket.Accept(c.Writer, c.Request, wsOptions)
@@ -186,9 +200,6 @@ func handleLocalWebRTCSignal(c *gin.Context) {
186200
return
187201
}
188202

189-
// get the source from the request
190-
source := c.ClientIP()
191-
192203
// Now use conn for websocket operations
193204
defer wsCon.Close(websocket.StatusNormalClosure, "")
194205

@@ -211,7 +222,6 @@ func handleWebRTCSignalWsMessages(wsCon *websocket.Conn, isCloudConnection bool,
211222

212223
// Add connection tracking to detect reconnections
213224
connectionID := uuid.New().String()
214-
cloudLogger.Infof("new websocket connection established with ID: %s", connectionID)
215225

216226
// connection type
217227
var sourceType string
@@ -223,18 +233,20 @@ func handleWebRTCSignalWsMessages(wsCon *websocket.Conn, isCloudConnection bool,
223233

224234
// probably we can use a better logging framework here
225235
logInfof := func(format string, args ...interface{}) {
226-
args = append(args, source, sourceType)
227-
websocketLogger.Infof(format+", source: %s, sourceType: %s", args...)
236+
args = append(args, source, sourceType, connectionID)
237+
websocketLogger.Infof(format+", source: %s, sourceType: %s, id: %s", args...)
228238
}
229239
logWarnf := func(format string, args ...interface{}) {
230-
args = append(args, source, sourceType)
231-
websocketLogger.Warnf(format+", source: %s, sourceType: %s", args...)
240+
args = append(args, source, sourceType, connectionID)
241+
websocketLogger.Warnf(format+", source: %s, sourceType: %s, id: %s", args...)
232242
}
233243
logTracef := func(format string, args ...interface{}) {
234-
args = append(args, source, sourceType)
235-
websocketLogger.Tracef(format+", source: %s, sourceType: %s", args...)
244+
args = append(args, source, sourceType, connectionID)
245+
websocketLogger.Tracef(format+", source: %s, sourceType: %s, id: %s", args...)
236246
}
237247

248+
logInfof("new websocket connection established")
249+
238250
go func() {
239251
for {
240252
time.Sleep(WebsocketPingInterval)
@@ -245,7 +257,7 @@ func handleWebRTCSignalWsMessages(wsCon *websocket.Conn, isCloudConnection bool,
245257
metricConnectionPingDuration.WithLabelValues(sourceType, source).Observe(v)
246258
}))
247259

248-
logInfof("pinging websocket")
260+
logTracef("sending ping frame")
249261
err := wsCon.Ping(runCtx)
250262

251263
if err != nil {
@@ -255,10 +267,12 @@ func handleWebRTCSignalWsMessages(wsCon *websocket.Conn, isCloudConnection bool,
255267
}
256268

257269
// dont use `defer` here because we want to observe the duration of the ping
258-
timer.ObserveDuration()
270+
duration := timer.ObserveDuration()
259271

260272
metricConnectionTotalPingCount.WithLabelValues(sourceType, source).Inc()
261273
metricConnectionLastPingTimestamp.WithLabelValues(sourceType, source).SetToCurrentTime()
274+
275+
logTracef("received pong frame, duration: %v", duration)
262276
}
263277
}()
264278

@@ -296,6 +310,16 @@ func handleWebRTCSignalWsMessages(wsCon *websocket.Conn, isCloudConnection bool,
296310
Data json.RawMessage `json:"data"`
297311
}
298312

313+
if bytes.Equal(msg, pingMessage) {
314+
logInfof("ping message received: %s", string(msg))
315+
err = wsCon.Write(context.Background(), websocket.MessageText, pongMessage)
316+
if err != nil {
317+
logWarnf("unable to write pong message: %v", err)
318+
return err
319+
}
320+
continue
321+
}
322+
299323
err = json.Unmarshal(msg, &message)
300324
if err != nil {
301325
logWarnf("unable to parse ws message: %v", err)
@@ -311,8 +335,9 @@ func handleWebRTCSignalWsMessages(wsCon *websocket.Conn, isCloudConnection bool,
311335
continue
312336
}
313337

314-
logInfof("new session request: %v", req.OidcGoogle)
315-
logTracef("session request info: %v", req)
338+
if req.OidcGoogle != "" {
339+
logInfof("new session request with OIDC Google: %v", req.OidcGoogle)
340+
}
316341

317342
metricConnectionSessionRequestCount.WithLabelValues(sourceType, source).Inc()
318343
metricConnectionLastSessionRequestTimestamp.WithLabelValues(sourceType, source).SetToCurrentTime()

0 commit comments

Comments
 (0)