package com.izouma.meta.web; import com.izouma.meta.config.Constants; import com.izouma.meta.domain.MetaScheduledFuture; import com.izouma.meta.enums.ScheduledFutureType; import com.izouma.meta.repo.MetaObjectMoveRepo; import com.izouma.meta.repo.MetaScheduledFutureRepo; import com.izouma.meta.websocket.MMOWebSocket; import lombok.AllArgsConstructor; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.*; import java.util.stream.Collectors; @RestController @RequestMapping("/mmo/websocket") @AllArgsConstructor @CrossOrigin(origins = {"http://localhost:8081", "https://raex.vip/", "https://test.raex.vip/", "https://www.raex.vip/"}) public class MMOWebSocketController { private MMOWebSocket mmoWebSocket; private MetaObjectMoveRepo metaObjectMoveRepo; private MetaScheduledFutureRepo metaScheduledFutureRepo; private final Map> tasks = new ConcurrentHashMap<>(); @GetMapping("/{objectId}/start") public synchronized void startSendingMessages(@PathVariable String objectId) { if (tasks.containsKey(objectId)) { throw new IllegalArgumentException(String.format("Task with id %S is already running", objectId)); } ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); ScheduledFuture future = executor.scheduleAtFixedRate(() -> sendMessage(objectId), Constants.META_ROBOT_SEND_MSG_DELAY_MS, Constants.META_ROBOT_SEND_MSG_PERIOD_MS, TimeUnit.MILLISECONDS); tasks.put(objectId, future); // 保存任务信息 MetaScheduledFuture metaScheduledFuture = metaScheduledFutureRepo.findByTypeAndTaskId(ScheduledFutureType.OBJECT_MOVE, objectId); if (Objects.isNull(metaScheduledFuture)) { metaScheduledFuture = new MetaScheduledFuture(); metaScheduledFuture.setType(ScheduledFutureType.OBJECT_MOVE); metaScheduledFuture.setTaskId(objectId); metaScheduledFutureRepo.save(metaScheduledFuture); } } @GetMapping("/{objectId}/stop") public synchronized void stopSendingMessages(@PathVariable String objectId) { ScheduledFuture future = tasks.get(objectId); if (future != null) { future.cancel(false); tasks.remove(objectId); } metaScheduledFutureRepo.deleteByTypeAndTaskId(ScheduledFutureType.OBJECT_MOVE, objectId); } private void sendMessage(String objectId) { if (mmoWebSocket != null) { mmoWebSocket.onMessage(Constants.META_ROBOT_NICK_NAME, Constants.META_ROBOT_USER_ID, String.format(Constants.META_ROBOT_MESSAGE_BODY, objectId), null); } } @GetMapping("/check") public synchronized String check() { List objectId = metaObjectMoveRepo.findAllRunningObjectId(); if (CollectionUtils.isEmpty(objectId)) { if (tasks.isEmpty()) { return "success"; } return String.format("物体: %s 未结束广播坐标任务,请联系管理员处理", String.join(",", tasks.keySet())); } if (tasks.isEmpty()) { return String.format("物体: %s 未开启广播坐标任务,请联系管理员处理", objectId.stream().map(Object::toString).collect(Collectors.toList())); } StringBuffer str = new StringBuffer(); objectId.forEach(id -> { if (!tasks.containsKey(String.valueOf(id))) { str.append(",").append(id); } }); if (StringUtils.isNotBlank(str)) { return String.format("物体: %s 未开启广播坐标任务,请联系管理员处理", str); } return "success"; } }