作者 crossoverJie

:sparkles: Introducing new features.新增拒绝重复登录

... ... @@ -50,7 +50,9 @@ public class CIMClient {
private RouteRequest routeRequest ;
@PostConstruct
public void start() throws Exception {
public void start() {
try {
//登录 + 获取可以使用的服务器 ip+port
CIMServerResVO.ServerInfo cimServer = userLogin();
... ... @@ -59,6 +61,11 @@ public class CIMClient {
//向服务端注册
loginCIMServer();
}catch (Exception e){
LOGGER.error("Exception",e);
}
}
/**
... ...
... ... @@ -7,6 +7,7 @@ import com.crossoverjie.cim.client.vo.req.GroupReqVO;
import com.crossoverjie.cim.client.vo.req.LoginReqVO;
import com.crossoverjie.cim.client.vo.res.CIMServerResVO;
import com.crossoverjie.cim.common.enums.StatusEnum;
import com.crossoverjie.cim.common.exception.CIMException;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -78,6 +79,12 @@ public class RouteRequestImpl implements RouteRequest {
String json = response.body().string();
CIMServerResVO cimServerResVO = JSON.parseObject(json, CIMServerResVO.class);
//重复登录
if (cimServerResVO.getCode().equals(StatusEnum.REPEAT_LOGIN.getCode())){
throw new CIMException(StatusEnum.REPEAT_LOGIN) ;
}
if (!cimServerResVO.getCode().equals(StatusEnum.SUCCESS.getCode())){
throw new RuntimeException("route server exception code=" + cimServerResVO.getCode()) ;
}
... ...
... ... @@ -11,7 +11,7 @@ logging.level.root=info
# 群发消息
cim.group.route.request.url=http://45.78.28.220:8083/groupRoute
# 获取服务器ip+port
# 登录并获取服务器ip+port
cim.server.route.request.url=http://45.78.28.220:8083/login
# 客户端唯一ID
... ...
... ... @@ -14,8 +14,8 @@ public enum StatusEnum {
/** 失败 */
FAIL("4000", "失败"),
/** 重复请求 */
REPEAT_REQUEST("5000", "重复请求"),
/** 重复登录 */
REPEAT_LOGIN("5000", "重复登录"),
/** 请求限流 */
REQUEST_LIMIT("6000", "请求限流"),
... ...
package com.crossoverjie.cim.common.exception;
import com.crossoverjie.cim.common.enums.StatusEnum;
/**
* Function:
*
* @author crossoverJie
* Date: 2018/8/25 15:26
* @since JDK 1.8
*/
public class CIMException extends GenericException {
public CIMException(String errorCode, String errorMessage) {
super(errorMessage);
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
public CIMException(Exception e, String errorCode, String errorMessage) {
super(e, errorMessage);
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
public CIMException(String message) {
super(message);
this.errorMessage = message;
}
public CIMException(StatusEnum statusEnum) {
super(statusEnum.getMessage());
this.errorMessage = statusEnum.message();
this.errorCode = statusEnum.getCode();
}
public CIMException(StatusEnum statusEnum, String message) {
super(message);
this.errorMessage = message;
this.errorCode = statusEnum.getCode();
}
public CIMException(Exception oriEx) {
super(oriEx);
}
public CIMException(Throwable oriEx) {
super(oriEx);
}
public CIMException(String message, Exception oriEx) {
super(message, oriEx);
this.errorMessage = message;
}
public CIMException(String message, Throwable oriEx) {
super(message, oriEx);
this.errorMessage = message;
}
public static boolean isResetByPeer(String msg) {
if ("Connection reset by peer".equals(msg)) {
return true;
}
return false;
}
}
... ...
package com.crossoverjie.cim.common.exception;
import java.io.Serializable;
/**
* Function:
*
* @author crossoverJie
* Date: 2018/8/25 15:27
* @since JDK 1.8
*/
public class GenericException extends RuntimeException implements Serializable {
private static final long serialVersionUID = 1L;
String errorCode;
String errorMessage;
public GenericException() {
}
public GenericException(String message) {
super(message);
}
public GenericException(Exception oriEx) {
super(oriEx);
}
public GenericException(Exception oriEx, String message) {
super(message, oriEx);
}
public GenericException(Throwable oriEx) {
super(oriEx);
}
public GenericException(String message, Exception oriEx) {
super(message, oriEx);
}
public GenericException(String message, Throwable oriEx) {
super(message, oriEx);
}
public String getErrorCode() {
return this.errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMessage() {
return this.errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
\ No newline at end of file
... ...
package com.crossoverjie.cim.common.pojo;
/**
* Function:
* Function: 用户信息
*
* @author crossoverJie
* Date: 2018/12/24 02:33
... ...
... ... @@ -61,7 +61,7 @@ public class RouteController {
CIMServerResVO value = cimServerResVOEntry.getValue();
if (userId.equals(groupReqVO.getUserId())){
//过滤掉自己
CIMUserInfo cimUserInfo = userInfoCacheService.loadUserInfo(groupReqVO.getUserId());
CIMUserInfo cimUserInfo = userInfoCacheService.loadUserInfoByUserId(groupReqVO.getUserId());
LOGGER.warn("过滤掉了发送者 userId={}",cimUserInfo.toString());
continue;
}
... ... @@ -85,7 +85,7 @@ public class RouteController {
public BaseResponse<NULLBody> offLine(@RequestBody ChatReqVO groupReqVO) throws Exception {
BaseResponse<NULLBody> res = new BaseResponse();
CIMUserInfo cimUserInfo = userInfoCacheService.loadUserInfo(groupReqVO.getUserId());
CIMUserInfo cimUserInfo = userInfoCacheService.loadUserInfoByUserId(groupReqVO.getUserId());
LOGGER.info("下线用户[{}]", cimUserInfo.toString());
accountService.offLine(groupReqVO.getUserId());
... ... @@ -138,8 +138,8 @@ public class RouteController {
res.setCode(StatusEnum.SUCCESS.getCode());
res.setMessage(StatusEnum.SUCCESS.getMessage());
} else {
res.setCode(StatusEnum.FAIL.getCode());
res.setMessage(StatusEnum.FAIL.getMessage());
res.setCode(StatusEnum.REPEAT_LOGIN.getCode());
res.setMessage(StatusEnum.REPEAT_LOGIN.getMessage());
}
return res;
... ...
... ... @@ -41,7 +41,7 @@ public interface AccountService {
void saveRouteInfo(LoginReqVO loginReqVO ,String msg) throws Exception ;
/**
* 加载所有的路有关系
* 加载所有用户的路有关系
* @return 所有的路由关系
*/
Map<Long,CIMServerResVO> loadRouteRelated() ;
... ...
... ... @@ -13,9 +13,9 @@ public interface UserInfoCacheService {
/**
* 通过 userID 获取用户信息
* @param userId
* @param userId 用户唯一 ID
* @return
* @throws Exception
*/
CIMUserInfo loadUserInfo(long userId) throws Exception ;
CIMUserInfo loadUserInfoByUserId(long userId) throws Exception ;
}
... ...
... ... @@ -68,6 +68,15 @@ public class AccountServiceRedisImpl implements AccountService {
@Override
public boolean login(LoginReqVO loginReqVO) throws Exception {
//先判断是否已经登录,第一次登录 cimUserInfo 为空
CIMUserInfo cimUserInfo = userInfoCacheService.loadUserInfoByUserId(loginReqVO.getUserId());
if (cimUserInfo != null){
//重复登录
return false ;
}
//再去Redis里查询
String key = ACCOUNT_PREFIX + loginReqVO.getUserId();
String userName = redisTemplate.opsForValue().get(key);
if (null == userName) {
... ... @@ -119,7 +128,7 @@ public class AccountServiceRedisImpl implements AccountService {
@Override
public void pushMsg(String url, long sendUserId, ChatReqVO groupReqVO) throws Exception {
CIMUserInfo cimUserInfo = userInfoCacheService.loadUserInfo(sendUserId);
CIMUserInfo cimUserInfo = userInfoCacheService.loadUserInfoByUserId(sendUserId);
JSONObject jsonObject = new JSONObject();
jsonObject.put("msg", cimUserInfo.getUserName() + ":【" + groupReqVO.getMsg() + "】");
... ...
... ... @@ -22,7 +22,7 @@ import static com.crossoverjie.cim.route.constant.Constant.ACCOUNT_PREFIX;
public class UserInfoCacheServiceImpl implements UserInfoCacheService {
/**
* 本地缓存,后期可换为 LRU
* 本地缓存,为了防止内存撑爆,后期可换为 LRU。
*/
private final static Map<Long,CIMUserInfo> USER_INFO_MAP = new ConcurrentHashMap<>(64) ;
... ... @@ -30,7 +30,7 @@ public class UserInfoCacheServiceImpl implements UserInfoCacheService {
private RedisTemplate<String,String> redisTemplate ;
@Override
public CIMUserInfo loadUserInfo(long userId) throws Exception {
public CIMUserInfo loadUserInfoByUserId(long userId) throws Exception {
//优先从本地缓存获取
CIMUserInfo cimUserInfo = USER_INFO_MAP.get(userId);
... ...
... ... @@ -2,6 +2,7 @@ package com.crossoverjie.cim.server.handle;
import com.alibaba.fastjson.JSONObject;
import com.crossoverjie.cim.common.constant.Constants;
import com.crossoverjie.cim.common.exception.CIMException;
import com.crossoverjie.cim.common.pojo.CIMUserInfo;
import com.crossoverjie.cim.common.protocol.CIMRequestProto;
import com.crossoverjie.cim.server.config.AppConfiguration;
... ... @@ -92,7 +93,7 @@ public class CIMServerHandle extends SimpleChannelInboundHandler<CIMRequestProto
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
if (isResetByPeer(cause.getMessage())){
if (CIMException.isResetByPeer(cause.getMessage())){
return;
}
... ... @@ -100,11 +101,4 @@ public class CIMServerHandle extends SimpleChannelInboundHandler<CIMRequestProto
}
private boolean isResetByPeer(String msg) {
if ("Connection reset by peer".equals(msg)) {
return true;
}
return false;
}
}
... ...