ZIM SDK supports the configuration of custom multi-device logins, which means that users can log in to multiple devices simultaneously with the same account, ensuring that the user's sessions, messages, groups and other data communicate with each other.
Multi-device login supports configuration on eight devices including Windows, Mac, Linux, Android, iOS, iPad, Web, and Mini Program. Among them, multi-device login is supported on Windows, Mac, Linux, Android, iOS, and iPad devices, with a maximum of 2 devices. Multi-instance login is supported on the Web device, with a maximum of 5 login instances.
The following are the three login policies supported by the ZIM SDK: single-device login, dual-device login, and multi-device login.
Login policies | Specific explanation |
---|---|
Single device login (default) |
Only supports users logging into the account on one device at a time. If the account is logged into another device, the account on the original device will be logged out. |
Dual-device login |
Allows users to log in to their accounts on any of the Windows, Mac, Linux, Android, iOS, and iPad devices while keeping their accounts online on the web device. |
Multi-device login |
Allows users to simultaneously log in to their accounts on multiple devices, including Windows, Mac, Linux, Android, iOS, iPad, Web, and Mini program. The following configurations are supported:
|
Before implementing the "multi-device login" function, please make sure:
Contact ZEGOCLOUD technical support team to activate the multi-terminal login service. After configuring the multi-device login, you can call login
on multiple devices to log in to the ZIM SDK. The implementation process is the same as a single-terminal login. For details on how to log in, please refer to the "Logging in ZIM" section in Send and receive messages.
When the number of login devices reaches the limit set by the policy, if you log in to the account on a new device, the account that was logged in the earliest on the original device will be kicked offline. You will be notified of this through the connectionStateChanged
callback with the event set to KickedOut
. For example, if the login specifies a maximum of 3 devices to be logged in, and the account has already been logged in on devices A, B, and C (in chronological order), logging in to the account on device D will kick the account on device A offline.
When the account is kicked offline, it is recommended to call the logout
interface to log out of the ZIM service and switch the user interface to the login interface.
The codes for the following functions must also be changed after configuring multi-device login.
ZIM SDK provides user information synchronization function for multi-device login users.After a user updates his or her information through updateUserName
, updateUserAvatarUrl
, updateUserExtendedData
interfaces on one device, other online clients can register the userInfoUpdated event to listen for user information being modified.
zim.on('userInfoUpdated', (zim, { info }) => {
console.log(info.baseInfo.userName, info.userAvatarUrl, info.extendedData);
});
When the user deletes the server conversation on one device through the deleteConversation
interface(that is, isAlsoDeleteServerConversation
set to true), other online clients can registerconversationChanged
event to listen for the deletion of the conversation.
zim.on('conversationChanged', (zim, { infoList }) => {
infoList.forEach((info) => {
if (info.event == 3) {
//The conversation is deleted
}
});
});
When the user deletes all server conversations on one device through the deleteAllConversations
interface(that is, isAlsoDeleteServerConversation
set to true), other clients can use conversationsAllDeleted
event to listen for the deletion of the.
zim.on('conversationsAllDeleted', (zim, { count }) => {
console.log('Number of deleted conversations', count);
});
When the user clears all unread conversations on one device through clearConversationTotalUnreadMessageCount
. Other clients can listen for the notification of all conversations having their unread message count cleared through the conversationTotalUnreadMessageCountUpdated
event.
zim.on('conversationTotalUnreadMessageCountUpdated', (zim, { totalUnreadMessageCount }) => {
//After clearing all unread messages in all conversations on other devices, the value of `totalUnreadMessageCount` in the current device will be 0
});
When a user logs in to a new device, the SDK does not automatically synchronize the existing messages from the old device to the new device. Users need to actively call the queryHistoryMessage
interface to retrieve the messages stored on the ZIM server. For more details, please refer to Get message history. As for the local messages stored on the old device, they cannot be retrieved.
When a user deletes server messages in a conversation through the deleteMessages
, deleteAllMessage
with (that is isAlsoDeleteServerMessage
set to true), other online clients can listen for the messageDeleted
to be notified of the deleted messages.
zim.on('messageDeleted', (zim, { conversationID, conversationType, isDeleteConversationAllMessage, messageList }) => {
if (isDeleteConversationAllMessage) {
// All current messages in the conversation are deleted
} else if (messageList.length > 0) {
// The specified message in the conversation is deleted
}
});
When a user sets a message receipt as read through the sendMessageReceiptsRead
, sendConversationMessageReceiptRead
interface on one device, other online clients can listen for the messageReceiptChanged
and conversationMessageReceiptChanged
event to be notified that the account has set the message receipt as read.
zim.on('messageReceiptChanged', (zim, { infos }) => {
infos.forEach((info) => {
if (info.isSelfOperated) {
// Message receipt set as read by the user
}
});
});
zim.on('conversationMessageReceiptChanged', (zim, { infos }) => {
infos.forEach((info) => {
if (info.isSelfOperated) {
// Conversation receipt set as read by the user
}
});
});
The room module's related interfaces and events do not support multi-device login. When a user joins a room on device A, and then joins the same room on device B, device A will be kicked out of the room. Device A will receive the event
as KickedOutByOtherDevice
through the roomStateChanged
.
// When a user joins a room on device A, and then joins the same room on device B, device A will be kicked out of the room
zim.on('roomStateChanged', (zim, { roomID, state, event }) => {
if (state == 0 && event == 10) {
// Kicked out of the room due to multi-device login
}
});
After enabling the multi-device login service, ZIM SDK will automatically synchronize group-related data between multiple devices.
When the user is logged in on both device A and device B, and receives a call invitation, if the user accepts the invitation on device A(calling callAccept
)or after rejecting the invitation(calling callReject
) :
ZIMCallAcceptanceSentResult
or ZIMCallRejectionSentResult
), and close the invitation popup window to perform other business operations.callUserStateChanged
callback to know the call user state of the current user(ZIMCallUserState
)as Accepted
or Rejected
,and close the invitation popup window to perform other business operations.Each device can receive the user state change event callUserStateChanged
in the call, as shown in the following table:
callUserState | Device A | Device B |
---|---|---|
Inviting | ✔️ | ✔️ |
Received | ✔️ | ✔️ |
Accepted | ✔️ | ✔️ |
Rejected | ✔️ | ✔️ |
Timeout | ✖ | ✖ |
Cancelled | ✖ | ✖ |
Quit | ✔️ | ✖ |
var selfUserID = '';
var curCallID = '';
// Device A accepts the invitation
zim.callAccept(curCallID, { extendedData: 'Device A accepts the invitation' }).then((res) => {
// Close the popup box for call waiting operation. Start stream publishing and playing, proceed with audio and video call.
});
// Device A rejects the invitation
zim.callReject(curCallID, { extendedData: 'Device A rejects the invitation' }).then((res) => {
// Close the popup box for call waiting operation. Call ends.
});
// Device B listens for callUserStateChanged
zim.on('callUserStateChanged', (zim, { callID, callUserList }) => {
if (curCallID == callID) {
callUserList.forEach((item) => {
if (item.userID == selfUserID && (item.state == 1 || item.state == 2)) {
// When Device A has accepted or rejected, close the popup box for call waiting operation.
}
});
}
});