278 lines
10 KiB
Java
278 lines
10 KiB
Java
package com.zchd.zim;
|
||
|
||
import com.zchd.base.BaseService;
|
||
import com.zchd.base.util.Kv;
|
||
import com.zchd.zim.bean.ImBean;
|
||
import com.zchd.zim.bean.SubscribeBean;
|
||
import com.zchd.zim.entity.AppInfo;
|
||
import com.zchd.zim.entity.ChannelUser;
|
||
import com.zchd.zim.entity.ImUser;
|
||
import net.tccn.zhub.Lock;
|
||
import net.tccn.zhub.RpcResult;
|
||
import org.redkale.convert.json.JsonConvert;
|
||
import org.redkale.net.http.RestMapping;
|
||
import org.redkale.net.http.RestService;
|
||
import org.redkale.service.RetResult;
|
||
import org.redkale.source.ColumnValue;
|
||
import org.redkale.source.FilterBean;
|
||
import org.redkale.source.FilterNode;
|
||
import org.redkale.source.Flipper;
|
||
import org.redkale.util.AnyValue;
|
||
import org.redkale.util.Comment;
|
||
import org.redkale.util.TypeToken;
|
||
import org.redkale.util.Utility;
|
||
import org.redkalex.cache.redis.MyRedisCacheSource;
|
||
|
||
import javax.annotation.Resource;
|
||
import java.io.Serializable;
|
||
import java.util.List;
|
||
import java.util.concurrent.CompletableFuture;
|
||
|
||
|
||
@RestService(name = "im_account", comment = "账号服务")
|
||
public class ImAccountService extends BaseService {
|
||
|
||
|
||
@Resource(name = "str_cache")
|
||
protected MyRedisCacheSource<String> strCache;
|
||
@Resource
|
||
protected ImMessageMonitor messageMonitor;
|
||
/*@Resource
|
||
protected ImAccountService accountService;*/
|
||
|
||
@Override
|
||
public void init(AnyValue config) {
|
||
|
||
CompletableFuture.runAsync(() -> {
|
||
List<Serializable> list = zimSource.queryColumnList("userid", ImUser.class, new Flipper(1, "userid DESC"), (FilterBean) null);
|
||
int userid = 10000;
|
||
if (!list.isEmpty()) {
|
||
userid = Kv.toAs(list.get(0), int.class);
|
||
}
|
||
intCache.set("im:max-userid", userid);
|
||
});
|
||
|
||
// 游戏用户注册
|
||
zhub.rpcSubscribe("im:account-register", new TypeToken<ImBean>() {
|
||
}, r -> {
|
||
ImBean bean = r.getValue();
|
||
RetResult<Kv> result = register(bean);
|
||
if (!result.isSuccess()) {
|
||
return r.retError(result.getRetinfo());
|
||
}
|
||
return r.render(result.getResult());
|
||
});
|
||
|
||
// 获取游戏用户 IM-TOKEN
|
||
zhub.rpcSubscribe("im:account-token", new TypeToken<ImBean>() {
|
||
}, r -> {
|
||
ImBean bean = r.getValue();
|
||
RetResult<Kv> result = getToken(bean);
|
||
if (!result.isSuccess()) {
|
||
return r.retError(result.getRetinfo());
|
||
}
|
||
return r.render(result.getResult());
|
||
});
|
||
|
||
// 为用户新增订阅频道
|
||
zhub.rpcSubscribe("im:subscribe", new TypeToken<SubscribeBean>() {
|
||
}, r -> {
|
||
SubscribeBean bean = r.getValue();
|
||
RetResult result = subscribe(bean);
|
||
return r.render(result.getResult());
|
||
});
|
||
|
||
// 为用户取消订阅频道
|
||
zhub.rpcSubscribe("im:unsubscribe", new TypeToken<SubscribeBean>() {
|
||
}, r -> {
|
||
SubscribeBean bean = r.getValue();
|
||
RetResult result = unsubscribe(bean);
|
||
return r.render(result.getResult());
|
||
});
|
||
|
||
// 禁言 todo: ①禁言时长 ②禁言指定频道
|
||
zhub.rpcSubscribe("im:banned-talk", new TypeToken<SubscribeBean>() {
|
||
}, r -> {
|
||
SubscribeBean bean = r.getValue();
|
||
String imtoken = bean.getImtoken();
|
||
|
||
ImUser user = currentImUser(imtoken);
|
||
int userid = user.getUserid();
|
||
zimSource.updateColumn(ImUser.class, userid, ColumnValue.create("status", ImUser.STATUS_FREEZE_ACTIVE));
|
||
intCache.setBit("im:banned-talk", userid, true);
|
||
return r.render();
|
||
});
|
||
|
||
// 取消禁言
|
||
zhub.rpcSubscribe("im:unbanned-talk", new TypeToken<SubscribeBean>() {
|
||
}, r -> {
|
||
SubscribeBean bean = r.getValue();
|
||
String imtoken = bean.getImtoken();
|
||
|
||
ImUser user = currentImUser(imtoken);
|
||
int userid = user.getUserid();
|
||
zimSource.updateColumn(ImUser.class, userid, ColumnValue.create("status", 10));
|
||
intCache.setBit("im:banned-talk", userid, false);
|
||
return r.render();
|
||
});
|
||
}
|
||
|
||
|
||
@Comment("获取当前用户ID")
|
||
public ImUser currentImUser(String token) {
|
||
|
||
ImUser user = strCache.hget("im:user-token", token, new TypeToken<ImUser>() {
|
||
}.getType());
|
||
if (user == null) {
|
||
user = zimSource.find(ImUser.class, FilterNode.create("imtoken", token));
|
||
strCache.hset("im:user-token", token, JsonConvert.root(), user);
|
||
}
|
||
return user;
|
||
}
|
||
|
||
public ImUser getImUser(ImBean bean) {
|
||
return zimSource.find(ImUser.class, FilterNode.create("guserid", bean.getGuserid()).and("appid", bean.getAppid()));
|
||
}
|
||
|
||
/*@Comment("获取当前用户ID")
|
||
public int currentImUserId(String token) {
|
||
return currentImUser(token).getUserid();
|
||
}*/
|
||
|
||
|
||
/*
|
||
Url: http://127.0.0.1:8021/im_account/register
|
||
Body: {"appid":"krlq07sx","appsecret":"79eb45ebdabc4d90bfb69949b8fd767e","guserid":"S_C_01_R0001","gender":10,"nickname":"M","face":"http://xxxxxx/xxx"}
|
||
Body: {"appid":"krlq07sx","appsecret":"79eb45ebdabc4d90bfb69949b8fd767e","guserid":"S_C_01_R0002","gender":20,"nickname":"V","face":"http://xxxxxx/xxx"}
|
||
*/
|
||
@RestMapping(name = "register", auth = false, comment = "获取当前登录用户ID")
|
||
public RetResult<Kv> register(ImBean bean) {
|
||
RetResult<Kv> result = check(bean);
|
||
if (!result.isSuccess()) {
|
||
return result;
|
||
}
|
||
|
||
// 检查有无当前用户
|
||
FilterNode node = FilterNode.create("guserid", bean.getGuserid()).and("appid", bean.getAppid());
|
||
ImUser user = zimSource.find(ImUser.class, node);
|
||
|
||
if (user == null) {
|
||
user = ImUser.buildImUser(bean.getGuserid(), bean.getAppid());
|
||
int userid = (int) intCache.incr("im:max-userid");
|
||
user.setUserid(userid);
|
||
|
||
user.setImtoken(Utility.uuid()); // 生成IM-TOKEN
|
||
zimSource.insert(user);
|
||
|
||
// intCache.set("im:account-user-token:" + user.getImtoken(), userid);
|
||
strCache.hset("im:user-token", user.getImtoken(), JsonConvert.root(), user);
|
||
|
||
}
|
||
|
||
return RetResult.success(Kv.of("token", user.getImtoken()));
|
||
}
|
||
|
||
/*
|
||
Url: http://127.0.0.1:8021/im_account/register
|
||
Body: {"appid":"krlq07sx","appsecret":"79eb45ebdabc4d90bfb69949b8fd767e","guserid":"S_C_01_R0001"}
|
||
Body: {"appid":"krlq07sx","appsecret":"79eb45ebdabc4d90bfb69949b8fd767e","guserid":"S_C_01_R0002"}
|
||
*/
|
||
@RestMapping(name = "get_token", auth = false, comment = "获取平台识别Token")
|
||
public RetResult<Kv> getToken(ImBean bean) {
|
||
RetResult<Kv> result = check(bean);
|
||
if (!result.isSuccess()) {
|
||
return result;
|
||
}
|
||
|
||
FilterNode node = FilterNode.create("appid", bean.getAppid()).and("guserid", bean.getGuserid());
|
||
Serializable imtoken = zimSource.findColumn(ImUser.class, "imtoken", node);
|
||
|
||
return RetResult.success(Kv.of("token", imtoken));
|
||
}
|
||
|
||
/*
|
||
Url: http://127.0.0.1:8021/im_app/subscribe
|
||
Body: {"imtoken":"krlq07sxS_C_01_R00011627473704040","channeltype":"Word","channelvalue":"W_C_01_001"}
|
||
Body: {"imtoken":"krlq07sxS_C_01_R00021627474715105","channeltype":"Word","channelvalue":"W_C_01_001"}
|
||
*/
|
||
@RestMapping(name = "subscribe", auth = false, comment = "给用户订阅频道信息")
|
||
public RetResult subscribe(SubscribeBean bean) {
|
||
ImUser user = currentImUser(bean.getImtoken());
|
||
int userid = user.getUserid();
|
||
Lock lock = zhub.lock("im:channel-create:" + userid, 500);
|
||
try {
|
||
// 添加数据库订阅关系
|
||
FilterNode node1 = FilterNode.create("appid", user.getAppid())
|
||
.and("channeltype", bean.getChanneltype())
|
||
.and("channelvalue", bean.getChannelvalue())
|
||
.and("userid", userid);
|
||
if (!zimSource.exists(ChannelUser.class, node1)) {
|
||
ChannelUser record = ChannelUser.buildChannelUser(userid, user.getAppid(), bean);
|
||
zimSource.insert(record);
|
||
|
||
// 确保写入库后,再发送订阅事件
|
||
messageMonitor.subscribeChannel(userid, record.buildChannelid(), true);
|
||
}
|
||
} finally {
|
||
lock.unLock();
|
||
}
|
||
return RET_SUCCESS;
|
||
}
|
||
|
||
|
||
/*
|
||
Url: http://127.0.0.1:8021/im_app/unsubscribe
|
||
Body: {"imtoken":"krlq07sxS_C_01_R00011627473704040","channeltype":"Word","channelvalue":"W_C_01_001"}
|
||
Body: {"imtoken":"krlq07sxS_C_01_R00021627474715105","channeltype":"Word","channelvalue":"W_C_01_001"}
|
||
*/
|
||
@RestMapping(name = "unsubscribe", auth = false, comment = "取消频道订阅")
|
||
public RetResult unsubscribe(SubscribeBean bean) {
|
||
ImUser user = currentImUser(bean.getImtoken());
|
||
int userid = user.getUserid();
|
||
|
||
|
||
String channelid = user.getAppid() + "-" + bean.getChanneltype() + "-" + bean.getChannelvalue();
|
||
messageMonitor.subscribeChannel(userid, channelid, false);
|
||
|
||
// 删除数据库订阅关系
|
||
FilterNode node1 = FilterNode.create("appid", user.getAppid())
|
||
.and("channeltype", bean.getChanneltype())
|
||
.and("channelvalue", bean.getChannelvalue())
|
||
.and("userid", userid);
|
||
zimSource.delete(ChannelUser.class, node1);
|
||
return RET_SUCCESS;
|
||
}
|
||
|
||
@Comment("平台安全校验")
|
||
public RetResult check(ImBean bean) {
|
||
FilterNode node = FilterNode.create("appid", bean.getAppid()).and("appsecret", bean.getAppsecret()).and("status", 10);
|
||
if (!zimSource.exists(AppInfo.class, node)) {
|
||
return retError("平台信息校验失败");
|
||
}
|
||
return RET_SUCCESS;
|
||
}
|
||
|
||
|
||
// ---------------------------------- 测试 ----------------------------------
|
||
|
||
@RestMapping(name = "test_account_register", auth = false, comment = "rpc测试")
|
||
public RpcResult testAccountRegister(ImBean bean) {
|
||
return zhub.rpc("im:account-register", bean);
|
||
}
|
||
|
||
@RestMapping(name = "test_account_token", auth = false, comment = "rpc测试")
|
||
public RpcResult testAccountToken(ImBean bean) {
|
||
return zhub.rpc("im:account-token", bean);
|
||
}
|
||
|
||
@RestMapping(name = "test_subscribe", auth = false, comment = "rpc测试")
|
||
public RpcResult testSubscribe(SubscribeBean bean) {
|
||
return zhub.rpc("im:subscribe", bean);
|
||
}
|
||
|
||
@RestMapping(name = "test_unsubscribe", auth = false, comment = "rpc测试")
|
||
public RpcResult testUnsubscribe(SubscribeBean bean) {
|
||
return zhub.rpc("im:unsubscribe", bean);
|
||
}
|
||
}
|