Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
---
changelog:
- date: 2025-03-20
version: v9.3.0
changes:
- type: feature
text: "Remove minimum limit for presence timeout (was 20 seconds) to make it possible specify shorter intervals."
- type: bug
text: "Fix issue because of which channels not aggregated and caused separate heartbeat requests."
- date: 2025-03-19
version: v9.2.0
changes:
Expand Down Expand Up @@ -1185,7 +1192,7 @@ supported-platforms:
- 'Ubuntu 14.04 and up'
- 'Windows 7 and up'
version: 'Pubnub Javascript for Node'
version: '9.2.0'
version: '9.3.0'
sdks:
- full-name: PubNub Javascript SDK
short-name: Javascript
Expand All @@ -1201,7 +1208,7 @@ sdks:
- distribution-type: source
distribution-repository: GitHub release
package-name: pubnub.js
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.2.0.zip
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.3.0.zip
requires:
- name: 'agentkeepalive'
min-version: '3.5.2'
Expand Down Expand Up @@ -1872,7 +1879,7 @@ sdks:
- distribution-type: library
distribution-repository: GitHub release
package-name: pubnub.js
location: https://github.com/pubnub/javascript/releases/download/v9.2.0/pubnub.9.2.0.js
location: https://github.com/pubnub/javascript/releases/download/v9.3.0/pubnub.9.3.0.js
requires:
- name: 'agentkeepalive'
min-version: '3.5.2'
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## v9.3.0
March 20 2025

#### Added
- Remove minimum limit for presence timeout (was 20 seconds) to make it possible specify shorter intervals.

#### Fixed
- Fix issue because of which channels not aggregated and caused separate heartbeat requests.

