Skip to content

Commit 9dc3e6f

Browse files
authored
[IMPROVE] Send only relevant data via WebSocket (RocketChat#22258)
1 parent 8a1eb6e commit 9dc3e6f

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

server/modules/watchers/watchers.module.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,21 @@ type Watcher = <T extends IBaseData>(model: IBaseRaw<T>, fn: (event: IChange<T>)
6666

6767
type BroadcastCallback = <T extends keyof EventSignatures>(event: T, ...args: Parameters<EventSignatures[T]>) => Promise<void>;
6868

69+
const hasKeys = (requiredKeys: string[]): (data?: Record<string, any>) => boolean =>
70+
(data?: Record<string, any>): boolean => {
71+
if (!data) {
72+
return false;
73+
}
74+
75+
return Object.keys(data)
76+
.filter((key) => key !== '_id')
77+
.map((key) => key.split('.')[0])
78+
.some((key) => requiredKeys.includes(key));
79+
};
80+
81+
const hasRoomFields = hasKeys(Object.keys(roomFields));
82+
const hasSubscriptionFields = hasKeys(Object.keys(subscriptionFields));
83+
6984
const startMonitor = typeof process.env.DISABLE_PRESENCE_MONITOR === 'undefined'
7085
|| !['true', 'yes'].includes(String(process.env.DISABLE_PRESENCE_MONITOR).toLowerCase());
7186

@@ -125,10 +140,14 @@ export function initWatchers(models: IModelsParam, broadcast: BroadcastCallback,
125140
}
126141
});
127142

128-
watch<ISubscription>(Subscriptions, async ({ clientAction, id }) => {
143+
watch<ISubscription>(Subscriptions, async ({ clientAction, id, data, diff }) => {
129144
switch (clientAction) {
130145
case 'inserted':
131146
case 'updated': {
147+
if (!hasSubscriptionFields(data || diff)) {
148+
return;
149+
}
150+
132151
// Override data cuz we do not publish all fields
133152
const subscription = await Subscriptions.findOneById(id, { projection: subscriptionFields });
134153
if (!subscription) {
@@ -283,12 +302,16 @@ export function initWatchers(models: IModelsParam, broadcast: BroadcastCallback,
283302
broadcast('watch.settings', { clientAction, setting });
284303
});
285304

286-
watch<IRoom>(Rooms, async ({ clientAction, id, data }) => {
305+
watch<IRoom>(Rooms, async ({ clientAction, id, data, diff }) => {
287306
if (clientAction === 'removed') {
288307
broadcast('watch.rooms', { clientAction, room: { _id: id } });
289308
return;
290309
}
291310

311+
if (!hasRoomFields(data || diff)) {
312+
return;
313+
}
314+
292315
const room = data ?? await Rooms.findOneById(id, { projection: roomFields });
293316
if (!room) {
294317
return;

0 commit comments

Comments
 (0)