Skip to main content

You are viewing Agora Docs forBetaproducts and features. Switch to Docs

How to handle token expiration?

After the token expires, you need to call the logout method to log out of the Signaling system. Then use the new token to create a new instance and call the login method to log in to the system again.

How to get the list of users who joined and left the stream channel during disconnection and reconnection?

After listening to the topic event notification, in a weak network environment, if you disconnect and reconnect, you will receive a SNAPSHOT event in topic.

To obtain the list of users who joined or left the stream channel during disconnection and reconnection, refer to the following sample code to generate a local cache and compare it with the user list in the SNAPSHOT event:

  • Users with more SNAPSHOT events than in the local cache are those who joined the channel during the disconnection and reconnection period.
  • Users with fewer SNAPSHOT events than in the local cache are those who left the channel during the disconnection and reconnection period.

_63
// Global variable
_63
const channelTopics = new Map();
_63
_63
// Event handler
_63
const rtmConfig = {};
_63
const rtm = new RTM("appid", "uid", rtmConfig);
_63
rtm.addEventListener("topic", (topicEvent) => {
_63
console.log(topicEvent, "topic");
_63
_63
const topicsCache = channelTopics.get(topicEvent.channelName) ?? new Map();
_63
const remoteLeaved = new Map();
_63
const remoteJoined = new Map();
_63
const { publisher: user, channelName } = topicEvent;
_63
_63
if (topicEvent.eventType === "SNAPSHOT") {
_63
topicEvent.topicInfos.forEach(({ publishers, topicName }) => {
_63
remoteJoined.set(topicName, []);
_63
remoteLeaved.set(topicName, []);
_63
const topicDetailsByCache = topicsCache.get(topicName) ?? [];
_63
_63
// Removed
_63
topicDetailsByCache.forEach(({ publisherMeta, publisherUserId: targetUid }) => {
_63
if (!publishers.some(({ publisherUserId: eventUid }) => targetUid === eventUid)) {
_63
remoteLeaved.get(topicName)?.push({ publisherUserId: targetUid, publisherMeta });
_63
topicDetailsByCache.filter(({ publisherUserId: cacheUid }) => cacheUid !== targetUid);
_63
}
_63
});
_63
_63
// Added
_63
publishers.forEach(({ publisherMeta, publisherUserId: eventUid }) => {
_63
if (!topicDetailsByCache.some(({ publisherUserId: cacheUid }) => eventUid === cacheUid)) {
_63
remoteJoined.get(topicName)?.push({ publisherUserId: eventUid, publisherMeta });
_63
topicDetailsByCache.push({ publisherUserId: eventUid, publisherMeta });
_63
}
_63
});
_63
_63
topicsCache.set(topicName, topicDetailsByCache);
_63
});
_63
} else {
_63
// Your code for handling the updated event
_63
topicEvent.topicInfos.forEach(({ topicName, publishers }) => {
_63
const topicDetailsByCache = topicsCache.get(topicName) ?? [];
_63
publishers.forEach(({ publisherMeta, publisherUserId }) => {
_63
if (user === publisherUserId) {
_63
switch (topicEvent.eventType) {
_63
case "REMOTE_JOIN": {
_63
topicDetailsByCache.push({ publisherMeta, publisherUserId });
_63
break;
_63
}
_63
case "REMOTE_LEAVE": {
_63
topicDetailsByCache.filter(({ publisherUserId: uid }) => uid !== publisherUserId);
_63
break;
_63
}
_63
}
_63
topicsCache.set(topicName, topicDetailsByCache);
_63
}
_63
});
_63
});
_63
}
_63
_63
channelTopics.set(channelName, topicsCache);
_63
console.log({ remoteJoined, remoteLeaved, channelTopics, channelName }, "topic diff for debug");
_63
});

vundefined