logo
Video Call
On this page

Real-Time Multi-User Status Synchronization


Feature Introduction

Since version 3.0.0, ZEGO Express SDK has added real-time multi-user status synchronization functionality, providing ordered, high-frequency, low-latency, large-scale status synchronization services to help developers quickly implement real-time information synchronization capabilities for player positions, actions, avatars, etc. in virtual gameplay, while supporting up to 10,000 users online simultaneously in a single scenario.

In large virtual worlds, users generally do not need to perceive distant scenarios or remote users. ZEGO provides AOI (Area Of Interest) capability to eliminate the need to obtain information outside the user's visible range, greatly reducing customer traffic costs, user-side traffic, and performance consumption.

Concept Explanation

  • Scenario: Users need to login to the scenario first. Only users who enter the same scenario can synchronize status information.
  • AOI (Area of Interest) Range: The square size of the user's area of interest, which is generally the user's visible range in virtual scenarios. This range follows the user's position in real-time and only synchronizes remote user information within the AOI range.

Application Scenarios

  • Metaverse scenarios such as virtual offices, virtual exhibitions, virtual social, virtual KTV, etc.
  • General scenarios requiring ultra-high frequency, low latency, large-scale information or control command synchronization.

Prerequisites

Warning

Using this service will incur corresponding fees. Please contact ZEGO business personnel for specific fee information.

Before implementing status synchronization, ensure that:

  • You have contacted ZEGO Technical Support for special packaging and enabled the status synchronization service.
  • You have integrated ZEGO Express SDK into your project.
  • You have created a project in the ZEGOCLOUD Console and applied for a valid AppID and AppSign. For details, please refer to Console - Project Management.

Implementation Flow

1 Create Engine

Call the createEngine interface, passing the obtained AppID and AppSign to the "appID" and "appSign" parameters, to create an engine singleton object. The engine currently only supports creating one instance at a time; exceeding this will return null.

ZegoEngineProfile profile;
/** Please obtain through official website registration, format: 123456789L */
profile.appID = appID;
/** 64 characters, please obtain through official website registration, format: "0123456789012345678901234567890123456789012345678901234567890123" */
profile.appSign = appSign;
/** General scenario access */
profile.scenario = ZegoScenario::ZEGO_SCENARIO_DEFAULT;
/** Create engine and register self as eventHandler callback. If you don't need to register callback, eventHandler parameter can be nil, and you can call "-setEventHandler:" method later to set callback */
engine_ = ZegoExpressSDK::createEngine(profile, nullptr);

2 Create Range Scenario Module

Call the createRangeScene interface to create a range scenario instance. Currently only one instance can be created at a time; exceeding this will return null.

/** Create range scenario */
range_scene_ = engine_->createRangeScene();

3 Listen to Range Scenario Event Callbacks

As needed, call the IZegoRangeScene.setEventHandler interface to set range scenario event callbacks, used to listen to range scenario status, login status, enter/leave AOI notifications, etc. Call the IZegoRangeSceneItem.setEventHandler interface to set range scenario item management class event callbacks, used to listen to item enter/leave AOI range, item binding status change, item status and command update events.

/** Set range scenario event callback */
range_scene_->setEventHandler(rangeSceneCallbackCenter);
range_scene_->getRangeSceneItem()->setEventHandler(rangeSceneCallbackCenter);

4 Login to Scenario

Call the loginScene interface, passing scenario parameters: sceneID, user, position, broadcastMode, to login to the scenario.

Warning
  • Within the same AppID, ensure userID is globally unique. Developers are advised to set it to a meaningful value and can associate userID with their business account system.
  • userID cannot be empty, otherwise login to the scenario will fail.
/** Login to scenario parameters */
ZegoSceneParam param;
/** Create user */
ZegoUser user = ZegoUser(user_id, user_name);
/** Set user's scenario coordinates, motion orientation, camera orientation */
ZegoPosition position;
memset(&position, 0, sizeof(ZegoPosition));
for (int i = 0; i < 3; ++i) {
    position.coordinate[i] = user_coordinate_[i];
    position.motionOrientation.axisForward[i] = user_orientation_forward_[i];
    position.motionOrientation.axisRight[i] = user_orientation_right_[i];
    position.motionOrientation.axisUp[i] = user_orientation_up_[i];
    position.cameraOrientation.axisForward[i] = user_orientation_forward_[i];
    position.cameraOrientation.axisRight[i] = user_orientation_right_[i];
    position.cameraOrientation.axisUp[i] = user_orientation_up_[i];
}
/** Set scenario ID */
param.sceneID = scene_id;
/** (Optional) Configure template ID */
param.templateID = template_id;
param.user = user;
param.position = position;
/** Set user's broadcast mode for logging into the scenario */
param.broadcastMode = ZegoBroadcastModeAll::ZEGO_BROADCAST_MODE_ALL;
range_scene_->loginScene(param, [](int errorCode, const ZegoSceneConfig &config) {
});
Warning

If you need to customize templates, please refer to Server API - Scenario Template Configuration for details.

5 Synchronize Status

Update user status and user commands through the updateUserStatus and updateUserCommand interfaces. Receive status information such as positions and commands of remote users within the AOI range through the onUserStatusUpdate and onUserCommandUpdate callbacks.

Note
  • User status (status, S) is a full update, user commands are incremental updates (command, C), user status can be calculated from a previous user status through a series of user commands.
  • The model for user status updates should be Si->Ci->Ci+1->Ci+2->...Ci+j->S(i+1)->C(i+1)+1->C(i+1)+2->...C(i+1)+k->S(i+2)->C(i+2)->...
  • The status synchronization service will ensure that incremental updates (commands) between two full status updates (Si, Si+1) arrive in order.
