Manage rooms
ZEGOCLOUD's In-app Chat (the ZIM SDK) provides the capability of room messaging, allows multiple users to send text or custom messages to a room, and chat and share ideas in real time.
With the room messaging feature, you can build your app to meet different requirements of various scenarios, such as one-to-many classes, online conferences, and more.
Join a room
Now, we provide two methods to join a room:
For in-room users to send messages to a room, call the sendRoomMessage method. For details, see Send & Receive messages.
If the room (roomID) already exists:
If the room (roomID) doesn't exist:
- Call the createRoom method: you can create a room, and you will join the room upon creation.
- Call the enterRoom method: a room will be created automatically, and you will join the room directly.
Method 1: Manually create a room & Join a room
Manually create a room
Let's suppose we have Client A and Client B. The following shows how Client A creates a room, how Client B and other client users join the room.
For Client A to create a room after login, he can call the createRoom method with the ZIMRoomInfo info. And he can be told whether the room is created successfully by the ZIMError
parameter. For related error codes, see Error codes.
- You can customize the roomID and roomName, and we recommend you set the roomID to a meaningful value and associate them with the account system of your application.
- After creating a room by calling the createRoom method, you will directly join the room you just created, you don't need to call the joinRoom method to join the room.
ZIMRoomInfo zimRoomInfo = new ZIMRoomInfo();
zimRoomInfo.roomID = roomID;
zimRoomInfo.roomName = roomName;
zim.createRoom(zimRoomInfo, new ZIMRoomCreatedCallback() {
@Override
public void onRoomCreated(ZIMRoomFullInfo zimRoomFullInfo, ZIMError error) {
if (error.code == ZIMErrorCode.SUCCESS) {
// Room created successfully.
} else {
// Failed to create a room.
}
}
});
1
// Set the room configurations.
ZIMRoomInfo roomInfo = ZIMRoomInfo();
roomInfo.roomID = 'roomID';
roomInfo.roomName = 'roomName';
//Creates a room.
ZIM
.getInstance()
.createRoom(roomInfo)
.then((value) {
//This will be triggered when room created successfully.
})
.catchError((onError) {
//This will be triggered when room creation failed.
});
1
// Set the room configurations.
ZIMRoomInfo *roomInfo = [[ZIMRoomInfo alloc]init];
roomInfo.roomID = @"" ;
roomInfo.roomName = @"" ;
//Creates a room.
[zim createRoom:roomInfo callback:^(ZIMRoomFullInfo * _Nonnull roomInfo, ZIMError * _Nonnull errorInfo) {
//Implement the event callback for creating a room here.
}];
1
// Set the room configurations.
ZIMRoomInfo *roomInfo = [[ZIMRoomInfo alloc]init];
roomInfo.roomID = @"" ;
roomInfo.roomName = @"" ;
//Creates a room.
[zim createRoom:roomInfo callback:^(ZIMRoomFullInfo * _Nonnull roomInfo, ZIMError * _Nonnull errorInfo) {
//Implement the event callback for creating a room here.
}];
1
ZIMRoomInfo room_info;
room_info.roomID = room_id;
room_info.roomName = room_name;
zim_->createRoom(room_info, [=](ZIMRoomFullInfo room_info, zim::ZIMError error_info) {
global_main_dialog_->PostUiThread([=] {});
if (error_info.code != 0)
{
ShowMsg(L"Create room failed, roomID: %s, error code: %d", room_info.baseInfo.roomID, error_info.code);
}
else
{
ShowMsg(L"Create room successfully, roomID: %s", room_info.baseInfo.roomID);
}
});
1
var roomInfo = { roomID: '', roomName: '' };
zim.createRoom(roomInfo)
.then(function ({ roomInfo }) {
// Operation successful.
})
.catch(function (err) {
// Operation failed.
});
1
Join a room
For Client B and other client users to join the room created by Client A, call the joinRoom method with the roomID of client A's room. And Client B and other client users can be told whether they joined the room successfully by the ZIMError
parameter. For related error codes, see Error codes.
zim.joinRoom(roomID, new ZIMRoomJoinedCallback() {
@Override
public void onRoomJoined(ZIMRoomFullInfo zimRoomFullInfo, ZIMError error) {
if (error.code == ZIMErrorCode.SUCCESS) {
// Room joined successfully.
} else {
// Failed to join the room.
}
}
});
1
ZIM
.getInstance()
.joinRoom('roomID')
.then((value) {
//This will be triggered when room joined successfully.
})
.catchError((onError) {
//This will be triggered when failed to join room.
});
1
[zim joinRoom:RoomID callback:^(ZIMRoomFullInfo * _Nonnull roomInfo, ZIMError * _Nonnull errorInfo) {
//Implement the event callback for joining a room here.
}];
1
[zim joinRoom:RoomID callback:^(ZIMRoomFullInfo * _Nonnull roomInfo, ZIMError * _Nonnull errorInfo) {
//Implement the event callback for joining a room here.
}];
1
zim_->joinRoom(roomId, [=](ZIMRoomFullInfo room_info, zim::ZIMError error_info) {
global_main_dialog_->PostUiThread([=] {});
if (error_info.code != 0)
{
ShowMsg(L"Join room failed, roomID: %s, error code: %d", room_info.baseInfo.roomID, error_info.code);
}
else
{
ShowMsg(L"Join room successfully, roomIDID: %s, roomName: %s", room_info.baseInfo.roomID, room_info.baseInfo.roomName);
}
});
1
var roomID = '';
zim.joinRoom(roomID)
.then(function ({ roomInfo }) {
// Operation successful.
})
.catch(function (err) {
// Operation failed.
});
1
To receive notifications when a new room member joins the room, call the setEventHandler method to set up the callback roomMemberJoined.
The following shows Client A receives the callback notification when Client B joins the room created by Client A:
zim.setEventHandler(new ZIMEventHandler() {
@Override
public void onRoomMemberJoined(ZIM zim, ArrayList<ZIMUserInfo> memberList, final String roomID) {
// Implement the event callback for new room members join the room.
}
});
1
ZIMEventHandler.onRoomMemberJoined = (memberList, roomID) {
//Implement the event callback for new room members join the room.
};
1
- (void)zim:(ZIM *)zim
roomMemberJoined:(NSArray<ZIMUserInfo *> *)memberList
roomID:(NSString *)roomID{
//Implement the event callback for new room members join the room.
}
1
- (void)zim:(ZIM *)zim
roomMemberJoined:(NSArray<ZIMUserInfo *> *)memberList
roomID:(NSString *)roomID{
//Implement the event callback for new room members join the room.
}
1
void onRoomMemberJoined(ZIM* zim, const std::vector<ZIMUserInfo>& member_list, const std::string& room_id)
{
for (auto member : member_list)
{
ShowMsg(L"User: (%s%s), enter the room: %s", member.userID, member.userName, room_id);
}
}
1
// Callback for receiving event notification when new room members join the room. And it also returns the information of the user who just joined the room.
zim.on('roomMemberJoined', function (zim, { roomID, memberList }) {
console.log(roomID, memberList);
});
1
Method 2: Join a room directly (room will be created automatically)
Let's suppose we have Client A and Client B. The following shows how Client A joins the room without creating a room manually, and how Client B and other client users join the room.
-
After logs in, Client A calls the enterRoom method with the ZIMRoomInfo information. The room will be created automatically when the passed roomID doesn't exist.
-
Client B and other client users call the enterRoom method with the roomID to join the room created by Client A.
-
For in-room client users to receive notifications when a new room member joins the room, call the setEventHandler method to set up the callback roomMemberJoined.
ZIMRoomInfo zimRoomInfo = new ZIMRoomInfo();
zimRoomInfo.roomID = roomID;
zimRoomInfo.roomName = roomName;
ZIMRoomAdvancedConfig config = new ZIMRoomAdvancedConfig();
zim.enterRoom(zimRoomInfo, config, new ZIMRoomEnteredCallback() {
@Override
public void onRoomEntered(ZIMRoomFullInfo zimRoomFullInfo, ZIMError error) {
if (error.code == ZIMErrorCode.SUCCESS) {
// Room joined successfully.
} else {
// Failed to join the room.
}
}
});
1
// Set up the configuration of a room.
ZIMRoomInfo roomInfo = ZIMRoomInfo();
roomInfo.roomID = 'roomID';
roomInfo.roomName = 'roomName';
ZIMRoomAdvancedConfig advancedConfig = ZIMRoomAdvancedConfig();
//Join a room directly.
ZIM.getInstance().enterRoom(roomInfo, advancedConfig).then((value) {
// enter This will be triggered when operation successful.
}).catchError((onError){
// enter This will be triggered when operation failed.
});
1
// Set up the configuration of a room.
ZIMRoomInfo *roomInfo = [[ZIMRoomInfo alloc]init];
roomInfo.roomID = @"" ;
roomInfo.roomName = @"" ;
ZIMRoomAdvancedConfig *config = [[ZIMRoomAdvancedConfig alloc] init];
//Join a room directly.
[zim enterRoom:roomInfo config:config callback:^(ZIMRoomFullInfo * _Nonnull roomInfo, ZIMError * _Nonnull errorInfo) {
//Implement the event callback for join a room.
}];
1
// Set up the configuration of a room.
ZIMRoomInfo *roomInfo = [[ZIMRoomInfo alloc]init];
roomInfo.roomID = @"" ;
roomInfo.roomName = @"" ;
ZIMRoomAdvancedConfig *config = [[ZIMRoomAdvancedConfig alloc] init];
//Join a room directly.
[zim enterRoom:roomInfo config:config callback:^(ZIMRoomFullInfo * _Nonnull roomInfo, ZIMError * _Nonnull errorInfo) {
//Implement the event callback for join a room.
}];
1
ZIMRoomInfo room_info;
room_info.roomID = room_id;
room_info.roomName = room_name;
ZIMRoomAdvancedConfig config;
zim_->enterRoom(room_info, config, [=](ZIMRoomFullInfo room_info, zim::ZIMError error_info) {
global_main_dialog_->PostUiThread([=] {});
if (error_info.code != 0)
{
ShowMsg(L"Failed to join room. roomID: %s, Error code: %d", room_info.baseInfo.roomID, error_info.code);
}
else
{
ShowMsg(L"Room joined successfully. roomID: %s", room_info.baseInfo.roomID);
}
});
1
var roomInfo = { roomID: '', roomName: '' };
zim.enterRoom(roomInfo)
.then(function ({ roomInfo }) {
// Operation successful.
})
.catch(function (err) {
// Operation failed.
});
// Callback for receiving event notification when new room members join the room. And it also returns the information of the user who just joined the room.
zim.on('roomMemberJoined', function (zim, { roomID, memberList }) {
console.log(roomID, memberList);
});
1
Switch Rooms
If a user wants to switch from one room to another, the user can call the switchRoomFromRoomID method, passing in the ID of the original room (fromRoomID
) and the information of the target room (toRoomInfo
), which includes the room ID and room name. This will allow the user to switch rooms.
However, it is possible for the room switch to fail if the target room does not exist. To avoid this failure, you can also pass isCreateWhenRoomNotExisted
as true
(allowing ZIM to create a new room if the target room does not exist) and config (used to configure the new room) when calling the switchRoomFromRoomID method. In this case, when ZIM finds that the target room does not exist, it will create a new room based on toRoomInfo
and config
(if provided) for the switch.
After a successful room switch, other users in the original room can be notified of a user leaving the room through the roomMemberJoined callback, and other users in the target room can be notified of a user joining the room through the callback interface roomMemberLeft.
String fromRoomID = "fromRoomID";
ZIMRoomInfo toRoomInfo = new ZIMRoomInfo();
roomInfo.roomID = "toRoomID";
roomInfo.roomName = "toRoomName";
// Whether to create a room if it does not exist.
// Only when this is true and the target room does not exist, the toRoomName and config in toRoomInfo are meaningful
boolean isCreateWhenRoomNotExisted = true;
// Advanced configuration for creating a room
ZIMRoomAdvancedConfig config = new ZIMRoomAdvancedConfig();
config.roomAttributes.put("key1", "value1");
config.roomDestroyDelayTime = 90;
// Switch rooms
zim.switchRoom(fromRoomID, toRoomInfo, isCreateWhenRoomNotExisted, config, new ZIMRoomSwitchedCallback() {
@Override
public void onRoomSwitched(ZIMRoomFullInfo roomInfo, ZIMError errorInfo) {
if (errorInfo.code == ZIMErrorCode.SUCCESS) {
// Room switch successful, you can obtain information about the switched room from roomInfo
}
}
});
1
NSString *fromRoomID = @"fromRoomID";
ZIMRoomInfo *toRoomInfo = [[ZIMRoomInfo alloc] init];
toRoomInfo.roomID = @"toRoomID";
toRoomInfo.roomName = @"toRoomName";
// Whether to create a room if it does not exist.
// Only when this is true and the target room does not exist, the toRoomName and config in toRoomInfo are meaningful
BOOL isCreateWhenRoomNotExisted = YES;
// Advanced configuration for creating a room
ZIMRoomAdvancedConfig *config = [[ZIMRoomAdvancedConfig alloc] init];
[config insertRoomAttribute:@"key1" value:@"value1"];
config.roomDestroyDelayTime = 90;
// Switch rooms
[zim switchRoomFromRoomID:fromRoomID
toRoomInfo:toRoomInfo
isCreateWhenRoomNotExisted:isCreateWhenRoomNotExisted
config:config
callback:^(ZIMRoomFullInfo *_Nonnull roomInfo, ZIMError *_Nonnull errorInfo) {
if (errorInfo.code == 0) {
// Room switch successful, you can obtain information about the switched room from roomInfo
}
}];
1
NSString *fromRoomID = @"fromRoomID";
ZIMRoomInfo *toRoomInfo = [[ZIMRoomInfo alloc] init];
toRoomInfo.roomID = @"toRoomID";
toRoomInfo.roomName = @"toRoomName";
// Whether to create a room if it does not exist.
// Only when this is true and the target room does not exist, the toRoomName and config in toRoomInfo are meaningful
BOOL isCreateWhenRoomNotExisted = YES;
// Advanced configuration for creating a room
ZIMRoomAdvancedConfig *config = [[ZIMRoomAdvancedConfig alloc] init];
[config insertRoomAttribute:@"key1" value:@"value1"];
config.roomDestroyDelayTime = 90;
// Switch rooms
[zim switchRoomFromRoomID:fromRoomID
toRoomInfo:toRoomInfo
isCreateWhenRoomNotExisted:isCreateWhenRoomNotExisted
config:config
callback:^(ZIMRoomFullInfo *_Nonnull roomInfo, ZIMError *_Nonnull errorInfo) {
if (errorInfo.code == 0) {
// Room switch successful, you can obtain information about the switched room from roomInfo
}
}];
1
std::string fromRoomID = "fromRoomID";
auto toRoomInfo = zim::ZIMRoomInfo("toRoomID", "toRoomName");
// Whether to create a room if it does not exist.
// Only when this is true and the target room does not exist, the toRoomName and config in toRoomInfo are meaningful
bool isCreateWhenRoomNotExisted = true;
// Advanced configuration for creating a room
auto config = zim::ZIMRoomAdvancedConfig();
config.roomAttributes.emplace("key1", "value1");
config.roomDestroyDelayTime = 90;
// Switch rooms
zim->switchRoom(
fromRoomID, toRoomInfo, isCreateWhenRoomNotExisted, config,
[=](const zim::ZIMRoomFullInfo &roomInfo, const zim::ZIMError &errorInfo) {
if (errorInfo.code == zim::ZIMErrorCode::ZIM_ERROR_CODE_SUCCESS) {
// Room switch successful, you can obtain information about the switched room from roomInfo
}
});
1
const fromRoomID = 'fromRoomID';
const toRoomInfo = { roomID: 'toRoomID', roomName: 'toRoomName' };
// Whether to create a room if it does not exist.
// Only when this is true and the target room does not exist, the toRoomName and config in toRoomInfo are meaningful
const isCreateWhenRoomNotExisted = true;
// Advanced configuration for creating a room
const to_room_attr = {
key1: 'value1', // Replace this code to the actual key-value pair
key2: 'value2', // Another key-value pair
// You can add more pairs
};
// Set room destruction delay time (in seconds)
const to_room_delay_destroy_time = 90;
const config = {
roomAttributes: to_room_attr,
roomDestroyDelayTime: to_room_delay_destroy_time,
};
zim.switchRoom(fromRoomID, toRoomInfo, isCreateWhenRoomNotExisted, config)
.then(function (res) {
// Operation successful
})
.catch(function (err) {
// Operation failed
});
1
String fromRoomID = 'fromRoomID';
ZIMRoomInfo toRoomInfo = ZIMRoomInfo();
toRoomInfo.roomID = 'toRoomID';
toRoomInfo.roomName = 'toRoomName';
// Whether to create a room if it does not exist.
// Only when this is true and the target room does not exist, the toRoomName and config in toRoomInfo are meaningful
bool isCreateWhenRoomNotExisted = true;
// Advanced configuration for creating a room
ZIMRoomAdvancedConfig config = ZIMRoomAdvancedConfig();
config.roomAttributes['key1'] = 'value1';
config.roomDestroyDelayTime = 90;
try{
ZIMRoomSwitchedResult? result = await ZIM.getInstance()?.switchRoom(fromRoomID, toRoomInfo, isCreateWhenRoomNotExisted, config);
// Operation successful
} on PlatformException catch (onError){
onError.code; // Return code for switch failure
onError.message; // Error message
}
1
Leave the room
For Client B to leave the room, call the leaveRoom method with roomID
.
And Client A and other client users in the room will receive notifications through the callback roomMemberLeft of the setEventHandler method.
Room members who leave the room cannot receive messages in the room anymore.
zim.leaveRoom(roomID, new ZIMRoomLeftCallback() {
@Override
public void onRoomLeft(String roomID, ZIMError errorInfo) {
}
});
1
zim.setEventHandler(new ZIMEventHandler() {
@Override
public void onRoomMemberLeft(ZIM zim, ArrayList<ZIMUserInfo> memberList, final String roomID) {
// Implement the event callback for exisiting users leave the room.
}
});
1
ZIM
.getInstance()
.leaveRoom('roomID')
.then((value) {
//This will be triggered when leave a room successfully.
})
.catchError((onError) {
//This will be triggered when failed to leave a room.
});
1
ZIMEventHandler.onRoomMemberLeft = (memberList, roomID) {
//Fill in your custom code here when room members leave.
};
1
[zim leaveRoom:roomID callback:^(ZIMError * _Nonnull errorInfo) {
//Implement the event callback for exisiting users leave the room.
}];
1
- (void)zim:(ZIM *)zim
roomMemberLeft:(NSArray<ZIMUserInfo *> *)memberList
roomID:(NSString *)roomID{
//Fill in your custom code here when room members leave.
}
1
[zim leaveRoom:roomID callback:^(ZIMError * _Nonnull errorInfo) {
//Implement the event callback for exisiting users leave the room.
}];
1
- (void)zim:(ZIM *)zim
roomMemberLeft:(NSArray<ZIMUserInfo *> *)memberList
roomID:(NSString *)roomID{
//Fill in your custom code here when room members leave.
}
1
zim_->leaveRoom(room_id, [=](zim::ZIMError error_info) {
global_main_dialog_->PostUiThread([=] {
ShowMsg(L"Logout result:%d", error_info.code);
});
});
1
void onRoomMemberLeft(ZIM* zim, const std::vector<ZIMUserInfo>& member_list, const std::string& room_id)
{
for (auto member : member_list)
{
ShowMsg(L"User: (%s,%s), logout the room: %s", member.userID, member.userName, room_id);
}
}
1
var roomID = '';
zim.leaveRoom(roomID)
.then(function ({ roomID }) {
// Operation successful.
})
.catch(function (err) {
// Operation failed.
});
1
// Callback for receiving event notification when existing room members leave the room. And it also returns the information of the user who just left the room.
zim.on('roomMemberLeft', function (zim, { roomID, memberList }) {
console.log(roomID, memberList);
});
1
The room will be automatically destroyed after all room members left the room. You can also delay the destruction with the room settings.
Leave all rooms
Call the leaveAllRoom method to leave all joined rooms and obtain a list of the rooms. If a user logs in to multiple platforms, calling this method on a platform lets the user leave rooms on the that platform only. Other platforms are not affected.
ZIM.getInstance().leaveAllRoom(new ZIMRoomAllLeftCallback() {
@Override
public void onRoomAllLeft(ArrayList<String> roomIDList, ZIMError errorInfo) {
if(errorInfo.code == ZIMErrorCode.SUCCESS){
// `roomIDList` contains the IDs of all rooms that the user have left from.
}else{
// Handle the error based on the corresponding error code table.
}
}];
1
try{
ZIMRoomAllLeftResult result = await ZIM.getInstance()!.leaveAllRoom();
result.roomIDs; // List of rooms left
} on PlatformException catch (onError) {
onError.code;
onError.message;
}
1
[[ZIM getInstance] leaveAllRoom:^(NSArray<NSString *> * _Nonnull roomIDList, ZIMError * _Nonnull errorinfo) {
if(errorinfo.code == ZIMErrorCodeSuccess){
// `roomIDList` contains the IDs of all rooms that the user have left from.
}else{
// Handle the error based on the corresponding error code table.
}
}];
1
[[ZIM getInstance] leaveAllRoom:^(NSArray<NSString *> * _Nonnull roomIDList, ZIMError * _Nonnull errorinfo) {
if(errorinfo.code == ZIMErrorCodeSuccess){
// `roomIDList` contains the IDs of all rooms that the user have left from.
}else{
// Handle the error based on the corresponding error code table.
}
}];
1
zim->leaveAllRoom([](const std::vector<std::string>& roomIDList, const ZIMError& errorInfo) {
if (errorInfo.errorCode == 0) {
// `roomIDList` contains the IDs of all rooms that the user have left from.
}else{
// Handle the error based on the corresponding error code table.
}
}];
1
var roomIDs = [];
zim.leaveAllRoom(roomIDs)
.then(function ({ roomIDs }) {
// Operation successful.
})
.catch(function (err) {
// Operation failed.
});
1
Other users in the room receive the member change notification in the setEventHandler callback of the roomMemberLeft method.
After leaving all rooms, the user receives the roomStateChanged callback multiple times based on the number of rooms. The value of ZIMRoomState is ZIMRoomStateDisconnected , and the value of ZIMRoomEvent is ZIMRoomEventSuccess .
After leaving a room, the user no longer receives messages in the room.