Skip to content

Commit 849e3d6

Browse files
authored
Merge pull request #2815 from robintown/keepalive-leave
Let leave requests outlive the window
2 parents 9ff6b35 + 4c6e1e5 commit 849e3d6

File tree

5 files changed

+36
-5
lines changed

5 files changed

+36
-5
lines changed

spec/unit/webrtc/groupCall.spec.ts

+20
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,32 @@ describe('Group Call', function() {
212212
],
213213
}),
214214
FAKE_USER_ID_1,
215+
{ keepAlive: false },
215216
);
216217
} finally {
217218
groupCall.leave();
218219
}
219220
});
220221

222+
it("sends member state event to room on leave", async () => {
223+
room.currentState.members[FAKE_USER_ID_1] = {
224+
userId: FAKE_USER_ID_1,
225+
} as unknown as RoomMember;
226+
227+
await groupCall.create();
228+
await groupCall.enter();
229+
mockSendState.mockClear();
230+
231+
groupCall.leave();
232+
expect(mockSendState).toHaveBeenCalledWith(
233+
FAKE_ROOM_ID,
234+
EventType.GroupCallMemberPrefix,
235+
expect.objectContaining({ "m.calls": [] }),
236+
FAKE_USER_ID_1,
237+
{ keepAlive: true }, // Request should outlive the window
238+
);
239+
});
240+
221241
it("starts with mic unmuted in regular calls", async () => {
222242
try {
223243
await groupCall.create();

src/client.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import {
6565
FileType,
6666
UploadResponse,
6767
HTTPError,
68+
IRequestOpts,
6869
} from "./http-api";
6970
import {
7071
Crypto,
@@ -7517,6 +7518,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
75177518
* @param {string} eventType
75187519
* @param {Object} content
75197520
* @param {string} stateKey
7521+
* @param {IRequestOpts} opts Options for the request function.
75207522
* @return {Promise} Resolves: TODO
75217523
* @return {module:http-api.MatrixError} Rejects: with an error response.
75227524
*/
@@ -7525,6 +7527,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
75257527
eventType: string,
75267528
content: any,
75277529
stateKey = "",
7530+
opts: IRequestOpts = {},
75287531
): Promise<ISendEventResponse> {
75297532
const pathParams = {
75307533
$roomId: roomId,
@@ -7535,7 +7538,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
75357538
if (stateKey !== undefined) {
75367539
path = utils.encodeUri(path + "/$stateKey", pathParams);
75377540
}
7538-
return this.http.authedRequest(Method.Put, path, undefined, content);
7541+
return this.http.authedRequest(Method.Put, path, undefined, content, opts);
75397542
}
75407543

75417544
/**

src/http-api/fetch.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ export class FetchHttpApi<O extends IHttpOpts> {
234234
method: Method,
235235
url: URL | string,
236236
body?: Body,
237-
opts: Pick<IRequestOpts, "headers" | "json" | "localTimeoutMs" | "abortSignal"> = {},
237+
opts: Pick<IRequestOpts, "headers" | "json" | "localTimeoutMs" | "keepAlive" | "abortSignal"> = {},
238238
): Promise<ResponseType<T, O>> {
239239
const headers = Object.assign({}, opts.headers || {});
240240
const json = opts.json ?? true;
@@ -252,6 +252,7 @@ export class FetchHttpApi<O extends IHttpOpts> {
252252
}
253253

254254
const timeout = opts.localTimeoutMs ?? this.opts.localTimeoutMs;
255+
const keepAlive = opts.keepAlive ?? false;
255256
const signals = [
256257
this.abortController.signal,
257258
];
@@ -284,6 +285,7 @@ export class FetchHttpApi<O extends IHttpOpts> {
284285
referrerPolicy: "no-referrer",
285286
cache: "no-cache",
286287
credentials: "omit", // we send credentials via headers
288+
keepalive: keepAlive,
287289
});
288290
} catch (e) {
289291
if ((<Error>e).name === "AbortError") {

src/http-api/interface.ts

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface IRequestOpts {
3838
headers?: Record<string, string>;
3939
abortSignal?: AbortSignal;
4040
localTimeoutMs?: number;
41+
keepAlive?: boolean; // defaults to false
4142
json?: boolean; // defaults to true
4243

4344
// Set to true to prevent the request function from emitting a Session.logged_out event.

src/webrtc/groupCall.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -726,10 +726,13 @@ export class GroupCall extends TypedEventEmitter<
726726
private async removeMemberStateEvent(): Promise<ISendEventResponse> {
727727
if (this.resendMemberStateTimer !== null) clearInterval(this.resendMemberStateTimer);
728728
this.resendMemberStateTimer = null;
729-
return await this.updateMemberCallState(undefined);
729+
return await this.updateMemberCallState(undefined, true);
730730
}
731731

732-
private async updateMemberCallState(memberCallState?: IGroupCallRoomMemberCallState): Promise<ISendEventResponse> {
732+
private async updateMemberCallState(
733+
memberCallState?: IGroupCallRoomMemberCallState,
734+
keepAlive = false,
735+
): Promise<ISendEventResponse> {
733736
const localUserId = this.client.getUserId()!;
734737

735738
const memberState = this.getMemberStateEvents(localUserId)?.getContent<IGroupCallRoomMemberState>();
@@ -758,7 +761,9 @@ export class GroupCall extends TypedEventEmitter<
758761
"m.expires_ts": Date.now() + CALL_MEMBER_STATE_TIMEOUT,
759762
};
760763

761-
return this.client.sendStateEvent(this.room.roomId, EventType.GroupCallMemberPrefix, content, localUserId);
764+
return this.client.sendStateEvent(
765+
this.room.roomId, EventType.GroupCallMemberPrefix, content, localUserId, { keepAlive },
766+
);
762767
}
763768

764769
public onMemberStateChanged = async (event: MatrixEvent) => {

0 commit comments

Comments
 (0)