频道消息管理
功能简介
社群(Community)是 ZIM 提供的类 Discord 实时互动社区能力,采用"社群 - 频道"的两层组织结构。频道是社群内聊天互动的基本载体,功能类似传统群组,支持发送文本、图片、语音、视频等各类消息。
本文介绍如何在社群频道中收发消息。频道消息的发送与接收基于 ZIM 标准消息接口,统一使用 ZIMConversationType.COMMUNITY_CHANNEL 作为会话类型。
前提条件
- 请参考 实现基本消息收发 完成 ZIM SDK 获取、初始化和用户登录。
- 请参考 使用 Token 鉴权 实现用户鉴权登录。
- 社群功能需要 ZIM SDK 3.0.0 及以上版本。
- 社群功能为旗舰版功能,使用前请联系 ZEGO 技术支持开通。
- 社群功能的 Token 生成方式与其他 ZIM 功能一致,无需额外权限声明。
- 发送频道消息前,需要先让用户加入(或创建)一个社群,并获取目标频道的
conversationID。
- 支持的消息类型与群组一致,包括文本、富媒体、自定义、组合等,详见 收发消息 - 消息类型。
步骤一:创建或加入社群
创建社群
调用 createCommunity 接口创建社群。创建成功后,系统会自动为该社群创建一个类型为 GENERAL 的默认频道。
import im.zego.zim.ZIM;
import im.zego.zim.entity.ZIMCommunityCreateConfig;
import im.zego.zim.entity.ZIMCommunityFullInfo;
import im.zego.zim.entity.ZIMCommunityInfo;
import im.zego.zim.entity.ZIMError;
import im.zego.zim.enums.ZIMErrorCode;
// 构造社群基本信息
ZIMCommunityInfo communityInfo = new ZIMCommunityInfo();
communityInfo.setCommunityID("community_001"); // 社群 ID,由开发者自定义
communityInfo.setCommunityName("我的社群");
communityInfo.setCommunityAvatarUrl("https://example.com/avatar.png");
ZIMCommunityCreateConfig config = new ZIMCommunityCreateConfig();
// 可选:设置社群公告
config.setCommunityNotice("欢迎加入!");
zim.createCommunity(communityInfo, config, (ZIMCommunityFullInfo fullInfo, ZIMError error) -> {
if (error.code == ZIMErrorCode.SUCCESS) {
// 创建成功,fullInfo 包含完整社群信息
}
});import im.zego.zim.ZIM;
import im.zego.zim.entity.ZIMCommunityCreateConfig;
import im.zego.zim.entity.ZIMCommunityFullInfo;
import im.zego.zim.entity.ZIMCommunityInfo;
import im.zego.zim.entity.ZIMError;
import im.zego.zim.enums.ZIMErrorCode;
// 构造社群基本信息
ZIMCommunityInfo communityInfo = new ZIMCommunityInfo();
communityInfo.setCommunityID("community_001"); // 社群 ID,由开发者自定义
communityInfo.setCommunityName("我的社群");
communityInfo.setCommunityAvatarUrl("https://example.com/avatar.png");
ZIMCommunityCreateConfig config = new ZIMCommunityCreateConfig();
// 可选:设置社群公告
config.setCommunityNotice("欢迎加入!");
zim.createCommunity(communityInfo, config, (ZIMCommunityFullInfo fullInfo, ZIMError error) -> {
if (error.code == ZIMErrorCode.SUCCESS) {
// 创建成功,fullInfo 包含完整社群信息
}
});示例代码
ZIMCommunityInfo *communityInfo = [[ZIMCommunityInfo alloc] init];
communityInfo.communityID = @"community_001";
communityInfo.communityName = @"我的社群";
communityInfo.communityAvatarUrl = @"https://example.com/avatar.png";
ZIMCommunityCreateConfig *config = [[ZIMCommunityCreateConfig alloc] init];
config.communityNotice = @"欢迎加入!";
[zim createCommunity:communityInfo config:config callback:^(ZIMCommunityFullInfo * _Nonnull communityFullInfo, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
// 创建成功,communityFullInfo 包含完整社群信息
}
}];ZIMCommunityInfo *communityInfo = [[ZIMCommunityInfo alloc] init];
communityInfo.communityID = @"community_001";
communityInfo.communityName = @"我的社群";
communityInfo.communityAvatarUrl = @"https://example.com/avatar.png";
ZIMCommunityCreateConfig *config = [[ZIMCommunityCreateConfig alloc] init];
config.communityNotice = @"欢迎加入!";
[zim createCommunity:communityInfo config:config callback:^(ZIMCommunityFullInfo * _Nonnull communityFullInfo, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
// 创建成功,communityFullInfo 包含完整社群信息
}
}];示例代码
#include <zim/zim.h>
using namespace ZIM;
// 构造社群基本信息
ZIMCommunityInfo communityInfo;
communityInfo.communityID = "community_001";
communityInfo.communityName = "我的社群";
communityInfo.communityAvatarUrl = "https://example.com/avatar.png";
ZIMCommunityCreateConfig config;
// 可选:设置社群公告
config.communityNotice = "欢迎加入!";
zim->createCommunity(communityInfo, config, [](ZIMCommunityFullInfo fullInfo, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
// 创建成功,fullInfo 包含完整社群信息
}
});#include <zim/zim.h>
using namespace ZIM;
// 构造社群基本信息
ZIMCommunityInfo communityInfo;
communityInfo.communityID = "community_001";
communityInfo.communityName = "我的社群";
communityInfo.communityAvatarUrl = "https://example.com/avatar.png";
ZIMCommunityCreateConfig config;
// 可选:设置社群公告
config.communityNotice = "欢迎加入!";
zim->createCommunity(communityInfo, config, [](ZIMCommunityFullInfo fullInfo, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
// 创建成功,fullInfo 包含完整社群信息
}
});示例代码
// 构造社群基本信息
const communityInfo = {
communityID: "community_001",
communityName: "我的社群",
communityAvatarUrl: "https://example.com/avatar.png"
};
const config = {
// 可选:设置社群公告
communityNotice: "欢迎加入!"
};
try {
const result = await zim.createCommunity(communityInfo, config);
// 创建成功,result 包含完整社群信息
} catch (error) {
// 创建失败,根据 error.code 处理
}// 构造社群基本信息
const communityInfo = {
communityID: "community_001",
communityName: "我的社群",
communityAvatarUrl: "https://example.com/avatar.png"
};
const config = {
// 可选:设置社群公告
communityNotice: "欢迎加入!"
};
try {
const result = await zim.createCommunity(communityInfo, config);
// 创建成功,result 包含完整社群信息
} catch (error) {
// 创建失败,根据 error.code 处理
}示例代码
// 构造社群基本信息
final communityInfo = ZIMCommunityInfo()
..communityID = 'community_001'
..communityName = '我的社群'
..communityAvatarUrl = 'https://example.com/avatar.png';
final config = ZIMCommunityCreateConfig();
// 可选:设置社群公告
config.communityNotice = '欢迎加入!';
try {
final result = await ZIM.getInstance()!.createCommunity(
communityInfo: communityInfo,
config: config,
);
// 创建成功,result 包含完整社群信息
} catch (error) {
// 创建失败,根据 error.code 处理
}// 构造社群基本信息
final communityInfo = ZIMCommunityInfo()
..communityID = 'community_001'
..communityName = '我的社群'
..communityAvatarUrl = 'https://example.com/avatar.png';
final config = ZIMCommunityCreateConfig();
// 可选:设置社群公告
config.communityNotice = '欢迎加入!';
try {
final result = await ZIM.getInstance()!.createCommunity(
communityInfo: communityInfo,
config: config,
);
// 创建成功,result 包含完整社群信息
} catch (error) {
// 创建失败,根据 error.code 处理
}加入已有社群
已知 communityID 时,调用 joinCommunity 接口加入社群。
String communityID = "community_001";
zim.joinCommunity(communityID, (ZIMCommunityFullInfo fullInfo, ZIMError error) -> {
if (error.code == ZIMErrorCode.SUCCESS) {
// 加入成功,fullInfo 包含完整社群信息
}
});String communityID = "community_001";
zim.joinCommunity(communityID, (ZIMCommunityFullInfo fullInfo, ZIMError error) -> {
if (error.code == ZIMErrorCode.SUCCESS) {
// 加入成功,fullInfo 包含完整社群信息
}
});示例代码
NSString *communityID = @"community_001";
[zim joinCommunity:communityID callback:^(ZIMCommunityFullInfo * _Nonnull communityFullInfo, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
// 加入成功,communityFullInfo 包含完整社群信息
}
}];NSString *communityID = @"community_001";
[zim joinCommunity:communityID callback:^(ZIMCommunityFullInfo * _Nonnull communityFullInfo, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
// 加入成功,communityFullInfo 包含完整社群信息
}
}];示例代码
std::string communityID = "community_001";
zim->joinCommunity(communityID, [](ZIMCommunityFullInfo fullInfo, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
// 加入成功,fullInfo 包含完整社群信息
}
});std::string communityID = "community_001";
zim->joinCommunity(communityID, [](ZIMCommunityFullInfo fullInfo, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
// 加入成功,fullInfo 包含完整社群信息
}
});示例代码
const communityID = "community_001";
try {
const result = await zim.joinCommunity(communityID);
// 加入成功,result 包含完整社群信息
} catch (error) {
// 加入失败,根据 error.code 处理
}const communityID = "community_001";
try {
const result = await zim.joinCommunity(communityID);
// 加入成功,result 包含完整社群信息
} catch (error) {
// 加入失败,根据 error.code 处理
}示例代码
const communityID = 'community_001';
try {
final result = await ZIM.getInstance()!.joinCommunity(communityID);
// 加入成功,result 包含完整社群信息
} catch (error) {
// 加入失败,根据 error.code 处理
}const communityID = 'community_001';
try {
final result = await ZIM.getInstance()!.joinCommunity(communityID);
// 加入成功,result 包含完整社群信息
} catch (error) {
// 加入失败,根据 error.code 处理
}步骤二:获取频道列表
加入社群后,调用 queryCommunityChannelList 接口查询频道列表,获取频道对象 ZIMCommunityChannel。
频道对象的 conversationID 字段即是后续收发消息所需的会话 ID。
String communityID = "community_001";
int count = 100; // 每次最多拉取的频道数量
ZIMCommunityChannelListQueryConfig config = new ZIMCommunityChannelListQueryConfig();
// config.nextFlag 用于分页,首次查询无需设置,下次查询填入上次返回的 nextFlag
zim.queryCommunityChannelList(communityID, count, config,
(ArrayList<ZIMCommunityChannel> channelList, long nextFlag, ZIMError error) -> {
if (error.code == ZIMErrorCode.SUCCESS) {
for (ZIMCommunityChannel channel : channelList) {
// channel.getBaseInfo().getChannelID() — 频道 ID
// channel.getBaseInfo().getChannelName() — 频道名称
// channel.getConversationID() — 发送/接收消息时使用的会话 ID
}
}
});String communityID = "community_001";
int count = 100; // 每次最多拉取的频道数量
ZIMCommunityChannelListQueryConfig config = new ZIMCommunityChannelListQueryConfig();
// config.nextFlag 用于分页,首次查询无需设置,下次查询填入上次返回的 nextFlag
zim.queryCommunityChannelList(communityID, count, config,
(ArrayList<ZIMCommunityChannel> channelList, long nextFlag, ZIMError error) -> {
if (error.code == ZIMErrorCode.SUCCESS) {
for (ZIMCommunityChannel channel : channelList) {
// channel.getBaseInfo().getChannelID() — 频道 ID
// channel.getBaseInfo().getChannelName() — 频道名称
// channel.getConversationID() — 发送/接收消息时使用的会话 ID
}
}
});示例代码
NSString *communityID = @"community_001";
NSUInteger count = 100;
ZIMCommunityChannelListQueryConfig *config = [[ZIMCommunityChannelListQueryConfig alloc] init];
// config.nextFlag 用于分页,首次查询无需设置
[zim queryCommunityChannelList:communityID count:count config:config callback:^(NSString * _Nonnull communityID, NSArray<ZIMCommunityChannel *> * _Nonnull channelList, long long nextFlag, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
for (ZIMCommunityChannel *channel in channelList) {
// channel.baseInfo.channelID — 频道 ID
// channel.baseInfo.channelName — 频道名称
// channel.conversationID — 发送/接收消息时使用的会话 ID
}
}
}];NSString *communityID = @"community_001";
NSUInteger count = 100;
ZIMCommunityChannelListQueryConfig *config = [[ZIMCommunityChannelListQueryConfig alloc] init];
// config.nextFlag 用于分页,首次查询无需设置
[zim queryCommunityChannelList:communityID count:count config:config callback:^(NSString * _Nonnull communityID, NSArray<ZIMCommunityChannel *> * _Nonnull channelList, long long nextFlag, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
for (ZIMCommunityChannel *channel in channelList) {
// channel.baseInfo.channelID — 频道 ID
// channel.baseInfo.channelName — 频道名称
// channel.conversationID — 发送/接收消息时使用的会话 ID
}
}
}];示例代码
std::string communityID = "community_001";
unsigned int count = 100; // 每次最多拉取的频道数量
ZIMCommunityChannelListQueryConfig config;
// config.nextFlag 用于分页,首次查询无需设置,下次查询填入上次返回的 nextFlag
zim->queryCommunityChannelList(communityID, count, config,
[](std::string communityID, std::vector<ZIMCommunityChannel> channelList, uint64_t nextFlag, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
for (auto& channel : channelList) {
// channel.baseInfo.channelID — 频道 ID
// channel.baseInfo.channelName — 频道名称
// channel.conversationID — 发送/接收消息时使用的会话 ID
}
}
});std::string communityID = "community_001";
unsigned int count = 100; // 每次最多拉取的频道数量
ZIMCommunityChannelListQueryConfig config;
// config.nextFlag 用于分页,首次查询无需设置,下次查询填入上次返回的 nextFlag
zim->queryCommunityChannelList(communityID, count, config,
[](std::string communityID, std::vector<ZIMCommunityChannel> channelList, uint64_t nextFlag, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
for (auto& channel : channelList) {
// channel.baseInfo.channelID — 频道 ID
// channel.baseInfo.channelName — 频道名称
// channel.conversationID — 发送/接收消息时使用的会话 ID
}
}
});示例代码
const communityID = "community_001";
const count = 100; // 每次最多拉取的频道数量
const config = {
// nextFlag 用于分页,首次查询无需设置,下次查询填入上次返回的 nextFlag
};
try {
const result = await zim.queryCommunityChannelList(communityID, count, config);
for (const channel of result.channelList) {
// channel.baseInfo.channelID — 频道 ID
// channel.baseInfo.channelName — 频道名称
// channel.conversationID — 发送/接收消息时使用的会话 ID
}
// result.nextFlag 用于分页,为 0 或列表为空时表示无更多数据
} catch (error) {
// 查询失败,根据 error.code 处理
}const communityID = "community_001";
const count = 100; // 每次最多拉取的频道数量
const config = {
// nextFlag 用于分页,首次查询无需设置,下次查询填入上次返回的 nextFlag
};
try {
const result = await zim.queryCommunityChannelList(communityID, count, config);
for (const channel of result.channelList) {
// channel.baseInfo.channelID — 频道 ID
// channel.baseInfo.channelName — 频道名称
// channel.conversationID — 发送/接收消息时使用的会话 ID
}
// result.nextFlag 用于分页,为 0 或列表为空时表示无更多数据
} catch (error) {
// 查询失败,根据 error.code 处理
}示例代码
const communityID = 'community_001';
const count = 100; // 每次最多拉取的频道数量
final config = ZIMCommunityChannelListQueryConfig();
// config.nextFlag 用于分页,首次查询无需设置
try {
final result = await ZIM.getInstance()!.queryCommunityChannelList(
communityID,
count,
config: config,
);
for (final channel in result.channelList) {
// channel.baseInfo.channelID — 频道 ID
// channel.baseInfo.channelName — 频道名称
// channel.conversationID — 发送/接收消息时使用的会话 ID
}
// result.nextFlag 用于分页,为 0 或列表为空时表示无更多数据
} catch (error) {
// 查询失败,根据 error.code 处理
}const communityID = 'community_001';
const count = 100; // 每次最多拉取的频道数量
final config = ZIMCommunityChannelListQueryConfig();
// config.nextFlag 用于分页,首次查询无需设置
try {
final result = await ZIM.getInstance()!.queryCommunityChannelList(
communityID,
count,
config: config,
);
for (final channel in result.channelList) {
// channel.baseInfo.channelID — 频道 ID
// channel.baseInfo.channelName — 频道名称
// channel.conversationID — 发送/接收消息时使用的会话 ID
}
// result.nextFlag 用于分页,为 0 或列表为空时表示无更多数据
} catch (error) {
// 查询失败,根据 error.code 处理
}ZIMCommunityChannel.conversationID与ZIMCommunityChannelInfo.channelID不同,发送消息时请使用conversationID。- 如果社群频道较多,可根据返回的
nextFlag多次分页拉取,直到返回的nextFlag为 0 或列表为空。
发送消息
频道消息发送和接收使用的 conversationID 与频道的 channelID 不同。conversationID 用于消息收发和会话管理,可通过频道对象获取;channelID 用于频道管理操作(如创建、更新、删除频道)。请勿将两者混淆。
获取到目标频道的 conversationID 后,调用 sendMessage 接口发送消息。与其他会话类型的区别在于:需要将 conversationType 设置为 ZIMConversationType.COMMUNITY_CHANNEL。
- 发送消息的接口与单聊、群组、房间共用同一个 sendMessage,通过
conversationType区分目标会话类型。 - 两次发送消息之间的间隔须大于 100ms。
普通消息
// 获取到目标频道后,用其 conversationID 发送消息
String conversationID = channel.getConversationID(); // 来自 queryCommunityChannelList 返回结果
ZIMTextMessage textMessage = new ZIMTextMessage();
textMessage.setMessage("Hello, Channel!");
ZIMMessageSendConfig config = new ZIMMessageSendConfig();
// 设置消息优先级:LOW(1) / MEDIUM(2) / HIGH(3)
config.setPriority(ZIMMessagePriority.LOW);
zim.sendMessage(
textMessage,
conversationID,
ZIMConversationType.COMMUNITY_CHANNEL, // 会话类型:社群频道
config,
new ZIMMessageSentFullCallback() {
@Override
public void onMessageAttached(ZIMMessage message) {
// 消息已通过本地校验,准备发送;可在此更新 UI(如展示发送中状态)
}
@Override
public void onMessageSent(ZIMMessage message, ZIMError error) {
if (error.code == ZIMErrorCode.SUCCESS) {
// 消息发送成功
} else {
// 消息发送失败,可根据 error.code 处理
}
}
@Override
public void onMediaUploadingProgress(ZIMMediaMessage message, long currentFileSize, long totalFileSize) {
}
@Override
public void onMultipleMediaUploadingProgress(ZIMMultipleMessage message, long messageInfoIndex, long currentIndexFileSize, int messageIndex, long totalIndexFileSize, long totalFileSize) {
}
}
);// 获取到目标频道后,用其 conversationID 发送消息
String conversationID = channel.getConversationID(); // 来自 queryCommunityChannelList 返回结果
ZIMTextMessage textMessage = new ZIMTextMessage();
textMessage.setMessage("Hello, Channel!");
ZIMMessageSendConfig config = new ZIMMessageSendConfig();
// 设置消息优先级:LOW(1) / MEDIUM(2) / HIGH(3)
config.setPriority(ZIMMessagePriority.LOW);
zim.sendMessage(
textMessage,
conversationID,
ZIMConversationType.COMMUNITY_CHANNEL, // 会话类型:社群频道
config,
new ZIMMessageSentFullCallback() {
@Override
public void onMessageAttached(ZIMMessage message) {
// 消息已通过本地校验,准备发送;可在此更新 UI(如展示发送中状态)
}
@Override
public void onMessageSent(ZIMMessage message, ZIMError error) {
if (error.code == ZIMErrorCode.SUCCESS) {
// 消息发送成功
} else {
// 消息发送失败,可根据 error.code 处理
}
}
@Override
public void onMediaUploadingProgress(ZIMMediaMessage message, long currentFileSize, long totalFileSize) {
}
@Override
public void onMultipleMediaUploadingProgress(ZIMMultipleMessage message, long messageInfoIndex, long currentIndexFileSize, int messageIndex, long totalIndexFileSize, long totalFileSize) {
}
}
);示例代码
// 获取到目标频道后,用其 conversationID 发送消息
NSString *conversationID = channel.conversationID;
ZIMTextMessage *textMessage = [[ZIMTextMessage alloc] init];
textMessage.message = @"Hello, Channel!";
ZIMMessageSendConfig *config = [[ZIMMessageSendConfig alloc] init];
config.priority = ZIMMessagePriorityLow;
[zim sendMessage:textMessage toConversationID:conversationID conversationType:ZIMConversationTypeCommunityChannel config:config callback:^(ZIMMessage * _Nonnull message, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
// 消息发送成功
}
}];// 获取到目标频道后,用其 conversationID 发送消息
NSString *conversationID = channel.conversationID;
ZIMTextMessage *textMessage = [[ZIMTextMessage alloc] init];
textMessage.message = @"Hello, Channel!";
ZIMMessageSendConfig *config = [[ZIMMessageSendConfig alloc] init];
config.priority = ZIMMessagePriorityLow;
[zim sendMessage:textMessage toConversationID:conversationID conversationType:ZIMConversationTypeCommunityChannel config:config callback:^(ZIMMessage * _Nonnull message, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
// 消息发送成功
}
}];示例代码
// 获取到目标频道后,用其 conversationID 发送消息
std::string conversationID = channel.conversationID; // 来自 queryCommunityChannelList 返回结果
auto textMessage = ZIMTextMessage();
textMessage.message = "Hello, Channel!";
ZIMMessageSendConfig config;
// 设置消息优先级:LOW(1) / MEDIUM(2) / HIGH(3)
config.priority = ZIMMessagePriority::LOW;
zim->sendMessage(
textMessage,
conversationID,
ZIMConversationType::COMMUNITY_CHANNEL, // 会话类型:社群频道
config,
[](ZIMMessage message, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
// 消息发送成功
} else {
// 消息发送失败,可根据 error.code 处理
}
});// 获取到目标频道后,用其 conversationID 发送消息
std::string conversationID = channel.conversationID; // 来自 queryCommunityChannelList 返回结果
auto textMessage = ZIMTextMessage();
textMessage.message = "Hello, Channel!";
ZIMMessageSendConfig config;
// 设置消息优先级:LOW(1) / MEDIUM(2) / HIGH(3)
config.priority = ZIMMessagePriority::LOW;
zim->sendMessage(
textMessage,
conversationID,
ZIMConversationType::COMMUNITY_CHANNEL, // 会话类型:社群频道
config,
[](ZIMMessage message, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
// 消息发送成功
} else {
// 消息发送失败,可根据 error.code 处理
}
});示例代码
// 获取到目标频道后,用其 conversationID 发送消息
const conversationID = channel.conversationID; // 来自 queryCommunityChannelList 返回结果
const textMessage = new ZIMTextMessage();
textMessage.message = "Hello, Channel!";
const config = {
// 设置消息优先级:LOW(1) / MEDIUM(2) / HIGH(3)
priority: ZIMMessagePriority.LOW,
};
try {
const result = await zim.sendMessage(
textMessage,
conversationID,
ZIMConversationType.COMMUNITY_CHANNEL, // 会话类型:社群频道
config
);
// 消息发送成功
} catch (error) {
// 消息发送失败,可根据 error.code 处理
}// 获取到目标频道后,用其 conversationID 发送消息
const conversationID = channel.conversationID; // 来自 queryCommunityChannelList 返回结果
const textMessage = new ZIMTextMessage();
textMessage.message = "Hello, Channel!";
const config = {
// 设置消息优先级:LOW(1) / MEDIUM(2) / HIGH(3)
priority: ZIMMessagePriority.LOW,
};
try {
const result = await zim.sendMessage(
textMessage,
conversationID,
ZIMConversationType.COMMUNITY_CHANNEL, // 会话类型:社群频道
config
);
// 消息发送成功
} catch (error) {
// 消息发送失败,可根据 error.code 处理
}示例代码
// 获取到目标频道后,用其 conversationID 发送消息
final conversationID = channel.conversationID; // 来自 queryCommunityChannelList 返回结果
final textMessage = ZIMTextMessage(message: 'Hello, Channel!');
final config = ZIMMessageSendConfig()
..priority = ZIMMessagePriority.low; // 设置消息优先级:low / medium / high
try {
final result = await ZIM.getInstance()!.sendMessage(
textMessage,
conversationID,
ZIMConversationType.communityChannel, // 会话类型:社群频道
config: config,
);
// 消息发送成功
} catch (error) {
// 消息发送失败,可根据 error.code 处理
}// 获取到目标频道后,用其 conversationID 发送消息
final conversationID = channel.conversationID; // 来自 queryCommunityChannelList 返回结果
final textMessage = ZIMTextMessage(message: 'Hello, Channel!');
final config = ZIMMessageSendConfig()
..priority = ZIMMessagePriority.low; // 设置消息优先级:low / medium / high
try {
final result = await ZIM.getInstance()!.sendMessage(
textMessage,
conversationID,
ZIMConversationType.communityChannel, // 会话类型:社群频道
config: config,
);
// 消息发送成功
} catch (error) {
// 消息发送失败,可根据 error.code 处理
}富媒体消息
发送图片、文件、音频、视频等富媒体消息时,同样将 conversationType 设置为 ZIMConversationType.COMMUNITY_CHANNEL,其余用法与群组消息一致。
// 以发送图片消息为例
ZIMImageMessage imageMessage = new ZIMImageMessage(
"/storage/emulated/0/Android/data/com.example/pictures/photo.jpg"
);
ZIMMessageSendConfig config = new ZIMMessageSendConfig();
config.setPriority(ZIMMessagePriority.MEDIUM);
zim.sendMessage(
imageMessage,
conversationID,
ZIMConversationType.COMMUNITY_CHANNEL,
config,
new ZIMMessageSentFullCallback() {
@Override
public void onMessageAttached(ZIMMessage message) {
// 可在此提前展示图片占位 UI
}
@Override
public void onMessageSent(ZIMMessage message, ZIMError error) {
if (error.code == ZIMErrorCode.SUCCESS) {
// 图片发送成功,message 中包含服务端生成的 fileDownloadUrl
}
}
@Override
public void onMediaUploadingProgress(
ZIMMediaMessage message, long currentFileSize, long totalFileSize) {
// 可在此更新上传进度条
}
}
);// 以发送图片消息为例
ZIMImageMessage imageMessage = new ZIMImageMessage(
"/storage/emulated/0/Android/data/com.example/pictures/photo.jpg"
);
ZIMMessageSendConfig config = new ZIMMessageSendConfig();
config.setPriority(ZIMMessagePriority.MEDIUM);
zim.sendMessage(
imageMessage,
conversationID,
ZIMConversationType.COMMUNITY_CHANNEL,
config,
new ZIMMessageSentFullCallback() {
@Override
public void onMessageAttached(ZIMMessage message) {
// 可在此提前展示图片占位 UI
}
@Override
public void onMessageSent(ZIMMessage message, ZIMError error) {
if (error.code == ZIMErrorCode.SUCCESS) {
// 图片发送成功,message 中包含服务端生成的 fileDownloadUrl
}
}
@Override
public void onMediaUploadingProgress(
ZIMMediaMessage message, long currentFileSize, long totalFileSize) {
// 可在此更新上传进度条
}
}
);示例代码
// 以发送图片消息为例
ZIMImageMessage *imageMessage = [[ZIMImageMessage alloc] initWithFileLocalPath:@"/path/to/photo.jpg"];
ZIMMessageSendConfig *config = [[ZIMMessageSendConfig alloc] init];
config.priority = ZIMMessagePriorityMedium;
[zim sendMessage:imageMessage toConversationID:conversationID conversationType:ZIMConversationTypeCommunityChannel config:config callback:^(ZIMMessage * _Nonnull message, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
// 图片发送成功
}
}];// 以发送图片消息为例
ZIMImageMessage *imageMessage = [[ZIMImageMessage alloc] initWithFileLocalPath:@"/path/to/photo.jpg"];
ZIMMessageSendConfig *config = [[ZIMMessageSendConfig alloc] init];
config.priority = ZIMMessagePriorityMedium;
[zim sendMessage:imageMessage toConversationID:conversationID conversationType:ZIMConversationTypeCommunityChannel config:config callback:^(ZIMMessage * _Nonnull message, ZIMError * _Nonnull errorInfo) {
if (errorInfo.code == ZIMErrorCodenoneSuccess) {
// 图片发送成功
}
}];示例代码
// 以发送图片消息为例
auto imageMessage = ZIMImageMessage("/path/to/photo.jpg");
ZIMMessageSendConfig config;
config.priority = ZIMMessagePriority::MEDIUM;
zim->sendMessage(
imageMessage,
conversationID,
ZIMConversationType::COMMUNITY_CHANNEL,
config,
[](ZIMMessage message, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
// 图片发送成功,message 中包含服务端生成的 fileDownloadUrl
}
});// 以发送图片消息为例
auto imageMessage = ZIMImageMessage("/path/to/photo.jpg");
ZIMMessageSendConfig config;
config.priority = ZIMMessagePriority::MEDIUM;
zim->sendMessage(
imageMessage,
conversationID,
ZIMConversationType::COMMUNITY_CHANNEL,
config,
[](ZIMMessage message, ZIMError error) {
if (error.code == ZIMErrorCodeSuccess) {
// 图片发送成功,message 中包含服务端生成的 fileDownloadUrl
}
});示例代码
// 以发送图片消息为例
const imageMessage = new ZIMImageMessage({ fileLocalPath: '/path/to/photo.jpg' });
const config = {
priority: ZIMMessagePriority.MEDIUM,
};
try {
const result = await zim.sendMessage(
imageMessage,
conversationID,
ZIMConversationType.COMMUNITY_CHANNEL,
config
);
// 图片发送成功
} catch (error) {
// 图片发送失败,可根据 error.code 处理
}// 以发送图片消息为例
const imageMessage = new ZIMImageMessage({ fileLocalPath: '/path/to/photo.jpg' });
const config = {
priority: ZIMMessagePriority.MEDIUM,
};
try {
const result = await zim.sendMessage(
imageMessage,
conversationID,
ZIMConversationType.COMMUNITY_CHANNEL,
config
);
// 图片发送成功
} catch (error) {
// 图片发送失败,可根据 error.code 处理
}示例代码
// 以发送图片消息为例
final imageMessage = ZIMImageMessage(fileLocalPath: '/path/to/photo.jpg');
final config = ZIMMessageSendConfig()
..priority = ZIMMessagePriority.medium;
try {
final result = await ZIM.getInstance()!.sendMessage(
imageMessage,
conversationID,
ZIMConversationType.communityChannel,
config: config,
);
// 图片发送成功
} catch (error) {
// 图片发送失败,可根据 error.code 处理
}// 以发送图片消息为例
final imageMessage = ZIMImageMessage(fileLocalPath: '/path/to/photo.jpg');
final config = ZIMMessageSendConfig()
..priority = ZIMMessagePriority.medium;
try {
final result = await ZIM.getInstance()!.sendMessage(
imageMessage,
conversationID,
ZIMConversationType.communityChannel,
config: config,
);
// 图片发送成功
} catch (error) {
// 图片发送失败,可根据 error.code 处理
}各消息类型(自定义消息、组合消息等)的构造方式与发送参数,请参考 收发消息。将对应示例代码中的 conversationType 替换为 ZIMConversationType.COMMUNITY_CHANNEL,toConversationID 替换为频道的 conversationID 即可。
接收消息
ZIM SDK 3.0.0 起,通过统一的 onMessageReceived 回调接收来自单聊、群组、房间和社群频道的所有在线消息。回调返回 ZIMMessageReceivedEventResult,其中 receivedInfo.conversationType 字段用于判断消息所属的会话类型。
zim.setEventHandler(new ZIMEventHandler() {
@Override
public void onMessageReceived(ZIM zim, ZIMMessageReceivedEventResult result) {
ZIMMessageReceivedInfo info = result.getReceivedInfo();
// 过滤社群频道消息
if (info.getConversationType() == ZIMConversationType.COMMUNITY_CHANNEL) {
String conversationID = info.getConversationID(); // 消息所属频道的 conversationID
for (ZIMMessage message : result.getMessageList()) {
// 根据消息类型处理
switch (message.getType()) {
case TEXT:
ZIMTextMessage textMsg = (ZIMTextMessage) message;
// 处理文本消息
break;
case IMAGE:
ZIMImageMessage imageMsg = (ZIMImageMessage) message;
// 处理图片消息,可调用 downloadMediaFile 下载原图
break;
default:
break;
}
}
}
}
});zim.setEventHandler(new ZIMEventHandler() {
@Override
public void onMessageReceived(ZIM zim, ZIMMessageReceivedEventResult result) {
ZIMMessageReceivedInfo info = result.getReceivedInfo();
// 过滤社群频道消息
if (info.getConversationType() == ZIMConversationType.COMMUNITY_CHANNEL) {
String conversationID = info.getConversationID(); // 消息所属频道的 conversationID
for (ZIMMessage message : result.getMessageList()) {
// 根据消息类型处理
switch (message.getType()) {
case TEXT:
ZIMTextMessage textMsg = (ZIMTextMessage) message;
// 处理文本消息
break;
case IMAGE:
ZIMImageMessage imageMsg = (ZIMImageMessage) message;
// 处理图片消息,可调用 downloadMediaFile 下载原图
break;
default:
break;
}
}
}
}
});示例代码
zim.eventHandler = self;
- (void)zim:(ZIM *)zim messageReceivedWithResult:(ZIMMessageReceivedEventResult *)result {
ZIMMessageReceivedInfo *info = result.receivedInfo;
// 过滤社群频道消息
if (info.conversationType == ZIMConversationTypeCommunityChannel) {
NSString *conversationID = info.conversationID;
for (ZIMMessage *message in result.messageList) {
// 根据消息类型处理
if ([message isKindOfClass:[ZIMTextMessage class]]) {
ZIMTextMessage *textMsg = (ZIMTextMessage *)message;
// 处理文本消息
} else if ([message isKindOfClass:[ZIMImageMessage class]]) {
ZIMImageMessage *imageMsg = (ZIMImageMessage *)message;
// 处理图片消息
}
}
}
}zim.eventHandler = self;
- (void)zim:(ZIM *)zim messageReceivedWithResult:(ZIMMessageReceivedEventResult *)result {
ZIMMessageReceivedInfo *info = result.receivedInfo;
// 过滤社群频道消息
if (info.conversationType == ZIMConversationTypeCommunityChannel) {
NSString *conversationID = info.conversationID;
for (ZIMMessage *message in result.messageList) {
// 根据消息类型处理
if ([message isKindOfClass:[ZIMTextMessage class]]) {
ZIMTextMessage *textMsg = (ZIMTextMessage *)message;
// 处理文本消息
} else if ([message isKindOfClass:[ZIMImageMessage class]]) {
ZIMImageMessage *imageMsg = (ZIMImageMessage *)message;
// 处理图片消息
}
}
}
}示例代码
zim->setEventHandler([&](ZIMMessageReceivedEventResult result) {
auto info = result.receivedInfo;
// 过滤社群频道消息
if (info.conversationType == ZIMConversationType::COMMUNITY_CHANNEL) {
std::string conversationID = info.conversationID;
for (auto& message : result.messageList) {
// 根据消息类型处理
if (message.type == ZIMMessageType::TEXT) {
auto textMsg = std::static_pointer_cast<ZIMTextMessage>(message);
// 处理文本消息
} else if (message.type == ZIMMessageType::IMAGE) {
auto imageMsg = std::static_pointer_cast<ZIMImageMessage>(message);
// 处理图片消息,可调用 downloadMediaFile 下载原图
}
}
}
});zim->setEventHandler([&](ZIMMessageReceivedEventResult result) {
auto info = result.receivedInfo;
// 过滤社群频道消息
if (info.conversationType == ZIMConversationType::COMMUNITY_CHANNEL) {
std::string conversationID = info.conversationID;
for (auto& message : result.messageList) {
// 根据消息类型处理
if (message.type == ZIMMessageType::TEXT) {
auto textMsg = std::static_pointer_cast<ZIMTextMessage>(message);
// 处理文本消息
} else if (message.type == ZIMMessageType::IMAGE) {
auto imageMsg = std::static_pointer_cast<ZIMImageMessage>(message);
// 处理图片消息,可调用 downloadMediaFile 下载原图
}
}
}
});示例代码
zim.on('messageReceived', (result: ZIMMessageReceivedEventResult) => {
const info = result.receivedInfo;
// 过滤社群频道消息
if (info.conversationType === ZIMConversationType.COMMUNITY_CHANNEL) {
const conversationID = info.conversationID;
for (const message of result.messageList) {
// 根据消息类型处理
if (message.type === ZIMMessageType.TEXT) {
const textMsg = message as ZIMTextMessage;
// 处理文本消息
} else if (message.type === ZIMMessageType.IMAGE) {
const imageMsg = message as ZIMImageMessage;
// 处理图片消息,可调用 downloadMediaFile 下载原图
}
}
}
});zim.on('messageReceived', (result: ZIMMessageReceivedEventResult) => {
const info = result.receivedInfo;
// 过滤社群频道消息
if (info.conversationType === ZIMConversationType.COMMUNITY_CHANNEL) {
const conversationID = info.conversationID;
for (const message of result.messageList) {
// 根据消息类型处理
if (message.type === ZIMMessageType.TEXT) {
const textMsg = message as ZIMTextMessage;
// 处理文本消息
} else if (message.type === ZIMMessageType.IMAGE) {
const imageMsg = message as ZIMImageMessage;
// 处理图片消息,可调用 downloadMediaFile 下载原图
}
}
}
});示例代码
ZIMEventHandler.onMessageReceived = (ZIM zim, ZIMMessageReceivedEventResult result) {
final info = result.receivedInfo;
// 过滤社群频道消息
if (info.conversationType == ZIMConversationType.communityChannel) {
final conversationID = info.conversationID;
for (final message in result.messageList) {
// 根据消息类型处理
if (message is ZIMTextMessage) {
// 处理文本消息
} else if (message is ZIMImageMessage) {
// 处理图片消息,可调用 downloadMediaFile 下载原图
}
}
}
};ZIMEventHandler.onMessageReceived = (ZIM zim, ZIMMessageReceivedEventResult result) {
final info = result.receivedInfo;
// 过滤社群频道消息
if (info.conversationType == ZIMConversationType.communityChannel) {
final conversationID = info.conversationID;
for (final message in result.messageList) {
// 根据消息类型处理
if (message is ZIMTextMessage) {
// 处理文本消息
} else if (message is ZIMImageMessage) {
// 处理图片消息,可调用 downloadMediaFile 下载原图
}
}
}
};- 用户重新登录后,可通过此回调收到离线期间积压的频道消息(需服务端开启频道离线消息存储)。
- 如需主动拉取历史消息,请参考 查询历史消息,传入频道的
conversationID和ZIMConversationType.COMMUNITY_CHANNEL。
进阶操作
在基础收发消息之外,社群频道还支持以下进阶消息操作。各功能的 conversationID 传入频道的 conversationID,conversationType 传入 ZIMConversationType.COMMUNITY_CHANNEL 即可,详细用法参见对应文档。
| 功能 | 说明 |
|---|---|
| 获取历史消息 | 分页拉取频道内的历史消息,支持按时间范围、消息序号等条件查询。 |
| 插入本地消息 | 向频道本地数据库插入一条仅本端可见的提示消息,不会发送给其他成员。 |
| 撤回消息 | 撤回频道内自己发送的消息;管理员或群主可撤回他人消息。 |
| 设置消息拓展字段 | 为频道消息附加对端可见或仅本端可见的拓展字段。 |
| 搜索本地消息 | 按关键字、用户 ID 等条件搜索频道内的本地历史消息。 |
| 消息表态 | 对频道消息添加或删除 Emoji 表态,支持群组投票等场景。 |
| 接收 Tips 消息 | 接收频道内由系统自动产生的操作提示消息(如成员加入/离开等)。 |
| 编辑消息 | 修改频道内已发送的消息,变更内容实时同步给所有频道成员。 |