/** Set user's scenario coordinates, motion orientation, camera orientation */
ZegoPosition position;
memset(&position, 0, sizeof(ZegoPosition));
for (int i = 0; i < 3; ++i) {
    position.coordinate[i] = user_coordinate_[i];
    position.motionOrientation.axisForward[i] = user_orientation_forward_[i];
    position.motionOrientation.axisRight[i] = user_orientation_right_[i];
    position.motionOrientation.axisUp[i] = user_orientation_up_[i];
    position.cameraOrientation.axisForward[i] = user_orientation_forward_[i];
    position.cameraOrientation.axisRight[i] = user_orientation_right_[i];
    position.cameraOrientation.axisUp[i] = user_orientation_up_[i];
}
/** Update user status */
int status_res = range_scene_->updateUserStatus(position, channel, status, status.length());
/** Update user command */
int command_res = range_scene_->updateUserCommand(position, channel, command, command.length());

6 (Optional) Get User Count in Scenario, Get User List Within AOI Range

As needed, call the getUserCount and getUserListInView interfaces to get the user count in the scenario and the user list within the AOI range.

/** Get user count in scenario */
range_scene_->getUserCount([](int errorCode, unsigned int count) {
});

/** Get user list within AOI range */
range_scene_->getUserListInView([](int errorCode, const std::vector<std::string> &userList) {
});

7 (Optional) Item Status and Competitive Lock

Item status synchronization can implement item movement and placement gameplay in virtual scenarios, such as placement systems, ball kicking, etc. Item locks can implement item grabbing gameplay, such as equipment pickup, musical chairs, etc., which can be set as needed.

  1. Create Item

As needed, call the createItem interface to create items in the scenario.

/** Create item parameters */
ZegoItemParam param;
/** Set item's scenario coordinates, motion orientation */
ZegoPosition position;
memset(&position, 0, sizeof(ZegoPosition));
for (int i = 0; i < 3; ++i) {
    position.coordinate[i] = user_coordinate_[i];
    position.motionOrientation.axisForward[i] = item_orientation_forward_[i];
    position.motionOrientation.axisRight[i] = item_orientation_right_[i];
    position.motionOrientation.axisUp[i] = item_orientation_up_[i];
}
/** Set item ID */
param.itemID = item_id;
/** Set maximum binding user limit for item */
param.capacity = capacity;
param.position = position;
/** Set create item mode */
param.createMode = ZegoCreateItemMode::ZEGO_CREATE_ITEM_MODE_NO_BIND;
range_scene_->getRangeSceneItem()->createItem(param, [](int errorCode, long long itemID) {
});
  1. Bind Item

If you need to operate on an item (i.e., update item status commands), you first need to call bindItem to bind the item.

range_scene_->getRangeSceneItem()->bindItem(item_id, [](int errorCode, long long itemID) {
});
  1. Synchronize Item Status

Update item status and item commands through the updateItemStatus and updateItemCommand interfaces. Receive status information such as positions and commands of remote items within the AOI range through the onItemStatusUpdate and onItemCommandUpdate callbacks.

Note
  • Before updating item status and commands, you need to bind the item first.
  • Item status (status, S) is a full update, item commands are incremental updates (command, C), item status can be calculated from a previous item status through a series of item commands.
  • The model for item status updates should be Si->Ci->Ci+1->Ci+2->...Ci+j->S(i+1)->C(i+1)+1->C(i+1)+2->...C(i+1)+k->S(i+2)->C(i+2)->...
  • The status synchronization service will ensure that incremental updates (commands) between two full status updates (Si, Si+1) arrive in order.
/** Set item's scenario coordinates, motion orientation */
ZegoPosition position;
memset(&position, 0, sizeof(ZegoPosition));
for (int i = 0; i < 3; ++i) {
    position.coordinate[i] = user_coordinate_[i];
    position.motionOrientation.axisForward[i] = item_orientation_forward_[i];
    position.motionOrientation.axisRight[i] = item_orientation_right_[i];
    position.motionOrientation.axisUp[i] = item_orientation_up_[i];
}
/** Update item status */
range_scene_->getRangeSceneItem()->updateItemStatus(item_id, position, channel, status, status.length(),[](int errorCode, long long itemID) {
});

/** Update item command */
range_scene_->getRangeSceneItem()->updateItemCommand(item_id, position, channel, command, command.length(),[](int errorCode, long long itemID) {
});
  1. Unbind Item

If you no longer need to operate on an item (i.e., update item status commands), you can call unbindItem to unbind the item.

range_scene_->getRangeSceneItem()->unbindItem(item_id, [](int errorCode, long long itemID) {
});
  1. Destroy Item

As needed, call destroyItem to destroy items in the scenario.

range_scene_->getRangeSceneItem()->destroyItem(item_id, [](int errorCode, long long itemID) {
});

8 Logout of Scenario

Call the logoutScene interface to logout of the scenario.

/** Logout of scenario */
range_scene_->logoutScene([](int errorCode) {
});

9 Destroy Range Scenario Module

When the range scenario module is no longer needed, you can call the destroyRangeScene interface to destroy the range scenario module.

engine_->destroyRangeScene(range_scene_);
range_scene_ = nullptr;

10 Destroy Engine

When ZEGO Express SDK is no longer needed, you can call destroyEngine to destroy the engine.

ZegoExpressSDK::destroyEngine(engine_);
engine_ = nullptr;

Previous

Mass-Scale Range Audio and Video

Next

Room Connection Status