V2TIMManager
和 V2TIMManager+Message(iOS & Mac)
/ V2TIMMessageManager(Android & Windows)
中。// 拉取单聊历史消息// 首次拉取,lastMsg 设置为 null// 再次拉取时,lastMsg 可以使用返回的消息列表中的最后一条消息V2TIMManager.getMessageManager().getC2CHistoryMessageList(#your user id#, 20, null, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "fail, " + code + ", " + desc);}@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {// 记录下次拉取的 lastMsg, 用于下次拉取V2TIMMessage lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);Log.i("imsdk", "success");}});
// 拉取单聊历史消息// 首次拉取,lastMsg 设置为 nil// 再次拉取时,lastMsg 可以使用返回的消息列表中的最后一条消息[V2TIMManager.sharedInstance getC2CHistoryMessageList:#your user id# count:20 lastMsg:nil succ:^(NSArray<V2TIMMessage *> *msgs) {// 记录下次拉取的 lastMsg,用于下次拉取V2TIMMessage *lastMsg = msgs.lastObject;NSLog(@"success, %@", msgs);} fail:^(int code, NSString *desc) {NSLog(@"fail, %d, %@", code, desc);}];
getGroupHistoryMessageList
(Android / iOS & Mac) 获取群聊历史消息。
在网络正常的情况下会拉取最新的云端数据。如果网络出现异常,SDK 会返回本地存储的历史消息。onRecvNewMessage
回调中获得入群前消息。// 拉取群聊历史消息// 首次拉取,lastMsg 设置为 null// 再次拉取时,lastMsg 可以使用返回的消息列表中的最后一条消息V2TIMManager.getMessageManager().getGroupHistoryMessageList(#your group id#, 20, null, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "fail, " + code + ", " + desc);}@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {// 记录下次拉取的 lastMsg,用于下次拉取V2TIMMessage lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);Log.i("imsdk", "success");}});
// 拉取群聊历史消息// 首次拉取,lastMsg 设置为 null// 再次拉取时,lastMsg 可以使用返回的消息列表中的最后一条消息[V2TIMManager.sharedInstance getGroupHistoryMessageList:#your group id# count:20 lastMsg:nil succ:^(NSArray<V2TIMMessage *> *msgs) {// 记录下次拉取的 lastMsg,用于下次拉取V2TIMMessage *lastMsg = msgs.lastObject;NSLog(@"success, %@", msgs);} fail:^(int code, NSString *desc) {NSLog(@"fail, %d, %@", code, desc);}];
public abstract void getHistoryMessageList(V2TIMMessageListGetOption option, V2TIMValueCallback<List<V2TIMMessage>> callback);
- (void)getHistoryMessageList:(V2TIMMessageListGetOption *)optionsucc:(V2TIMMessageListSucc)succfail:(V2TIMFail)fail;
virtual void GetHistoryMessageList(const V2TIMMessageListGetOption& option,V2TIMValueCallback<V2TIMMessageVector>* callback) = 0;
V2TIMMessageListGetOption
类参数说明:参数 | 含义 | 单聊有效 | 群聊有效 | 是否必填 | 说明 |
getType | 拉取消息的位置及方向,可以设置拉取 本地/云端 的 更老/更新 的消息 | YES | YES | YES | 当设置从云端拉取时,会将本地存储消息列表与云端存储消息列表合并后返回。如果无网络,则直接返回本地消息列表。 |
userID | 拉取指定用户的单聊历史消息 | YES | NO | NO | 拉取单聊消息,需要指定对方的 userID ,此时 groupID 传空即可。 |
groupID | 拉取指定群组的群聊历史消息 | NO | YES | NO | 拉取群聊消息,需要指定群聊的 groupID ,此时 userID 传空即可。 |
count | 单次拉取的消息数量 | YES | YES | YES | 建议设置为 20,否则可能影响拉取速度 |
messageTypeList | 拉取的消息类型集合 | YES | YES | NO | 1. 只支持本地拉取,即当 getType 为 V2TIM_GET_LOCAL_OLDER_MSG 或 V2TIM_GET_LOCAL_NEWER_MSG 时有效。2. 如果该字段为空,表示拉取所有的消息类型。 |
lastMsg | 最后一条消息 | YES | YES | NO | 可用于拉取历史消息的场景。 1. 单聊和群聊中均能使用。 2. 设置 lastMsg 作为拉取的起点,返回的消息列表中不包含这条消息。3. 如果设置为空,则使用会话的最新一条消息作为拉取起点。 |
lastMsgSeq | 最后一条消息的 seq | NO | YES | NO | 可用于拉取历史消息或消息定位等场景。 1. 仅能在群聊中使用该字段。 2. 设置 lastMsgSeq 作为拉取的起点,返回的消息列表中包含这条消息。3. 如果同时指定了 lastMsg 和 lastMsgSeq ,SDK 优先使用 lastMsg 。4. 如果均未指定 lastMsg 和 lastMsgSeq ,拉取的起点取决于是否设置 getTimeBegin 。设置了,则使用设置的范围作为起点;未设置,则使用最新消息作为起点。 |
getTimeBegin | 拉取消息的时间起点。UTC 时间戳,单位:秒 | YES | YES | NO | 默认为 0,表示从当前时间开始拉取。 |
getTimePeriod | 拉取消息的时间范围。单位:秒 | YES | YES | NO | 1. 默认为 0,表示不限制时间范围。 2. 取值的范围区间为闭区间,包含起止时间,二者关系如下: 如果 getType 指定了朝消息时间更老的方向拉取,则时间范围表示为 [getTimeBegin - getTimePeriod , getTimeBegin ]。如果 getType 指定了朝消息时间更新的方向拉取,则时间范围表示为 [ getTimeBegin , getTimeBegin + getTimePeriod ]。 |
lastMsg
和 count
来实现:lastMsg
为空,此时 SDK 会拉取到最新的消息。lastMsg
,拉取下一页数据。此时消息列表返回的消息不包含设置的 lastMsg。lastMsgSeq
拉取历史消息,返回的消息列表会包含该 lastMsgSeq
所对应的消息。
因此,非首次拉取群聊历史消息(也就是续拉)时,建议不要使用 lastMsgSeq
,否则可能出现同一条消息被重复拉到的情况。
例如,现在的历史消息有 8 条,分别是:msg1、msg2、msg3、msg4、msg5、msg6、msg7、msg8。
每次拉取 4 条,首次拉取得到了 msg1、msg2、msg3、msg4,此时再用 msg4 的 lastMsgSeq
续拉,会拉到消息 msg4、msg5、msg6、msg7。两次拉取中,msg4 被重复拉取了。
如果您一定要使用 lastMsgSeq
续拉,建议处理好消息去重的逻辑。getTimeBegin
和 getTimePeriod
来拉取指定的时间范围内的消息。
如下图所示,时间范围的起止时间戳与 getType 有关。V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取云端的更老的消息option.setGetTimeBegin(1640966400); // 从 2022-01-01 00:00:00 开始option.setGetTimePeriod(1 * 24 * 60 * 60); // 拉取一整天的消息option.setCount(Integer.MAX_VALUE); // 返回时间范围内所有的消息option.setGroupID(#you group id#); // 拉取群聊消息V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {Log.i("imsdk", "success");}@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);}});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];option.getType = V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息option.getTimeBegin = 1640966400; // 从 2022-01-01 00:00:00 开始option.getTimePeriod = 1 * 24 * 60 * 60; // 拉取一整天的消息option.count = INT_MAX; // 返回时间范围内所有的消息option.groupID = #your group id#; // 拉取群聊消息[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {NSLog(@"success");} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];
template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public:using SuccessCallback = std::function<void(const T&)>;using ErrorCallback = std::function<void(int, const V2TIMString&)>;ValueCallback() = default;~ValueCallback() override = default;void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {success_callback_ = std::move(success_callback);error_callback_ = std::move(error_callback);}void OnSuccess(const T& value) override {if (success_callback_) {success_callback_(value);}}void OnError(int error_code, const V2TIMString& error_message) override {if (error_callback_) {error_callback_(error_code, error_message);}}private:SuccessCallback success_callback_;ErrorCallback error_callback_;};V2TIMMessageListGetOption option;option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息option.getTimeBegin = 1640966400; // 从 2022-01-01 00:00:00 开始option.getTimePeriod = 1 * 24 * 60 * 60; // 拉取一整天的消息option.count = std::numeric_limits<uint64_t>::max(); // 返回时间范围内所有的消息option.groupID = "your group id"; // 拉取群聊消息auto callback = new ValueCallback<V2TIMMessageVector>{};callback->SetCallback([=](const V2TIMMessageVector& messageList) {std::cout << "success" << std::endl;delete callback;},[=](int error_code, const V2TIMString& error_message) {std::cout << "error" << std::endl;delete callback;});V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);
lastMsg
/lastMsgSeq
。此时 SDK 的表现是:getTimeBegin
/getTimePeriod
和 lastMsg
/lastMsgSeq
,结果集可理解成:「单独按起始消息拉取的结果」与「单独按时间范围拉取的结果」 取交集。getTimeBegin
/getTimePeriod
和 lastMsg
/lastMsgSeq
,结果集可理解成:从当前会话最新的一条消息开始,按照 getType
所指定的方向和拉取方式拉取。// 定义变量,记录每次拉取的游标private V2TIMMessage m_lastMsg = null; // 首次拉取时为 null// 分页拉取逻辑V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取云端的更老的消息option.setGetTimeBegin(1640966400); // 从 2022-01-01 00:00:00 开始option.setGetTimePeriod(1 * 24 * 60 * 60); // 拉取一整天的消息option.setCount(20); // 每页 20 条option.setLastMsg(m_lastMsg); // 上次拉取的位置 (每次返回的消息列表的最后一条消息)option.setGroupID(#you group id#); // 拉取群聊消息V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {Log.i("imsdk", "success");// 记录下一次拉取的 lastMsgm_lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);}@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);}});
// 定义变量,记录每次拉取的游标@property (nonatomic, copy) V2TIMMessage *lastMsg;// 分页拉取逻辑V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];option.getType = V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息option.getTimeBegin = 1640966400; // 从 2022-01-01 00:00:00 开始option.getTimePeriod = 1 * 24 * 60 * 60; // 拉取一整天的消息option.count = 20; // 每页 20 条option.lastMsg = self.lastMsg; // 上次拉取的位置 (每次返回的消息列表的最后一条消息)option.groupID = #your group id#; // 拉取群聊消息__weak typeof(self) weakSelf = self;[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {NSLog(@"success");// 记录下一次拉取的 lastMsgweakSelf.lastMsg = msgs.lastObject;} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];
template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public:using SuccessCallback = std::function<void(const T&)>;using ErrorCallback = std::function<void(int, const V2TIMString&)>;ValueCallback() = default;~ValueCallback() override = default;void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {success_callback_ = std::move(success_callback);error_callback_ = std::move(error_callback);}void OnSuccess(const T& value) override {if (success_callback_) {success_callback_(value);}}void OnError(int error_code, const V2TIMString& error_message) override {if (error_callback_) {error_callback_(error_code, error_message);}}private:SuccessCallback success_callback_;ErrorCallback error_callback_;};// 定义变量,记录每次拉取的游标V2TIMMessage lastMsg;// 分页拉取逻辑V2TIMMessageListGetOption option;option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息option.getTimeBegin = 1640966400; // 从 2022-01-01 00:00:00 开始option.getTimePeriod = 1 * 24 * 60 * 60; // 拉取一整天的消息option.count = 20; // 每页 20 条option.lastMsg = 首次拉取 ? nullptr : &lastMsg; // 上次拉取的位置(每次返回的消息列表的最后一条消息)option.groupID = "your group id"; // 拉取群聊消息auto callback = new ValueCallback<V2TIMMessageVector>{};callback->SetCallback([=](const V2TIMMessageVector& messageList) mutable {std::cout << "success" << std::endl;// 记录下一次拉取的 lastMsglastMsg = messageList[messageList.Size() - 1];delete callback;},[=](int error_code, const V2TIMString& error_message) {std::cout << "error" << std::endl;delete callback;});V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);
getType
来实现仅拉取本地消息:getType
取值为 V2TIM_GET_LOCAL_OLDER_MSG
时,表示往时间更旧的方向,拉取本地存储的消息。getType
取值为 V2TIM_GET_LOCAL_NEWER_MSG
时,表示往时间更新的方向,拉取本地存储的消息。V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_LOCAL_OLDER_MSG); // 拉取本地的更老的消息option.setLastMsg(null); // 设置从最新的消息开始拉取option.setCount(20); // 拉取 20 条消息option.setUserID(#you user id#); // 拉取单聊消息V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {Log.i("imsdk", "success");}@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);}});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];option.getType = V2TIM_GET_LOCAL_OLDER_MSG; // 拉取本地的更老的消息option.lastMsg = nil; // 设置从最新的消息开始拉取option.count = 20; // 拉取 20 条消息option.userID = #your user id#; // 拉取单聊消息[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {NSLog(@"success");} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];
template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public:using SuccessCallback = std::function<void(const T&)>;using ErrorCallback = std::function<void(int, const V2TIMString&)>;ValueCallback() = default;~ValueCallback() override = default;void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {success_callback_ = std::move(success_callback);error_callback_ = std::move(error_callback);}void OnSuccess(const T& value) override {if (success_callback_) {success_callback_(value);}}void OnError(int error_code, const V2TIMString& error_message) override {if (error_callback_) {error_callback_(error_code, error_message);}}private:SuccessCallback success_callback_;ErrorCallback error_callback_;};V2TIMMessageListGetOption option;option.getType = V2TIMMessageGetType::V2TIM_GET_LOCAL_OLDER_MSG; // 拉取本地的更老的消息option.count = 20; // 拉取 20 条消息option.userID = "you user id"; // 拉取单聊消息auto callback = new ValueCallback<V2TIMMessageVector>{};callback->SetCallback([=](const V2TIMMessageVector& messageList) mutable {std::cout << "success" << std::endl;delete callback;},[=](int error_code, const V2TIMString& error_message) {std::cout << "error" << std::endl;delete callback;});V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);
messageTypeList
为空时,表示拉取所有类型的消息。// 拉取图片消息、文本消息ArrayList<Integer> messageTypeList = new ArrayList<Integer>();messageTypeList.add(V2TIM_ELEM_TYPE_IMAGE);messageTypeList.add(V2TIM_ELEM_TYPE_TEXT);V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取云端的更老的消息option.setCount(20);option.setMessageTypeList(messageTypeList);option.setGroupID("you group id");V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {Log.i("imsdk", "success");}@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);}});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];option.getType = V2TIM_GET_CLOUD_OLDER_MSG;// 拉取图片消息、文本消息option.messageTypeList = @[@(V2TIM_ELEM_TYPE_IMAGE), @(V2TIM_ELEM_TYPE_TEXT)];option.count = 20;option.groupID = @"your group id";[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {NSLog(@"success");} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];
template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public:using SuccessCallback = std::function<void(const T&)>;using ErrorCallback = std::function<void(int, const V2TIMString&)>;ValueCallback() = default;~ValueCallback() override = default;void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {success_callback_ = std::move(success_callback);error_callback_ = std::move(error_callback);}void OnSuccess(const T& value) override {if (success_callback_) {success_callback_(value);}}void OnError(int error_code, const V2TIMString& error_message) override {if (error_callback_) {error_callback_(error_code, error_message);}}private:SuccessCallback success_callback_;ErrorCallback error_callback_;};V2TIMMessageListGetOption option;option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息option.count = 20; // 拉取 20 条消息option.messageTypeList.PushBack(V2TIMElemType::V2TIM_ELEM_TYPE_IMAGE); // 拉取图片消息option.messageTypeList.PushBack(V2TIMElemType::V2TIM_ELEM_TYPE_TEXT); // 拉取文本消息option.userID = "you group id"; // 拉取群聊消息auto callback = new ValueCallback<V2TIMMessageVector>{};callback->SetCallback([=](const V2TIMMessageVector& messageList) mutable {std::cout << "success" << std::endl;delete callback;},[=](int error_code, const V2TIMString& error_message) {std::cout << "error" << std::endl;delete callback;});V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);
ArrayList<Long> sequenceList = new ArrayList<>();sequenceList.add(1L);sequenceList.add(3L);sequenceList.add(5L);sequenceList.add(9L);V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();option.setGroupID("your groupID");option.setMessageSeqList(sequenceList);option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG;);V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {}@Overridepublic void onError(int code, String desc) {}});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];option.getType = V2TIM_GET_CLOUD_OLDER_MSG;option.groupID = @"your groupID";option.messageSeqList = @[@(1), @(3), @(5), @(9)];[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {} fail:^(int code, NSString *desc) {}];
template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public:using SuccessCallback = std::function<void(const T&)>;using ErrorCallback = std::function<void(int, const V2TIMString&)>;ValueCallback() = default;~ValueCallback() override = default;void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {success_callback_ = std::move(success_callback);error_callback_ = std::move(error_callback);}void OnSuccess(const T& value) override {if (success_callback_) {success_callback_(value);}}void OnError(int error_code, const V2TIMString& error_message) override {if (error_callback_) {error_callback_(error_code, error_message);}}private:SuccessCallback success_callback_;ErrorCallback error_callback_;};V2TIMUInt64Vector sequence_list;sequence_list.PushBack(1);sequence_list.PushBack(3);sequence_list.PushBack(5);sequence_list.PushBack(9);V2TIMMessageListGetOption option;option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG;option.messageSeqList = sequence_list;option.groupID = "your group id";auto callback = new ValueCallback<V2TIMMessageVector>{};callback->SetCallback([=](const V2TIMMessageVector& messageList) {std::cout << "success" << std::endl;delete callback;},[=](int error_code, const V2TIMString& error_message) {std::cout << "error" << std::endl;delete callback;});V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);
sequence
,并使用高级接口 getHistoryMessageList
来拉取。// 获取群 @ 消息对应的的 sequencelong atSequence = 1081;// 拉取群 @ 消息及之前的消息V2TIMMessageListGetOption beforeOption = new V2TIMMessageListGetOption();beforeOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取比群 @ 消息更早的消息beforeOption.setCount(20); // 拉取 20 条beforeOption.setLastMsgSeq(atSequence); // 从群 @ 消息开始拉取,包括群 @ 消息beforeOption.setGroupID(#you group id#); // 拉取群聊消息V2TIMManager.getMessageManager().getHistoryMessageList(beforeOption, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {、// 返回的消息列表中包括群 @ 消息Log.i("imsdk", "success");}@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);}});// 拉取群 @ 消息之后的消息V2TIMMessageListGetOption afterOption = new V2TIMMessageListGetOption();afterOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_NEWER_MSG); // 拉取比群 @ 消息更晚的消息afterOption.setCount(20); // 拉取 20 条afterOption.setLastMsgSeq(atSequence + 1); // 从群 @ 消息的后一条消息开始拉取,不包括群 @ 消息afterOption.setGroupID(#you group id#); // 拉取群聊消息V2TIMManager.getMessageManager().getHistoryMessageList(afterOption, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {// 返回的消息列表中不包括群 @ 消息Log.i("imsdk", "success");}@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);}});
// 获取群 @ 消息对应的的 sequenceNSInteger atSequence = 1081;// 拉取群 @ 消息及之前的消息V2TIMMessageListGetOption *beforeOption = [[V2TIMMessageListGetOption alloc] init];beforeOption.getType = V2TIM_GET_CLOUD_OLDER_MSG; // 拉取比群 @ 消息更早的消息beforeOption.count = 20; // 拉取 20 条beforeOption.lastMsgSeq = atSequence; // 从群 @ 消息开始拉取, 包括群 @ 消息beforeOption.groupID = #your group id#; // 拉取群聊消息[V2TIMManager.sharedInstance getHistoryMessageList:beforeOption succ:^(NSArray<V2TIMMessage *> *msgs) {// 返回的消息列表中包括群 @ 消息NSLog(@"success");} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];// 拉取群 @ 消息之后的消息V2TIMMessageListGetOption *afterOption = [[V2TIMMessageListGetOption alloc] init];afterOption.getType = V2TIM_GET_CLOUD_NEWER_MSG; // 拉取比群 @ 消息更晚的消息afterOption.count = 20; // 拉取 20 条afterOption.lastMsgSeq = atSequence + 1; // 从群 @ 消息的后一条消息开始拉取,不包括群 @ 消息afterOption.groupID = #your group id#; // 拉取群聊消息[V2TIMManager.sharedInstance getHistoryMessageList:afterOption succ:^(NSArray<V2TIMMessage *> *msgs) {// 返回的消息列表中不包括群 @ 消息NSLog(@"success");} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];
template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public:using SuccessCallback = std::function<void(const T&)>;using ErrorCallback = std::function<void(int, const V2TIMString&)>;ValueCallback() = default;~ValueCallback() override = default;void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {success_callback_ = std::move(success_callback);error_callback_ = std::move(error_callback);}void OnSuccess(const T& value) override {if (success_callback_) {success_callback_(value);}}void OnError(int error_code, const V2TIMString& error_message) override {if (error_callback_) {error_callback_(error_code, error_message);}}private:SuccessCallback success_callback_;ErrorCallback error_callback_;};// 获取群 @ 消息对应的的 sequenceuint64_t atSequence = 1081;// 拉取群 @ 消息及之前的消息V2TIMMessageListGetOption beforeOption;beforeOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取比群 @ 消息更早的消息beforeOption.count = 20; // 拉取 20 条消息beforeOption.lastMsgSeq = atSequence; // 从群 @ 消息开始拉取,包括群 @ 消息beforeOption.userID = "you group id"; // 拉取群聊消息auto beforeCallback = new ValueCallback<V2TIMMessageVector>{};beforeCallback->SetCallback([=](const V2TIMMessageVector& messageList) mutable {// 返回的消息列表中包括群 @ 消息std::cout << "success" << std::endl;delete beforeCallback;},[=](int error_code, const V2TIMString& error_message) {std::cout << "error" << std::endl;delete beforeCallback;});V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(beforeOption, beforeCallback);// 拉取群 @ 消息及之前的消息V2TIMMessageListGetOption afterOption;afterOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_NEWER_MSG; // 拉取比群 @ 消息更晚的消息afterOption.count = 20; // 拉取 20 条消息afterOption.lastMsgSeq = atSequence + 1; // 从群 @ 消息的后一条消息开始拉取,不包括群 @ 消息afterOption.userID = "you group id"; // 拉取群聊消息auto afterCallback = new ValueCallback<V2TIMMessageVector>{};afterCallback->SetCallback([=](const V2TIMMessageVector& messageList) mutable {// 返回的消息列表中不包括群 @ 消息std::cout << "success" << std::endl;delete afterCallback;},[=](int error_code, const V2TIMString& error_message) {std::cout << "error" << std::endl;delete afterCallback;});V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(afterOption, afterCallback);
V2TIMMessage
对象。点击该消息后,一般需要跳转到该消息对应的位置并展示附近的消息。
此时可以将 lastMsg
设置成该消息对象,并使用高级接口 getHistoryMessageList
拉取前后的消息。// 获取当前的 message 对象V2TIMMessage lastMsg = #搜索到的消息#;// 拉取指定消息之前的消息V2TIMMessageListGetOption beforeOption = new V2TIMMessageListGetOption();beforeOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取比指定消息更早的消息beforeOption.setCount(20); // 拉取 20 条beforeOption.setLastMsg(lastMsg); // 从指定消息开始拉取,不包括该消息beforeOption.setGroupID(#you group id#); // 拉取群聊消息V2TIMManager.getMessageManager().getHistoryMessageList(beforeOption, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {、// 返回的消息列表中不包括 lastMsgLog.i("imsdk", "success");}@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);}});// 拉取指定消息之后的消息V2TIMMessageListGetOption afterOption = new V2TIMMessageListGetOption();afterOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_NEWER_MSG); // 拉取比指定消息更晚的消息afterOption.setCount(20); // 拉取 20 条afterOption.setLastMsg(lastMsg); // 从指定消息开始拉取,不包括该消息afterOption.setGroupID(#you group id#); // 拉取群聊消息V2TIMManager.getMessageManager().getHistoryMessageList(afterOption, new V2TIMValueCallback<List<V2TIMMessage>>() {@Overridepublic void onSuccess(List<V2TIMMessage> v2TIMMessages) {// 返回的消息列表中不包括 lastMsgLog.i("imsdk", "success");}@Overridepublic void onError(int code, String desc) {Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);}});
// 获取当前的 message 对象V2TIMMessage *lastMsg = #搜索后的消息#;// 拉取指定消息之前的消息V2TIMMessageListGetOption *beforeOption = [[V2TIMMessageListGetOption alloc] init];beforeOption.getType = V2TIM_GET_CLOUD_OLDER_MSG; // 拉取比指定消息更早的消息beforeOption.count = 20; // 拉取 20 条beforeOption.lastMsg = lastMsg; // 从指定消息开始拉取, 不包括该消息beforeOption.groupID = #your group id#; // 拉取群聊消息[V2TIMManager.sharedInstance getHistoryMessageList:beforeOption succ:^(NSArray<V2TIMMessage *> *msgs) {// 返回的消息列表中不包括指定消息NSLog(@"success");} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];// 拉取指定消息之后的消息V2TIMMessageListGetOption *afterOption = [[V2TIMMessageListGetOption alloc] init];afterOption.getType = V2TIM_GET_CLOUD_NEWER_MSG; // 拉取比指定消息更晚的消息afterOption.count = 20; // 拉取 20 条afterOption.lastMsg = lastMsg; // 从指定消息开始拉取,不包括该消息afterOption.groupID = #your group id#; // 拉取群聊消息[V2TIMManager.sharedInstance getHistoryMessageList:afterOption succ:^(NSArray<V2TIMMessage *> *msgs) {// 返回的消息列表中不包括指定消息NSLog(@"success");} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];
template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public:using SuccessCallback = std::function<void(const T&)>;using ErrorCallback = std::function<void(int, const V2TIMString&)>;ValueCallback() = default;~ValueCallback() override = default;void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {success_callback_ = std::move(success_callback);error_callback_ = std::move(error_callback);}void OnSuccess(const T& value) override {if (success_callback_) {success_callback_(value);}}void OnError(int error_code, const V2TIMString& error_message) override {if (error_callback_) {error_callback_(error_code, error_message);}}private:SuccessCallback success_callback_;ErrorCallback error_callback_;};// 获取当前的 message 对象V2TIMMessage lastMsg = 搜索到的消息;// 拉取指定消息之前的消息V2TIMMessageListGetOption beforeOption;beforeOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取比指定消息更早的消息beforeOption.count = 20; // 拉取 20 条消息beforeOption.lastMsg = lastMsg; // 从指定消息开始拉取,不包括该消息beforeOption.userID = "you group id"; // 拉取群聊消息auto beforeCallback = new ValueCallback<V2TIMMessageVector>{};beforeCallback->SetCallback([=](const V2TIMMessageVector& messageList) mutable {// 返回的消息列表中不包括 lastMsgstd::cout << "success" << std::endl;delete beforeCallback;},[=](int error_code, const V2TIMString& error_message) {std::cout << "error" << std::endl;delete beforeCallback;});V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(beforeOption, beforeCallback);// 拉取指定消息之后的消息V2TIMMessageListGetOption afterOption;afterOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_NEWER_MSG; // 拉取比指定消息更晚的消息afterOption.count = 20; // 拉取 20 条消息afterOption.lastMsg = lastMsg; // 从指定消息开始拉取,不包括该消息afterOption.userID = "you group id"; // 拉取群聊消息auto afterCallback = new ValueCallback<V2TIMMessageVector>{};afterCallback->SetCallback([=](const V2TIMMessageVector& messageList) mutable {// 返回的消息列表中不包括 lastMsgstd::cout << "success" << std::endl;delete afterCallback;},[=](int error_code, const V2TIMString& error_message) {std::cout << "error" << std::endl;delete afterCallback;});V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(afterOption, afterCallback);
invite/inviteInGroup
时,设置了 onlineUserOnly
为 false
(Android) / NO
(iOS),那么每次信令操作(包括 invite
、cancel
、accept
、reject
、timeout
)都会产生一条自定义消息,该消息会通过 V2TIMAdvancedMsgListener
的 onRecvNewMessage
回调抛给用户,也可以通过历史消息拉取。/*** 获取信令信息** 如果 invite 设置 onlineUserOnly 为 false,每次信令操作(包括 invite、cancel、accept、reject、timeout)都会产生一条自定义消息,* 该消息会通过 V2TIMAdvancedMsgListener -> onRecvNewMessage 抛给用户,用户也可以通过历史消息拉取,如果需要根据信令信息做自定义化文本展示,可以调用下面接口获取信令信息。** @param msg 消息对象* @return V2TIMSignalingInfo 信令信息,如果为 null,则 msg 不是一条信令消息。*/public abstract V2TIMSignalingInfo getSignalingInfo(V2TIMMessage msg);
/*** 获取信令信息** 如果 invite 设置 onlineUserOnly 为 NO,每次信令操作(包括 invite、cancel、accept、reject、timeout)都会产生一条自定义消息,该消息会通过 V2TIMAdvancedMsgListener -> onRecvNewMessage 抛给用户,用户也可以通过历史消息拉取,如果需要根据信令信息做自定义化文本展示,可以调用下面接口获取信令信息。** @param msg 消息对象* @return V2TIMSignalingInfo 信令信息,如果为 nil,则 msg 不是一条信令消息。*/- (V2TIMSignalingInfo *)getSignallingInfo:(V2TIMMessage *)msg;
/*** 获取信令信息** 如果 Invite 设置 onlineUserOnly 为 false,每次信令操作(包括* Invite、Cancel、Accept、Reject、Timeout)都会产生一条自定义消息, 该消息会通过* V2TIMAdvancedMsgListener -> onRecvNewMessage* 抛给用户,用户也可以通过历史消息拉取,如果需要根据信令信息做自定义化文本展示,可以调用下面接口获取信令信息。** @param msg 消息对象* @return V2TIMSignalingInfo 信令信息,如果 V2TIMSignalingInfo::inviteID 为空字符串,则 msg 不是一条信令消息。*/virtual V2TIMSignalingInfo GetSignalingInfo(const V2TIMMessage& msg) = 0;
/// 信令消息对应的自定义文本public String getCallSignalingContentWithMessage(V2TIMMessage message) {if (message == null) {Log.e(TAG, " invalid param ");return "";}V2TIMSignalingInfo signalingInfo = V2TIMManager.getSignalingManager().getSignalingInfo(message);if (signalingInfo == null) {Log.e(TAG, " signalingInfo is null ");return "";}String content = "";Gson gson = new Gson();Object businessIdObj = null;String businessId = null;try {HashMap signalDataMap = gson.fromJson(signalingInfo.getData(), HashMap.class);if (signalDataMap != null) {businessIdObj = signalDataMap.get(TUIConstants.Message.CUSTOM_BUSINESS_ID_KEY);} else {Log.e(TAG, " signalDataMap is null ");return "";}} catch (JsonSyntaxException e) {Log.e(TAG, " get signalingInfoCustomJsonMap error ");}if (businessIdObj instanceof String) {businessId = (String) businessIdObj;}if (TextUtils.equals(businessId, "av_call")) {if (signalingInfo.getActionType() == V2TIMSignalingInfo.SIGNALING_ACTION_TYPE_INVITE) {// 邀请通话content = "@邀请通话";} else if (signalingInfo.getActionType() == V2TIMSignalingInfo.SIGNALING_ACTION_TYPE_ACCEPT_INVITE) {// 同意邀请content = "@同意通话";} else {// 其他// ...}}return content;}
/// 信令消息对应的自定义文本+ (NSString *)getCallSignalingContentWithMessage:(V2TIMMessage *)message{V2TIMSignalingInfo *info = [[V2TIMManager sharedInstance] getSignallingInfo:message];if (!info) {return nil;}// 解析透传的data字段NSError *err = nil;NSDictionary *param = nil;if (info.data != nil) {param = [NSJSONSerialization JSONObjectWithData:[info.data dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&err];}if (!param || ![param isKindOfClass:[NSDictionary class]]) {return nil;}// 判断业务类型NSArray *allKeys = param.allKeys;if (![allKeys containsObject:@"businessID"]) {return nil;}NSString *businessId = [param objectForKey:@"businessID"];// 判断是否为音视频通话信令NSString *content = nil;if ([businessId isEqualToString:@"av_call"]) {if (info.actionType == SignalingActionType_Invite) {// 邀请通话content = @"邀请通话";} else if (info.actionType == SignalingActionType_Accept_Invite) {// 同意邀请content = @"同意通话";} else {// 其他// ...}}return content;}
信令消息对应的自定义文本std::string GetCallSignalingContentWithMessage(const V2TIMMessage& message) {V2TIMSignalingInfo signalingInfo =V2TIMManager::GetInstance()->GetSignalingManager()->GetSignalingInfo(message);if (signalingInfo.inviteID.Empty()) {// 如果 V2TIMSignalingInfo::inviteID 为空,则 message 不是一条信令消息return {};}// 解析透传的 data 字段,使用开源库 RapidJSON :https://github.com/Tencent/rapidjson/rapidjson::Document document;document.Parse(signalingInfo.data.CString(), signalingInfo.data.Size());if (!document.HasMember("businessId") || !document["businessId"].IsString()) {return {};}const char* businessId = document["businessId"].GetString();// 判断是否为音视频通话信令std::string content;if (businessId == "av_call") {if (signalingInfo.actionType == V2TIMSignalingActionType::SignalingActionType_Invite) {// 邀请通话content = u8"邀请通话";} else if (signalingInfo.actionType == 2TIMSignalingActionType::SignalingActionType_Accept_Invite) {// 同意邀请content = u8"同意通话";} else {// 其他 ...}}return content;}
getType
设置成拉云端历史消息,且拉取 count 条消息时,SDK 会从云端拉取 count 条消息。onlineUserOnly
为 YES/true
。getType
设置成拉云端历史消息,且拉取 count 条消息时,SDK 会做如下操作:count
。
本页内容是否解决了您的问题?