Skip to content

Commit 0d39c05

Browse files
authored
Merge pull request #771 from aws-samples/qnastreaming/heartbeat
[Aws-lex-web-ui] add heartbeat for streaming responses to prevent idle timeout of 10 mins
2 parents de518e5 + 44dd09f commit 0d39c05

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

lex-web-ui/src/store/actions.js

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,11 +710,11 @@ export default {
710710

711711
wsClient.onmessage = (event) => {
712712
if(event.data!=='/stop/' && context.getters.isStartingTypingWsMessages()){
713-
console.info("streaming ", context.getters.isStartingTypingWsMessages());
713+
console.info('Streaming: ', context.getters.isStartingTypingWsMessages());
714714
context.commit('pushWebSocketMessage',event.data);
715715
context.dispatch('typingWsMessages')
716716
}else{
717-
console.info('stopping streaming');
717+
console.info('Currently not streaming');
718718
}
719719
}
720720
}
@@ -1304,6 +1304,41 @@ export default {
13041304

13051305
const signedUrl = Signer.signUrl(context.state.config.lex.streamingWebSocketEndpoint+'?sessionId='+sessionId, accessInfo, serviceInfo);
13061306
wsClient = new WebSocket(signedUrl);
1307+
1308+
// Add heartbeat logic
1309+
const HEARTBEAT_INTERVAL = 540000; // 9 minutes
1310+
const MAX_DURATION = 7200000; // 2 hours
1311+
const startTime = Date.now();
1312+
let heartbeatTimer = null;
1313+
1314+
function startHeartbeat() {
1315+
if (wsClient.readyState === WebSocket.OPEN) {
1316+
const elapsedTime = Date.now() - startTime;
1317+
if (elapsedTime < MAX_DURATION) {
1318+
const pingMessage = JSON.stringify({ action: 'ping' });
1319+
wsClient.send(pingMessage);
1320+
console.log('Sending Ping:', new Date().toISOString());
1321+
heartbeatTimer = setTimeout(startHeartbeat, HEARTBEAT_INTERVAL);
1322+
} else {
1323+
console.log('Stopped sending pings after reaching 2-hour limit.');
1324+
clearTimeout(heartbeatTimer);
1325+
}
1326+
}
1327+
}
1328+
wsClient.onopen = () => {
1329+
console.log('WebSocket Connected');
1330+
startHeartbeat();
1331+
};
1332+
1333+
wsClient.onclose = () => {
1334+
console.log('WebSocket Closed');
1335+
clearTimeout(heartbeatTimer);
1336+
};
1337+
1338+
wsClient.onerror = (error) => {
1339+
console.log('WebSocket Error', error.message);
1340+
clearTimeout(heartbeatTimer);
1341+
};
13071342
},
13081343
typingWsMessages(context){
13091344
if (context.getters.wsMessagesCurrentIndex()<context.getters.wsMessagesLength()-1){

templates/streaming-support.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,34 @@ Resources:
169169
IntegrationUri:
170170
Fn::Sub:
171171
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${StreamingLambda.Arn}/invocations
172+
173+
PingRoute:
174+
Type: AWS::ApiGatewayV2::Route
175+
Properties:
176+
ApiId: !Ref StreamingWebSocket
177+
RouteKey: ping
178+
OperationName: PingRoute
179+
Target: !Join
180+
- '/'
181+
- - 'integrations'
182+
- !Ref PingIntegration
183+
184+
PingIntegration:
185+
Type: AWS::ApiGatewayV2::Integration
186+
Properties:
187+
ApiId: !Ref StreamingWebSocket
188+
Description: Ping Integration
189+
IntegrationType: MOCK
190+
PassthroughBehavior: WHEN_NO_MATCH
191+
RequestTemplates:
192+
application/json: '{"statusCode":200}'
193+
172194

173195
Deployment:
174196
Type: AWS::ApiGatewayV2::Deployment
175197
DependsOn:
176198
- ConnectRoute
199+
- PingRoute
177200
Properties:
178201
ApiId: !Ref StreamingWebSocket
179202

0 commit comments

Comments
 (0)