public abstract class AbstractGamingHandler<Req> {
@Autowired
WebSocketService webSocketService;
@Autowired
RoomService roomService;
@Autowired
PlayerStatusService playerStatusService;
private Class<Req> bodyClass;
@PostConstruct
private void init() {
ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
this.bodyClass = (Class<Req>) genericSuperclass.getActualTypeArguments()[0];
GamingHandlerFactory.register(getTypeEnum().getStatus(), this);
}
@Transactional
public void saveAndSend(GamingReq req, Long uid) throws Exception {
checkStatus(req, uid);
Req bean = toBean(req.getBody());
WSBaseResp save = buildWSResp(req, uid, bean);
webSocketService.sendToUid(save, getUids(req.getRoomId()));
}
abstract WSBaseResp buildWSResp(GamingReq req, Long uid, Req body);
List<Long> getUids(@NotNull Long roomId) {
List<Long> broadcastIds = roomService.getTwoPlayer(roomId);
return broadcastIds;
}
void checkStatus(GamingReq req, Long uid) throws Exception {
if (false) {
throw new Exception("错误");
}
}
private Req toBean(Object body) {
if (bodyClass.isAssignableFrom(body.getClass())) {
return (Req) body;
}
return BeanUtil.toBean(body, bodyClass);
}
abstract GamingEnum getTypeEnum();
abstract WSRespTypeEnum getWSRespTypeEnum();
public WSBaseResp WSAdapter(Object data) {
return WSBaseResp.build(getWSRespTypeEnum(), data);
}
}
package com.example.demo.game.biz.strategy;
import com.example.demo.common.redis.RedisKeys;
import com.example.demo.common.redis.RedisUtil;
import com.example.demo.game.biz.BizGameService;
import com.example.demo.game.model.dto.ChallengeDto;
import com.example.demo.game.model.dto.GamingReq;
import com.example.demo.web.enums.GamingEnum;
import com.example.demo.websocket.model.WSBaseResp;
import com.example.demo.websocket.model.enums.WSRespTypeEnum;
import com.example.demo.websocket.model.vo.ChallengeData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ChallengeReqHandler extends AbstractGamingHandler<ChallengeDto> {
@Autowired
RedisUtil redisUtil;
@Autowired
BizGameService bizGameService;
@Override
WSBaseResp buildWSResp(GamingReq req, Long uid, ChallengeDto body) {
ChallengeData challengeData = new ChallengeData();
redisUtil.set(RedisKeys.GAME_CHESS_UNDO + req.getRoomId(), req.getRoomId());
return WSAdapter(challengeData);
}
@Override
public GamingEnum getTypeEnum() {
return GamingEnum.CHALLENGE;
}
@Override
WSRespTypeEnum getWSRespTypeEnum() {
return WSRespTypeEnum.CHALLENGE;
}
}
@AllArgsConstructor
@Getter
public enum GamingEnum {
REDO_REQUEST(1, "悔棋请求", RedoReqDto.class),
;
private static final Map<Integer, GamingEnum> cache;
static {
cache = Arrays.stream(GamingEnum.values()).collect(Collectors.toMap(GamingEnum::getStatus, Function.identity()));
}
private final Integer status;
private final String desc;
private final Class<?> dataClass;
public static GamingEnum of(Integer type) {
return cache.get(type);
}
public <T> AbstractGamingHandler<T> getHandler() {
return GamingHandlerFactory.getStrategyNoNull(this.getStatus());
}
}
public class GamingHandlerFactory {
private static final Map<Integer, AbstractGamingHandler<?>> STRATEGY_MAP = new HashMap<>();
public static void register(Integer code, AbstractGamingHandler strategy) {
STRATEGY_MAP.put(code, strategy);
}
public static AbstractGamingHandler getStrategyNoNull(Integer code) {
AbstractGamingHandler strategy = STRATEGY_MAP.get(code);
return strategy;
}
}