diff --git a/internal/events/websocket/mock_server/client.go b/internal/events/websocket/mock_server/client.go index 495d2b6..62d684e 100644 --- a/internal/events/websocket/mock_server/client.go +++ b/internal/events/websocket/mock_server/client.go @@ -19,6 +19,7 @@ type Client struct { keepAliveChanOpen bool keepAliveLoopChan chan struct{} keepAliveTimer *time.Ticker + keepAliveSeconds int pingChanOpen bool pingLoopChan chan struct{} pingTimer *time.Ticker diff --git a/internal/events/websocket/mock_server/server.go b/internal/events/websocket/mock_server/server.go index b776f38..5ec10fa 100644 --- a/internal/events/websocket/mock_server/server.go +++ b/internal/events/websocket/mock_server/server.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "net/http" + "strconv" "strings" "sync" "time" @@ -51,9 +52,18 @@ func (ws *WebSocketServer) WsPageHandler(w http.ResponseWriter, r *http.Request) // Connection successful. WebSocket is open. + // keepalive timeout + keepalive_seconds := KEEPALIVE_TIMEOUT_SECONDS + if keepalive_seconds_string := r.URL.Query().Get("keepalive_timeout_seconds"); keepalive_seconds_string != "" { + if val, err := strconv.Atoi(keepalive_seconds_string); err == nil && val >= 10 && val <= 600 { + keepalive_seconds = val + } + } + keepalive_duration := time.Duration(keepalive_seconds) * time.Second + // Get connected at time and set automatic read timeout connectedAtTimestamp := time.Now().UTC().Format(time.RFC3339Nano) - conn.SetReadDeadline(time.Now().Add(time.Second * KEEPALIVE_TIMEOUT_SECONDS)) + conn.SetReadDeadline(time.Now().Add(keepalive_duration)) client := &Client{ clientName: util.RandomGUID()[:8], @@ -62,6 +72,7 @@ func (ws *WebSocketServer) WsPageHandler(w http.ResponseWriter, r *http.Request) connectionUrl: fmt.Sprintf("%v://%v/ws", serverManager.protocolHttp, r.Host), KeepAliveEnabled: true, keepAliveChanOpen: false, + keepAliveSeconds: keepalive_seconds, pingChanOpen: false, } @@ -129,7 +140,7 @@ func (ws *WebSocketServer) WsPageHandler(w http.ResponseWriter, r *http.Request) Session: WelcomeMessagePayloadSession{ ID: fmt.Sprintf("%v_%v", ws.ServerId, client.clientName), Status: "connected", - KeepaliveTimeoutSeconds: KEEPALIVE_TIMEOUT_SECONDS, + KeepaliveTimeoutSeconds: keepalive_seconds, ReconnectUrl: nil, ConnectedAt: connectedAtTimestamp, }, @@ -156,7 +167,7 @@ func (ws *WebSocketServer) WsPageHandler(w http.ResponseWriter, r *http.Request) } // Set up ping/pong and keepalive handling - client.keepAliveTimer = time.NewTicker(10 * time.Second) + client.keepAliveTimer = time.NewTicker(keepalive_duration) client.pingTimer = time.NewTicker(5 * time.Second) client.keepAliveLoopChan = make(chan struct{}) client.pingLoopChan = make(chan struct{}) @@ -319,6 +330,12 @@ func (ws *WebSocketServer) InitiateRestart() { reconnectId = reconnectId[:len(reconnectId)-1] clientConnectionUrl := strings.Replace(client.connectionUrl, "http://", "ws://", -1) clientConnectionUrl = strings.Replace(clientConnectionUrl, "https://", "wss://", -1) + var reconnecturl string + if client.keepAliveSeconds != KEEPALIVE_TIMEOUT_SECONDS { + reconnecturl = fmt.Sprintf("%v?reconnect_id=%v&keepalive_timeout_seconds=%d", clientConnectionUrl, reconnectId, client.keepAliveSeconds) + } else { + reconnecturl = fmt.Sprintf("%v?reconnect_id=%v", clientConnectionUrl, reconnectId) + } reconnectMsg, _ := json.Marshal( ReconnectMessage{ Metadata: MessageMetadata{ @@ -331,7 +348,7 @@ func (ws *WebSocketServer) InitiateRestart() { ID: sessionId, Status: "reconnecting", KeepaliveTimeoutSeconds: nil, - ReconnectUrl: fmt.Sprintf("%v?reconnect_id=%v", clientConnectionUrl, reconnectId), + ReconnectUrl: reconnecturl, ConnectedAt: client.ConnectedAtTimestamp, }, },