## v9.2.0
March 19 2025

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ Watch [Getting Started with PubNub JS SDK](https://app.dashcam.io/replay/64ee0d2
npm install pubnub
```
* or download one of our builds from our CDN:
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.2.0.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.2.0.min.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.3.0.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.3.0.min.js

2. Configure your keys:

Expand Down
21 changes: 14 additions & 7 deletions dist/web/pubnub.js
Original file line number Diff line number Diff line change
Expand Up @@ -3594,9 +3594,9 @@
*/
const PRESENCE_TIMEOUT = 300;
/**
* Minimum user presence timeout.
* Maximum user presence timeout.
*/
const PRESENCE_TIMEOUT_MINIMUM = 20;
const PRESENCE_TIMEOUT_MAXIMUM = 320;
/**
* Apply configuration default values.
*
Expand Down Expand Up @@ -3637,10 +3637,17 @@
publishKey: configurationCopy.publishKey,
secretKey: configurationCopy.secretKey,
};
if (configurationCopy.presenceTimeout !== undefined && configurationCopy.presenceTimeout < PRESENCE_TIMEOUT_MINIMUM) {
configurationCopy.presenceTimeout = PRESENCE_TIMEOUT_MINIMUM;
// eslint-disable-next-line no-console
console.log('WARNING: Presence timeout is less than the minimum. Using minimum value: ', PRESENCE_TIMEOUT_MINIMUM);
if (configurationCopy.presenceTimeout !== undefined) {
if (configurationCopy.presenceTimeout > PRESENCE_TIMEOUT_MAXIMUM) {
configurationCopy.presenceTimeout = PRESENCE_TIMEOUT_MAXIMUM;
// eslint-disable-next-line no-console
console.warn('WARNING: Presence timeout is larger than the maximum. Using maximum value: ', PRESENCE_TIMEOUT_MAXIMUM);
}
else if (configurationCopy.presenceTimeout <= 0) {
// eslint-disable-next-line no-console
console.warn('WARNING: Presence timeout should be larger than zero.');
delete configurationCopy.presenceTimeout;
}
}
if (configurationCopy.presenceTimeout !== undefined)
configurationCopy.heartbeatInterval = configurationCopy.presenceTimeout / 2 - 1;
Expand Down Expand Up @@ -3932,7 +3939,7 @@
return base.PubNubFile;
},
get version() {
return '9.2.0';
return '9.3.0';
},
getVersion() {
return this.version;
Expand Down
4 changes: 2 additions & 2 deletions dist/web/pubnub.min.js

Large diffs are not rendered by default.

45 changes: 28 additions & 17 deletions dist/web/pubnub.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@
const hbRequests = (hbRequestsBySubscriptionKey !== null && hbRequestsBySubscriptionKey !== void 0 ? hbRequestsBySubscriptionKey : {})[heartbeatRequestKey];
notifyRequestProcessing('start', [client], new Date().toISOString(), request);
if (!request) {
consoleLog(`Previous heartbeat request has been sent less than ${client.heartbeatInterval} seconds ago. Skipping...`);
consoleLog(`Previous heartbeat request has been sent less than ${client.heartbeatInterval} seconds ago. Skipping...`, client);
let response;
let body;
// Pulling out previous response.
Expand Down Expand Up @@ -855,30 +855,36 @@
const { channels, channelGroups, response } = hbRequestsBySubscriptionKey[heartbeatRequestKey];
aggregatedState = (_d = client.heartbeat.presenceState) !== null && _d !== void 0 ? _d : {};
aggregated =
includesStrings(channels, client.heartbeat.channels) &&
includesStrings(channelGroups, client.heartbeat.channelGroups);
includesStrings(channels, channelsForAnnouncement) &&
includesStrings(channelGroups, channelGroupsForAnnouncement);
if (response)
failedPreviousRequest = response[0].status >= 400;
}
// Find minimum heartbeat interval which maybe required to use.
let minimumHeartbeatInterval = client.heartbeatInterval;
for (const client of clients) {
if (client.heartbeatInterval)
minimumHeartbeatInterval = Math.min(minimumHeartbeatInterval, client.heartbeatInterval);
}
if (aggregated) {
const expectedTimestamp = hbRequestsBySubscriptionKey[heartbeatRequestKey].timestamp + client.heartbeatInterval * 1000;
const expectedTimestamp = hbRequestsBySubscriptionKey[heartbeatRequestKey].timestamp + minimumHeartbeatInterval * 1000;
const currentTimestamp = Date.now();
// Check whether it is too soon to send request or not (5 is leeway which let send request a bit earlier).
// Request should be sent if previous attempt failed.
if (!failedPreviousRequest && currentTimestamp < expectedTimestamp && expectedTimestamp - currentTimestamp > 5000)
return undefined;
delete hbRequestsBySubscriptionKey[heartbeatRequestKey].response;
// Aggregate channels for similar clients which is pending for heartbeat.
for (const client of clients) {
const { heartbeat } = client;
if (heartbeat === undefined || client.clientIdentifier === event.clientIdentifier)
continue;
// Append presence state from the client (will override previously set value if already set).
if (heartbeat.presenceState)
aggregatedState = Object.assign(Object.assign({}, aggregatedState), heartbeat.presenceState);
channelGroupsForAnnouncement.push(...heartbeat.channelGroups.filter((channel) => !channelGroupsForAnnouncement.includes(channel)));
channelsForAnnouncement.push(...heartbeat.channels.filter((channel) => !channelsForAnnouncement.includes(channel)));
}
}
delete hbRequestsBySubscriptionKey[heartbeatRequestKey].response;
// Aggregate channels for similar clients which is pending for heartbeat.
for (const client of clients) {
const { heartbeat } = client;
if (heartbeat === undefined || client.clientIdentifier === event.clientIdentifier)
continue;
// Append presence state from the client (will override previously set value if already set).
if (heartbeat.presenceState)
aggregatedState = Object.assign(Object.assign({}, aggregatedState), heartbeat.presenceState);
channelGroupsForAnnouncement.push(...heartbeat.channelGroups.filter((channel) => !channelGroupsForAnnouncement.includes(channel)));
channelsForAnnouncement.push(...heartbeat.channels.filter((channel) => !channelsForAnnouncement.includes(channel)));
}
hbRequestsBySubscriptionKey[heartbeatRequestKey].channels = channelsForAnnouncement;
hbRequestsBySubscriptionKey[heartbeatRequestKey].channelGroups = channelGroupsForAnnouncement;
Expand Down Expand Up @@ -1231,6 +1237,7 @@
subscriptionKey: event.subscriptionKey,
userId: event.userId,
heartbeatInterval: event.heartbeatInterval,
newlyRegistered: true,
logVerbosity: event.logVerbosity,
offlineClientsCheckInterval: event.workerOfflineClientsCheckInterval,
unsubscribeOfflineClients: event.workerUnsubscribeOfflineClients,
Expand Down Expand Up @@ -1330,7 +1337,8 @@
subscription.channelGroupQuery = channelGroupQuery;
subscription.channelGroups = channelGroupsFromRequest(event.request);
}
const { authKey, userId } = client;
let { authKey } = client;
const { userId } = client;
subscription.request = event.request;
subscription.filterExpression = ((_j = query['filter-expr']) !== null && _j !== void 0 ? _j : '');
subscription.timetoken = ((_k = query.tt) !== null && _k !== void 0 ? _k : '0');
Expand All @@ -1341,6 +1349,9 @@
client.userId = query.uuid;
client.pnsdk = query.pnsdk;
client.accessToken = event.token;
if (client.newlyRegistered && !authKey && client.authKey)
authKey = client.authKey;
client.newlyRegistered = false;
handleClientIdentityChangeIfRequired(client, userId, authKey);
};
/**
Expand Down
2 changes: 1 addition & 1 deletion dist/web/pubnub.worker.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/core/components/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ const makeConfiguration = (base, setupCryptoModule) => {
return base.PubNubFile;
},
get version() {
return '9.2.0';
return '9.3.0';
},
getVersion() {
return this.version;
Expand Down
19 changes: 13 additions & 6 deletions lib/core/interfaces/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ const FILE_REQUEST_TIMEOUT = 300;
*/
const PRESENCE_TIMEOUT = 300;
/**
* Minimum user presence timeout.
* Maximum user presence timeout.
*/
const PRESENCE_TIMEOUT_MINIMUM = 20;
const PRESENCE_TIMEOUT_MAXIMUM = 320;
/**
* Apply configuration default values.
*
Expand Down Expand Up @@ -134,10 +134,17 @@ const setDefaults = (configuration) => {
publishKey: configurationCopy.publishKey,
secretKey: configurationCopy.secretKey,
};
if (configurationCopy.presenceTimeout !== undefined && configurationCopy.presenceTimeout < PRESENCE_TIMEOUT_MINIMUM) {
configurationCopy.presenceTimeout = PRESENCE_TIMEOUT_MINIMUM;
// eslint-disable-next-line no-console
console.log('WARNING: Presence timeout is less than the minimum. Using minimum value: ', PRESENCE_TIMEOUT_MINIMUM);
if (configurationCopy.presenceTimeout !== undefined) {
if (configurationCopy.presenceTimeout > PRESENCE_TIMEOUT_MAXIMUM) {
configurationCopy.presenceTimeout = PRESENCE_TIMEOUT_MAXIMUM;
// eslint-disable-next-line no-console
console.warn('WARNING: Presence timeout is larger than the maximum. Using maximum value: ', PRESENCE_TIMEOUT_MAXIMUM);
}
else if (configurationCopy.presenceTimeout <= 0) {
// eslint-disable-next-line no-console
console.warn('WARNING: Presence timeout should be larger than zero.');
delete configurationCopy.presenceTimeout;
}
}
if (configurationCopy.presenceTimeout !== undefined)
configurationCopy.heartbeatInterval = configurationCopy.presenceTimeout / 2 - 1;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pubnub",
"version": "9.2.0",
"version": "9.3.0",
"author": "PubNub <support@pubnub.com>",
"description": "Publish & Subscribe Real-time Messaging with PubNub",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/core/components/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export const makeConfiguration = (
return base.PubNubFile;
},
get version(): string {
return '9.2.0';
return '9.3.0';
},
getVersion(): string {
return this.version;
Expand Down
21 changes: 15 additions & 6 deletions src/core/interfaces/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ const FILE_REQUEST_TIMEOUT = 300;
const PRESENCE_TIMEOUT = 300;

/**
* Minimum user presence timeout.
* Maximum user presence timeout.
*/
const PRESENCE_TIMEOUT_MINIMUM = 20;
const PRESENCE_TIMEOUT_MAXIMUM = 320;
// endregion

/**
Expand Down Expand Up @@ -786,10 +786,19 @@ export const setDefaults = (configuration: UserConfiguration): ExtendedConfigura
secretKey: configurationCopy.secretKey,
};

if (configurationCopy.presenceTimeout !== undefined && configurationCopy.presenceTimeout < PRESENCE_TIMEOUT_MINIMUM) {
configurationCopy.presenceTimeout = PRESENCE_TIMEOUT_MINIMUM;
// eslint-disable-next-line no-console
console.log('WARNING: Presence timeout is less than the minimum. Using minimum value: ', PRESENCE_TIMEOUT_MINIMUM);
if (configurationCopy.presenceTimeout !== undefined) {
if (configurationCopy.presenceTimeout > PRESENCE_TIMEOUT_MAXIMUM) {
configurationCopy.presenceTimeout = PRESENCE_TIMEOUT_MAXIMUM;
// eslint-disable-next-line no-console
console.warn(
'WARNING: Presence timeout is larger than the maximum. Using maximum value: ',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great to have log types. 👍🏻

PRESENCE_TIMEOUT_MAXIMUM,
);
} else if (configurationCopy.presenceTimeout <= 0) {
// eslint-disable-next-line no-console
console.warn('WARNING: Presence timeout should be larger than zero.');
delete configurationCopy.presenceTimeout;
}
}

if (configurationCopy.presenceTimeout !== undefined)
Expand Down
Loading
Loading