Skip to content

Commit 05de2f0

Browse files
committed
refactor with ServerTimeSync
Signed-off-by: Timo K <[email protected]>
1 parent 348c37f commit 05de2f0

File tree

3 files changed

+91
-11
lines changed

3 files changed

+91
-11
lines changed

Diff for: src/matrixrtc/CallMembership.ts

+6-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ limitations under the License.
1515
*/
1616

1717
import { MatrixEvent } from "../matrix";
18+
import * as ServeTimeSync from "../server-time-sync";
1819
import { deepCompare } from "../utils";
1920
import { Focus } from "./focus";
2021

@@ -101,16 +102,12 @@ export class CallMembership {
101102

102103
// gets the expiry time of the event, converted into the device's local time
103104
public getLocalExpiry(): number {
104-
if (this.data.expires_ts) {
105-
// With expires_ts we cannot convert to local time.
106-
// TODO: Check the server timestamp and compute a diff to local time.
107-
return this.data.expires_ts;
105+
ServeTimeSync.tryComputeTimeSyncWithEvent(this.parentEvent);
106+
if (this.data.expires) {
107+
return ServeTimeSync.serverTsToLocalTs(this.createdTs()) + this.data.expires!;
108108
} else {
109-
const relativeCreationTime = this.parentEvent.getTs() - this.createdTs();
110-
111-
const localCreationTs = this.parentEvent.localTimestamp - relativeCreationTime;
112-
113-
return localCreationTs + this.data.expires!;
109+
// We know it exists because we checked for this in the constructor.
110+
return ServeTimeSync.serverTsToLocalTs(this.data.expires_ts!);
114111
}
115112
}
116113

Diff for: src/matrixrtc/MatrixRTCSession.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { MatrixError, MatrixEvent } from "../matrix";
2626
import { randomString, secureRandomBase64Url } from "../randomstring";
2727
import { EncryptionKeysEventContent } from "./types";
2828
import { decodeBase64, encodeUnpaddedBase64 } from "../base64";
29+
import * as ServerTimeSync from "../server-time-sync";
2930

3031
const MEMBERSHIP_EXPIRY_TIME = 60 * 60 * 1000;
3132
const MEMBER_EVENT_CHECK_PERIOD = 2 * 60 * 1000; // How often we check to see if we need to re-send our member event
@@ -625,8 +626,7 @@ export class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSessionEvent, M
625626

626627
if (prevMembership) m.created_ts = prevMembership.createdTs();
627628
if (m.created_ts) m.expires_ts = m.created_ts + (m.expires ?? 0);
628-
// TODO: Date.now() should be the origin_server_ts (now).
629-
else m.expires_ts = Date.now() + (m.expires ?? 0);
629+
else m.expires_ts = ServerTimeSync.getServerTimeNow() + (m.expires ?? 0);
630630

631631
return m;
632632
}

Diff for: src/server-time-sync.ts

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { logger } from "./logger";
2+
import { MatrixEvent } from "./matrix";
3+
4+
/*
5+
Copyright 2021-2024 The Matrix.org Foundation C.I.C.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
*/
19+
let serverToLocalTimeOffset: number | undefined = undefined;
20+
21+
/**
22+
* This method should only be used after computing the server-client time offset
23+
* using: tryComputeTimeSyncWithEvent or computeTimeSyncWithRequest.
24+
*/
25+
const getServerToLocalTimeOffset = (): number => {
26+
if (!serverToLocalTimeOffset) {
27+
logger.warn("Server time offset not computed yet, using 0");
28+
serverToLocalTimeOffset = 0;
29+
}
30+
if (!serverToLocalTimeOffset) throw new Error("Failed to compute time sync");
31+
32+
return serverToLocalTimeOffset;
33+
};
34+
/**
35+
* This uses a matrix event with an age property to compute the time offset.
36+
* This also works when the event was not just now received from the homeserver
37+
* because the event tracks the time since it has been received via the localTimestamp.
38+
* @param event - The matrix event used to compute the time offset.
39+
* @returns true if the time offset computation was successful, false otherwise
40+
*/
41+
export const tryComputeTimeSyncWithEvent = (event: MatrixEvent): boolean => {
42+
const serverTimeNow = event.getTs() + event.getLocalAge();
43+
serverToLocalTimeOffset = serverTimeNow - Date.now();
44+
45+
return true;
46+
};
47+
48+
/**
49+
* Computes the time offset between the server and the local machine by sending
50+
* a http request to the server.
51+
* (UNIMPLEMNENTED)
52+
* @returns true if the time offset computation was successful, false otherwise
53+
*/
54+
export const computeTimeSyncWithRequest = async (): Promise<boolean> => {
55+
// TODO: fetch time now from server (temporarily use offset of 0)
56+
serverToLocalTimeOffset = 0;
57+
return true;
58+
// await ...
59+
};
60+
61+
/**
62+
* This method should only be used after computing the server-client time offset
63+
* using: tryComputeTimeSyncWithEvent or computeTimeSyncWithRequest.
64+
*/
65+
export const getServerTimeNow = (): number => {
66+
return localTsToServerTs(Date.now());
67+
};
68+
69+
/**
70+
* This method should only be used after computing the server-client time offset
71+
* using: tryComputeTimeSyncWithEvent or computeTimeSyncWithRequest.
72+
*/
73+
export const serverTsToLocalTs = (serverTs: number): number => {
74+
return serverTs + getServerToLocalTimeOffset();
75+
};
76+
77+
/**
78+
* This method should only be used after computing the server-client time offset
79+
* using: tryComputeTimeSyncWithEvent or computeTimeSyncWithRequest.
80+
*/
81+
export const localTsToServerTs = (localTs: number): number => {
82+
return localTs - getServerToLocalTimeOffset();
83+
};

0 commit comments

Comments
 (0)