package com.netease.nim.demo.event;
import android.os.Handler;
import com.netease.nim.demo.DemoCache;
import com.netease.nim.demo.common.infra.Handlers;
import com.netease.nim.demo.config.preference.UserPreferences;
import com.netease.nim.uikit.cache.FriendDataCache;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.event.EventSubscribeService;
import com.netease.nimlib.sdk.event.model.EventSubscribeRequest;
import com.netease.nimlib.sdk.event.model.NimOnlineStateEvent;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import java.util.List;
/**
* Created by chenkang on 2017/4/26.
*/
public class OnlineStateEventSubscribe {
// 订阅好友并同步当前在线状态的频率控制30 s,对同一账号连续2次订阅时间间隔在30s 以上
private static final long SUBS_FREQ = 30 * 1000;
private static long lastSubsTime = -1;
private static boolean initSubsFinished = true;
private static boolean waitInitSubs = false;
// 订阅有效期 1天,单位秒
public static final long SUBSCRIBE_EXPIRY = 60 * 60 * 24;
public static void initSubscribes() {
// 正在进行
if (waitInitSubs || !initSubsFinished) {
return;
}
final long timeInterval = getSubsTimeInterval();
if (timeInterval <= SUBS_FREQ) {
waitInitSubs = true;
long delay = SUBS_FREQ - timeInterval + 1000;
LogUtil.ui("time interval short than 30 and init subscribe delay " + delay);
Handler handler = Handlers.sharedHandler(DemoCache.getContext());
handler.postDelayed(new Runnable() {
@Override
public void run() {
// 延迟订阅
waitInitSubs = false;
initSubscribes();
}
}, delay);
return;
}
initSubsFinished = false;
// 重置事件、订阅关系缓存
OnlineStateEventCache.resetCache();
// 重置订阅有效期管理
SubscribeExpiryManager.reset();
// 订阅好友、最近联系人中非好友的在线状态事件
subscribeAllOnlineStateEvent();
}
private static long getSubsTimeInterval() {
if (lastSubsTime < 0) {
lastSubsTime = UserPreferences.getOnlineStateSubsTime();
}
return System.currentTimeMillis() - lastSubsTime;
}
private static void updateLastSubsTime() {
lastSubsTime = System.currentTimeMillis();
UserPreferences.setOnlineStateSubsTime(lastSubsTime);
}
/**
* 订阅好友、最近联系人的在线状态事件
*/
public static void subscribeAllOnlineStateEvent() {
final List<String> accounts = FriendDataCache.getInstance().getMyFriendAccounts();
NIMClient.getService(MsgService.class).queryRecentContacts().setCallback(new RequestCallbackWrapper<List<RecentContact>>() {
@Override
public void onResult(int code, List<RecentContact> result, Throwable exception) {
if (result != null && !result.isEmpty()) {
for (RecentContact recentContact : result) {
if (recentContact.getSessionType() == SessionTypeEnum.Team) {
continue;
}
String id = recentContact.getContactId();
if (!FriendDataCache.getInstance().isMyFriend(id)) {
accounts.add(id);
}
}
}
initSubsFinished = true;
if (accounts.isEmpty()) {
return;
}
LogUtil.ui("subscribe friends and recentContact " + accounts);
subscribeOnlineStateEvent(accounts, SUBSCRIBE_EXPIRY);
}
});
}
/**
* 订阅指定账号的在线状态事件
*
* @param accounts 目标账号
*/
public static void subscribeOnlineStateEvent(final List<String> accounts, long expiry) {
if (waitInitSubs || !initSubsFinished || accounts == null || accounts.isEmpty()) {
return;
}
LogUtil.ui("do subscribe onlineStateEvent accounts = " + accounts);
EventSubscribeRequest eventSubscribeRequest = new EventSubscribeRequest();
eventSubscribeRequest.setEventType(NimOnlineStateEvent.EVENT_TYPE);
eventSubscribeRequest.setPublishers(accounts);
eventSubscribeRequest.setExpiry(expiry);
eventSubscribeRequest.setSyncCurrentValue(true);
OnlineStateEventCache.addSubsAccounts(accounts);
updateLastSubsTime();
NIMClient.getService(EventSubscribeService.class).subscribeEvent(eventSubscribeRequest).setCallback(new RequestCallbackWrapper<List<String>>() {
@Override
public void onResult(int code, List<String> result, Throwable exception) {
if (code == ResponseCode.RES_SUCCESS) {
// 可能网络比较慢,所以再更新一把时间
updateLastSubsTime();
SubscribeExpiryManager.subscribeSuccess();
if (result != null) {
// 部分订阅失败的账号。。。
OnlineStateEventCache.removeSubsAccounts(result);
}
} else {
OnlineStateEventCache.removeSubsAccounts(accounts);
}
}
});
}
/**
* 取消订阅指定账号的在线状态事件
*
* @param accounts 目标账号
*/
public static void unSubscribeOnlineStateEvent(List<String> accounts) {
if (accounts == null || accounts.isEmpty()) {
return;
}
LogUtil.ui("unSubscribe OnlineStateEvent " + accounts);
OnlineStateEventCache.removeSubsAccounts(accounts);
OnlineStateEventCache.removeOnlineState(accounts);
EventSubscribeRequest eventSubscribeRequest = new EventSubscribeRequest();
eventSubscribeRequest.setEventType(NimOnlineStateEvent.EVENT_TYPE);
eventSubscribeRequest.setPublishers(accounts);
NIMClient.getService(EventSubscribeService.class).unSubscribeEvent(eventSubscribeRequest);
}
/**
* 订阅有效期管理,快到期时重新订阅
*/
private static class SubscribeExpiryManager {
private static boolean firstSubs = true;
public static void reset() {
LogUtil.ui("time task reset");
Handler handler = Handlers.sharedHandler(DemoCache.getContext());
handler.removeCallbacks(runnable);
firstSubs = true;
}
private static Runnable runnable = new Runnable() {
@Override
public void run() {
// 如果不是好友并且不在最近联系人里面,则不会续订
LogUtil.ui("time task subscribe again");
initSubscribes();
}
};
private static void startTimeTask() {
LogUtil.ui("time task start");
Handler handler = Handlers.sharedHandler(DemoCache.getContext());
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, SUBSCRIBE_EXPIRY * 1000);
}
public static void subscribeSuccess() {
if (firstSubs) {
firstSubs = false;
startTimeTask();
}
}
}
}