Skip to content

Commit

Permalink
add websocket onClose callback
Browse files Browse the repository at this point in the history
  • Loading branch information
mhiaror committed Jan 30, 2024
1 parent cef17c3 commit 6002cb4
Show file tree
Hide file tree
Showing 9 changed files with 4,048 additions and 6,758 deletions.
10,740 changes: 3,982 additions & 6,758 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const ACPS_METHODS = {

export const WEBSOCKET_EVENTS = {
ConnectionLost: "WebsocketConnectionLost",
ConnectionClose: "WebsocketConnectionClose",
ConnectionGained: "WebsocketConnectionGained",
Ended: "WebsocketEnded",
IncomingMessage: "WebsocketIncomingMessage",
Expand All @@ -56,6 +57,7 @@ export const CHAT_EVENTS = {
INCOMING_DELIVERED_RECEIPT: "INCOMING_DELIVERED_RECEIPT",
CONNECTION_ESTABLISHED: "CONNECTION_ESTABLISHED",
CONNECTION_LOST: "CONNECTION_LOST",
CONNECTION_CLOSE: "CONNECTION_CLOSE",
CONNECTION_BROKEN: "CONNECTION_BROKEN",
CONNECTION_ACK: "CONNECTION_ACK",
CHAT_ENDED: "CHAT_ENDED",
Expand Down
10 changes: 10 additions & 0 deletions src/core/chatController.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ class ChatController {
this.connectionDetails = connectionDetails;
this.connectionHelper.onEnded(this._handleEndedConnection.bind(this));
this.connectionHelper.onConnectionLost(this._handleLostConnection.bind(this));
this.connectionHelper.onConnectionClose(this._handleCloseConnection.bind(this));
this.connectionHelper.onConnectionGain(this._handleGainedConnection.bind(this));
this.connectionHelper.onMessage(this._handleIncomingMessage.bind(this));
return this.connectionHelper.start();
Expand Down Expand Up @@ -267,6 +268,13 @@ class ChatController {
});
}

_handleCloseConnection(eventData) {
this._forwardChatEvent(CHAT_EVENTS.CONNECTION_CLOSE, {
data: eventData,
chatDetails: this.getChatDetails()
});
}

_handleGainedConnection(eventData) {
this.hasChatEnded = false;

Expand Down Expand Up @@ -430,6 +438,8 @@ class ChatController {
return NetworkLinkStatus.Broken;
case ConnectionHelperStatus.ConnectionLost:
return NetworkLinkStatus.Broken;
case ConnectionHelperStatus.ConnectionClose:
return NetworkLinkStatus.Broken;
case ConnectionHelperStatus.Connected:
return NetworkLinkStatus.Established;
}
Expand Down
1 change: 1 addition & 0 deletions src/core/chatController.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ describe("ChatController", () => {
onEndedHandlers.push(handlers);
},
onConnectionLost: () => {},
onConnectionClose: () => {},
onConnectionGain: () => {},
onMessage: (handler) => {
messageHandlers.push(handler);
Expand Down
4 changes: 4 additions & 0 deletions src/core/chatSession.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ export class ChatSession {
onConnectionLost(callback) {
this.controller.subscribe(CHAT_EVENTS.CONNECTION_LOST, callback);
}

onConnectionClose(callback) {
this.controller.subscribe(CHAT_EVENTS.CONNECTION_CLOSE, callback);
}

sendMessage(args) {
return this.controller.sendMessage(args);
Expand Down
4 changes: 4 additions & 0 deletions src/core/chatSession.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ describe("chatSession", () => {
const cb9 = jest.fn();
const cb10 = jest.fn();
const cb11 = jest.fn();
const cb12 = jest.fn();

session.onParticipantIdle(cb1);
session.onParticipantReturned(cb2);
Expand All @@ -92,6 +93,7 @@ describe("chatSession", () => {
session.onConnectionEstablished(cb9);
session.onEnded(cb10);
session.onConnectionLost(cb11);
session.onConnectionClose(cb12);

controller._forwardChatEvent(CHAT_EVENTS.PARTICIPANT_IDLE, eventData);
controller._forwardChatEvent(CHAT_EVENTS.PARTICIPANT_RETURNED, eventData);
Expand All @@ -104,6 +106,7 @@ describe("chatSession", () => {
controller._forwardChatEvent(CHAT_EVENTS.CONNECTION_ESTABLISHED, eventData);
controller._forwardChatEvent(CHAT_EVENTS.CHAT_ENDED, eventData);
controller._forwardChatEvent(CHAT_EVENTS.CONNECTION_LOST, eventData);
controller._forwardChatEvent(CHAT_EVENTS.CONNECTION_CLOSE, eventData);

await new Promise((r) => setTimeout(r, 0));

Expand All @@ -118,6 +121,7 @@ describe("chatSession", () => {
expect(cb9).toHaveBeenCalled();
expect(cb10).toHaveBeenCalled();
expect(cb11).toHaveBeenCalled();
expect(cb12).toHaveBeenCalled();
});

test('events', () => {
Expand Down
24 changes: 24 additions & 0 deletions src/core/connectionHelpers/LpcConnectionHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ class LpcConnectionHelper extends BaseConnectionHelper {
this.subscriptions = [
this.baseInstance.onEnded(this.handleEnded.bind(this)),
this.baseInstance.onConnectionGain(this.handleConnectionGain.bind(this)),
// connection-lost if fired when both primary and secondary websocket connection have been closed!
this.baseInstance.onConnectionLost(this.handleConnectionLost.bind(this)),
// connection-close is fired when any websocket connection is closed,
// connection-lost is fired after connection-close event,
this.baseInstance.onConnectionClose(this.handleConnectionClose.bind(this)),
this.baseInstance.onMessage(this.handleMessage.bind(this))
];
}
Expand Down Expand Up @@ -96,10 +100,18 @@ class LpcConnectionHelper extends BaseConnectionHelper {
return this.eventBus.subscribe(ConnectionHelperEvents.ConnectionLost, handler);
}

onConnectionClose(handler) {
return this.eventBus.subscribe(ConnectionHelperEvents.ConnectionClose, handler);
}

handleConnectionLost() {
this.eventBus.trigger(ConnectionHelperEvents.ConnectionLost, {});
}

handleConnectionClose() {
this.eventBus.trigger(ConnectionHelperEvents.ConnectionClose, {});
}

onMessage(handler) {
return this.eventBus.subscribe(ConnectionHelperEvents.IncomingMessage, handler);
}
Expand Down Expand Up @@ -133,6 +145,7 @@ class LpcConnectionHelperBase {
this.websocketManager.onMessage("aws/chat", this.handleMessage.bind(this)),
this.websocketManager.onConnectionGain(this.handleConnectionGain.bind(this)),
this.websocketManager.onConnectionLost(this.handleConnectionLost.bind(this)),
this.websocketManager.onConnectionClose(this.handleConnectionClose.bind(this)),
this.websocketManager.onInitFailure(this.handleEnded.bind(this))
];
this.logger.info("Initializing websocket manager.");
Expand Down Expand Up @@ -230,13 +243,24 @@ class LpcConnectionHelperBase {
return this.eventBus.subscribe(ConnectionHelperEvents.ConnectionLost, handler);
}

onConnectionClose(handler) {
return this.eventBus.subscribe(ConnectionHelperEvents.ConnectionClose, handler);
}

handleConnectionLost() {
this.status = ConnectionHelperStatus.ConnectionLost;
this.eventBus.trigger(ConnectionHelperEvents.ConnectionLost, {});
csmService.addCountMetric(WEBSOCKET_EVENTS.ConnectionLost, CSM_CATEGORY.API);
this.logger.info("Websocket connection lost.");
}

handleConnectionClose() {
this.status = ConnectionHelperStatus.ConnectionClose;
this.eventBus.trigger(ConnectionHelperEvents.ConnectionClose, {});
csmService.addCountMetric(WEBSOCKET_EVENTS.ConnectionClose, CSM_CATEGORY.API);
this.logger.info("Websocket connection close.");
}

onMessage(handler) {
return this.eventBus.subscribe(ConnectionHelperEvents.IncomingMessage, handler);
}
Expand Down
19 changes: 19 additions & 0 deletions src/core/connectionHelpers/LpcConnectionHelper.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe("LpcConnectionHelper", () => {
function createWebsocketManager() {
const messageHandlers = [];
const connectionLostHandlers = [];
const connectionCloseHandlers = [];
const connectionGainHandlers = [];
const endedHandlers = [];
const refreshHandlers = [];
Expand All @@ -39,6 +40,10 @@ describe("LpcConnectionHelper", () => {
connectionLostHandlers.push(handler);
return () => { };
}),
onConnectionClose: jest.fn((handler) => {
connectionCloseHandlers.push(handler);
return () => { };
}),
onInitFailure: jest.fn((handler) => {
endedHandlers.push(handler);
return () => { };
Expand All @@ -52,6 +57,9 @@ describe("LpcConnectionHelper", () => {
$simulateConnectionLost() {
connectionLostHandlers.forEach(f => f());
},
$simulateConnectionClose() {
connectionCloseHandlers.forEach(f => f());
},
$simulateConnectionGain() {
connectionGainHandlers.forEach(f => f());
},
Expand Down Expand Up @@ -121,6 +129,17 @@ describe("LpcConnectionHelper", () => {
expect(onConnectionLostHandler1).toHaveBeenCalledTimes(1);
expect(onConnectionLostHandler2).toHaveBeenCalledTimes(1);
});

test("onConnectionClose handler is called", () => {
const websocketManager = createWebsocketManager();
const onConnectionCloseHandler1 = jest.fn();
const onConnectionCloseHandler2 = jest.fn();
getLpcConnectionHelper("id1", websocketManager).onConnectionClose(onConnectionCloseHandler1);
getLpcConnectionHelper("id2", websocketManager).onConnectionClose(onConnectionCloseHandler2);
websocketManager.$simulateConnectionClose();
expect(onConnectionCloseHandler1).toHaveBeenCalledTimes(1);
expect(onConnectionCloseHandler2).toHaveBeenCalledTimes(1);
});

test("onConnectionGain handler is called", () => {
const websocketManager = createWebsocketManager();
Expand Down
2 changes: 2 additions & 0 deletions src/core/connectionHelpers/baseConnectionHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ const ConnectionHelperStatus = {
Starting: "Starting",
Connected: "Connected",
ConnectionLost: "ConnectionLost",
ConnectionClose: "ConnectionClose",
Ended: "Ended"
};

const ConnectionHelperEvents = {
ConnectionLost: "ConnectionLost", // event data is: {reason: ...}
ConnectionClose: "ConnectionClose", // event data is: {reason: ...}
ConnectionGained: "ConnectionGained", // event data is: {reason: ...}
Ended: "Ended", // event data is: {reason: ...}
IncomingMessage: "IncomingMessage" // event data is: {payloadString: ...}
Expand Down

0 comments on commit 6002cb4

Please sign in to comment.