Commit 8a62313e authored by 高滢's avatar 高滢
parents 887a4a0a 77a664da
...@@ -27,8 +27,6 @@ public class CarReviewTask implements Serializable { ...@@ -27,8 +27,6 @@ public class CarReviewTask implements Serializable {
@TableField(exist = false)
public static final String TASK_STATUS_NONE = "NONE";
@TableField(exist = false) @TableField(exist = false)
public static final String TASK_STATUS_NEW = "NEW"; public static final String TASK_STATUS_NEW = "NEW";
@TableField(exist = false) @TableField(exist = false)
...@@ -55,7 +53,7 @@ public class CarReviewTask implements Serializable { ...@@ -55,7 +53,7 @@ public class CarReviewTask implements Serializable {
/** /**
* 任务状态(PENDING、FINISH) * 任务状态(PENDING、FINISH)
*/ */
@ApiModelProperty("任务状态[NONE、NEW、PENDING、FINISH]") @ApiModelProperty("任务状态[NEW、PENDING、FINISH]")
private String taskStatus; private String taskStatus;
/** /**
......
...@@ -24,7 +24,9 @@ import java.util.List; ...@@ -24,7 +24,9 @@ import java.util.List;
public class Task { public class Task {
@TableField(exist = false) @TableField(exist = false)
public static final String STATUS_NEW = "NEW"; public static final String STATUS_RUNNABLE = "RUNNABLE";
@TableField(exist = false)
public static final String STATUS_RUNNING = "RUNNING";
@TableField(exist = false) @TableField(exist = false)
public static final String STATUS_FINISH = "FINISH"; public static final String STATUS_FINISH = "FINISH";
...@@ -59,6 +61,9 @@ public class Task { ...@@ -59,6 +61,9 @@ public class Task {
@ApiModelProperty("任务状态(NEW、FINISH)") @ApiModelProperty("任务状态(NEW、FINISH)")
private String taskStatus; private String taskStatus;
@ApiModelProperty("下一个节点 SUB_TASK_SRAIF(体系审查子任务)、SUB_TASK_TRFIS(车辆实验子任务)、SUB_TASK_GRFIS(车辆问卷子任务)")
private String nextNode;
@ApiModelProperty("产品名称") @ApiModelProperty("产品名称")
private String productName; private String productName;
......
...@@ -19,4 +19,8 @@ public interface TaskMapper extends BaseMapper<Task> { ...@@ -19,4 +19,8 @@ public interface TaskMapper extends BaseMapper<Task> {
List<TaskFindPendingResponse> findPending(TaskFindPendingRequest request); List<TaskFindPendingResponse> findPending(TaskFindPendingRequest request);
List<Task> findFinish(TaskFindFinishRequest request); List<Task> findFinish(TaskFindFinishRequest request);
Long findByCarReviewTaskId(@Param("carReviewId") Long carReviewId);
Long findBySystemReviewTaskId(@Param("systemReviewId") Long systemReviewId);
} }
...@@ -36,4 +36,6 @@ public interface TaskService extends IService<Task> { ...@@ -36,4 +36,6 @@ public interface TaskService extends IService<Task> {
void editTask(TaskEditRequest request); void editTask(TaskEditRequest request);
void deleteTask(TaskDeleteRequest request); void deleteTask(TaskDeleteRequest request);
void startTask(TaskStartRequest request);
} }
...@@ -93,8 +93,6 @@ public class CarReviewTaskServiceImpl extends ServiceImpl<CarReviewTaskMapper, C ...@@ -93,8 +93,6 @@ public class CarReviewTaskServiceImpl extends ServiceImpl<CarReviewTaskMapper, C
.setFile(standard.getFile()); .setFile(standard.getFile());
if (request.getReview()) { if (request.getReview()) {
task.setTaskStatus(CarReviewTask.TASK_STATUS_NEW); task.setTaskStatus(CarReviewTask.TASK_STATUS_NEW);
} else {
task.setTaskStatus(CarReviewTask.TASK_STATUS_NONE);
} }
carReviewTaskService.save(task); carReviewTaskService.save(task);
......
package com.ruoyi.service.impl;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.domain.CarReviewTask;
import com.ruoyi.service.StrategyCarReviewTask;
import com.ruoyi.web.response.CarReviewTaskViewResponse;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Service
public class StrategyCarReviewTaskNone implements StrategyCarReviewTask, InitializingBean {
@Autowired
private StrategyCarReviewTaskContext strategyCarReviewTaskContext;
@Autowired
private ApplicationContext applicationContext;
@Override
public CarReviewTaskViewResponse doView(CarReviewTask carReviewTask) {
throw new ServiceException("不能查看一个不存在的任务", HttpStatus.ERROR);
}
@Override
public void doStartReview(CarReviewTask carReviewTask) {
throw new ServiceException("不能开始一个不存在的任务", HttpStatus.ERROR);
}
@Override
public void doConfirmReview(CarReviewTask carReviewTask) {
throw new ServiceException("不能确认一个不存在的任务", HttpStatus.ERROR);
}
@Override
public void doSubmitReview(CarReviewTask carReviewTask,String imagesUrl) {
throw new ServiceException("不能提交一个不存在的任务", HttpStatus.ERROR);
}
@Override
public void afterPropertiesSet() throws Exception {
strategyCarReviewTaskContext.putResource(CarReviewTask.TASK_STATUS_NONE, applicationContext.getBean(this.getClass()));
}
}
...@@ -8,6 +8,7 @@ import com.ruoyi.domain.*; ...@@ -8,6 +8,7 @@ import com.ruoyi.domain.*;
import com.ruoyi.mapper.CarReviewTaskMapper; import com.ruoyi.mapper.CarReviewTaskMapper;
import com.ruoyi.mapper.ReviewDetailsMapper; import com.ruoyi.mapper.ReviewDetailsMapper;
import com.ruoyi.mapper.ReviewDetailsResultMapper; import com.ruoyi.mapper.ReviewDetailsResultMapper;
import com.ruoyi.mapper.TaskMapper;
import com.ruoyi.service.ReviewDetailsResultService; import com.ruoyi.service.ReviewDetailsResultService;
import com.ruoyi.service.ReviewSceneChangeTaskService; import com.ruoyi.service.ReviewSceneChangeTaskService;
import com.ruoyi.service.ReviewStandardService; import com.ruoyi.service.ReviewStandardService;
...@@ -19,6 +20,7 @@ import org.springframework.context.ApplicationContext; ...@@ -19,6 +20,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.swing.table.TableModel;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -38,6 +40,9 @@ public class StrategyCarReviewTaskSigned implements StrategyCarReviewTask, Initi ...@@ -38,6 +40,9 @@ public class StrategyCarReviewTaskSigned implements StrategyCarReviewTask, Initi
@Autowired @Autowired
private CarReviewTaskMapper carReviewTaskMapper; private CarReviewTaskMapper carReviewTaskMapper;
@Autowired
private TaskMapper taskMapper;
// SIGNED状态下 // SIGNED状态下
// 1.standard字段使用task中归档的问卷 // 1.standard字段使用task中归档的问卷
// 2.不查询场景变更任务 // 2.不查询场景变更任务
...@@ -77,7 +82,12 @@ public class StrategyCarReviewTaskSigned implements StrategyCarReviewTask, Initi ...@@ -77,7 +82,12 @@ public class StrategyCarReviewTaskSigned implements StrategyCarReviewTask, Initi
// 4. 保存签名图片地址 // 4. 保存签名图片地址
carReviewTask.setImagesUrl(imagesUrl); carReviewTask.setImagesUrl(imagesUrl);
// 5.再找带该子任务所属的总任务,将总任务的状态由 RUNNING 改回 RUNNABLE
Task task = taskMapper.selectById(taskMapper.findByCarReviewTaskId(carReviewTask.getId()));
task.setTaskStatus(Task.STATUS_RUNNABLE);
carReviewTaskMapper.updateById(carReviewTask); carReviewTaskMapper.updateById(carReviewTask);
taskMapper.updateById(task);
} }
......
...@@ -8,6 +8,7 @@ import com.ruoyi.domain.*; ...@@ -8,6 +8,7 @@ import com.ruoyi.domain.*;
import com.ruoyi.mapper.ReviewDetailsMapper; import com.ruoyi.mapper.ReviewDetailsMapper;
import com.ruoyi.mapper.ReviewDetailsResultMapper; import com.ruoyi.mapper.ReviewDetailsResultMapper;
import com.ruoyi.mapper.SystemReviewTaskMapper; import com.ruoyi.mapper.SystemReviewTaskMapper;
import com.ruoyi.mapper.TaskMapper;
import com.ruoyi.service.ReviewDetailsResultService; import com.ruoyi.service.ReviewDetailsResultService;
import com.ruoyi.service.ReviewSceneChangeTaskService; import com.ruoyi.service.ReviewSceneChangeTaskService;
import com.ruoyi.service.ReviewStandardService; import com.ruoyi.service.ReviewStandardService;
...@@ -38,6 +39,9 @@ public class StrategySystemReviewTaskSigned implements StrategySystemReviewTask, ...@@ -38,6 +39,9 @@ public class StrategySystemReviewTaskSigned implements StrategySystemReviewTask,
@Autowired @Autowired
private SystemReviewTaskMapper systemReviewTaskMapper; private SystemReviewTaskMapper systemReviewTaskMapper;
@Autowired
private TaskMapper taskMapper;
@Override @Override
public void doStart(SystemReviewTask systemReviewTask) { public void doStart(SystemReviewTask systemReviewTask) {
...@@ -67,7 +71,12 @@ public class StrategySystemReviewTaskSigned implements StrategySystemReviewTask, ...@@ -67,7 +71,12 @@ public class StrategySystemReviewTaskSigned implements StrategySystemReviewTask,
// 4.保存签名图片地址 // 4.保存签名图片地址
systemReviewTask.setImagesUrl(imagesUrl); systemReviewTask.setImagesUrl(imagesUrl);
// 5.再找带该子任务所属的总任务,将总任务的状态由 RUNNING 改回 RUNNABLE
Task task = taskMapper.selectById(taskMapper.findBySystemReviewTaskId(systemReviewTask.getId()));
task.setTaskStatus(Task.STATUS_RUNNABLE);
systemReviewTaskMapper.updateById(systemReviewTask); systemReviewTaskMapper.updateById(systemReviewTask);
taskMapper.updateById(task);
} }
@Override @Override
......
...@@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects;
@Transactional @Transactional
@Service @Service
...@@ -86,37 +87,42 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta ...@@ -86,37 +87,42 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
Task task = new Task(); Task task = new Task();
task.setTaskInitiator(initiator.getNickName()); task.setTaskInitiator(initiator.getNickName());
task.setTaskInitiatorDept(initiator.getDept().getDeptName()); task.setTaskInitiatorDept(initiator.getDept().getDeptName());
task.setTaskStatus(Task.STATUS_NEW); task.setTaskStatus(Task.STATUS_RUNNABLE);
task.setLeaderId(leader.getUserId()); task.setLeaderId(leader.getUserId());
task.setLeader(leader.getName()); task.setLeader(leader.getName());
task.setCreateTime(new Date()); task.setCreateTime(new Date());
task.setName(standard.getName()); task.setName(standard.getName());
task.setStandardNo(standard.getStandardNo()); task.setStandardNo(standard.getStandardNo());
task.setFile(standard.getFile()); task.setFile(standard.getFile());
AutomobileEnterprise automobileEnterprise = automobileEnterpriseMapper.selectById(request.getProductionId());
task.setProductionEnterprise(automobileEnterprise.getEnterpriseName());
BeanUtils.copyBeanProp(task, request); BeanUtils.copyBeanProp(task, request);
AutomobileEnterprise automobileEnterprise = automobileEnterpriseMapper.selectAutomobileEnterpriseById(request.getProductionId());
task.setProductionEnterprise(automobileEnterprise.getEnterpriseName());
Long systemReviewTaskId = null;
Long carReviewTaskId = null;
if (request.getTaskList().contains(Task.SUB_TASK_SRAIF)) { String nextNode = null;
// 保存体系审查任务
systemReviewTaskId = saveSystemReview(request,initiator,standard,leader); if(request.getTaskList().contains(Task.SUB_TASK_TRFIS)) {
nextNode = Task.SUB_TASK_TRFIS;
} }
if (request.getTaskList().contains(Task.SUB_TASK_GRFIS)) { if(request.getTaskList().contains(Task.SUB_TASK_GRFIS)) {
// 保存车型审查问卷任务 // 保存车型审查问卷任务
carReviewTaskId = saveCarReview(request,initiator,standard,leader); nextNode = Task.SUB_TASK_GRFIS;;
task.setCarReviewTaskId(saveCarReview(request,initiator,standard,leader));
}
if(request.getTaskList().contains(Task.SUB_TASK_SRAIF)) {
// 保存体系审查任务
nextNode = Task.SUB_TASK_SRAIF;
task.setSystemReviewTaskId(saveSystemReview(request,initiator,standard,leader));
} }
task.setCarReviewTaskId(carReviewTaskId); task.setNextNode(nextNode);
task.setSystemReviewTaskId(systemReviewTaskId);
taskService.save(task); taskService.save(task);
// 构建并保存该任务所关联的审核组信息 // 构建并保存该任务所关联的审核组信息
for(TaskUserRelation auditor : auditors) { for(TaskUserRelation auditor : auditors) {
auditor.setTaskId(task.getId()); auditor.setTaskId(task.getId());
} }
taskUserRelationService.saveBatch(auditors); taskUserRelationService.saveBatch(auditors);
} }
...@@ -178,6 +184,31 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta ...@@ -178,6 +184,31 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
taskMapper.deleteById(request.getId()); taskMapper.deleteById(request.getId());
} }
@Override
public void startTask(TaskStartRequest request) {
Task task = taskMapper.selectById(request.getId());
SystemReviewTaskStartRequest systemRequest = new SystemReviewTaskStartRequest();
systemRequest.setTaskId(task.getSystemReviewTaskId());
CarReviewTaskStartRequest carRequest = new CarReviewTaskStartRequest();
carRequest.setTaskId(task.getCarReviewTaskId());
if (Objects.equals(task.getNextNode(), Task.SUB_TASK_SRAIF)) {
systemReviewTaskService.start(systemRequest);
task.setTaskStatus(Task.STATUS_RUNNING);
task.setNextNode(Task.SUB_TASK_GRFIS);
taskMapper.updateById(task);
} else if (Objects.equals(task.getNextNode(), Task.SUB_TASK_GRFIS)) {
carReviewTaskService.startReviewTask(carRequest);
task.setTaskStatus(Task.STATUS_RUNNING);
task.setNextNode(Task.SUB_TASK_TRFIS);
taskMapper.updateById(task);
}
}
public Long saveSystemReview(TaskCreateRequest request,SysUser initiator,Standard standard,TaskUserRelation leader) { public Long saveSystemReview(TaskCreateRequest request,SysUser initiator,Standard standard,TaskUserRelation leader) {
// 构建并保存任务信息 // 构建并保存任务信息
...@@ -207,11 +238,10 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta ...@@ -207,11 +238,10 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
.setTaskNo(request.getTaskNo()) .setTaskNo(request.getTaskNo())
.setTaskInitiator(initiator.getNickName()) .setTaskInitiator(initiator.getNickName())
.setTaskInitiatorDept(initiator.getDept().getDeptName()) .setTaskInitiatorDept(initiator.getDept().getDeptName())
.setTaskStatus(taskList.contains(Task.SUB_TASK_GRFIS) ? CarReviewTask.TASK_STATUS_NEW : CarReviewTask.TASK_STATUS_NONE) .setTaskStatus(CarReviewTask.TASK_STATUS_NEW)
.setLeaderId(leader.getUserId()) .setLeaderId(leader.getUserId())
.setLeader(leader.getName()) .setLeader(leader.getName())
.setCreateTime(new Date()) .setCreateTime(new Date())
.setTaskBeginTime(new Date())
.setStandardId(standard.getId()) .setStandardId(standard.getId())
.setName(standard.getName()) .setName(standard.getName())
.setStandardNo(standard.getStandardNo()) .setStandardNo(standard.getStandardNo())
......
...@@ -109,4 +109,15 @@ public class TaskController extends BaseController { ...@@ -109,4 +109,15 @@ public class TaskController extends BaseController {
return R.ok(); return R.ok();
} }
@ApiOperation("开始任务")
@Trace
@Tags({@Tag(key = "param", value = "arg[0]"), @Tag(key = "result", value = "returnedObj")})
@Log(title = "开始任务", businessType = BusinessType.UPDATE)
@RequestMapping(method = RequestMethod.POST, value = "/startTask")
public R<String> startTask(@Validated @RequestBody TaskStartRequest request) {
taskService.startTask(request);
return R.ok();
}
} }
package com.ruoyi.web.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel(value = "TaskStartRequest", description = "开始任务")
@Data
public class TaskStartRequest {
@ApiModelProperty("ID")
private Long id;
}
...@@ -32,6 +32,9 @@ public class TaskFindPendingResponse { ...@@ -32,6 +32,9 @@ public class TaskFindPendingResponse {
@ApiModelProperty("任务状态(NEW、PENDING、FINISH)") @ApiModelProperty("任务状态(NEW、PENDING、FINISH)")
private String taskStatus; private String taskStatus;
@ApiModelProperty("下一个节点 SUB_TASK_SRAIF(体系审查子任务)、SUB_TASK_TRFIS(车辆实验子任务)、SUB_TASK_GRFIS(车辆问卷子任务)")
private String nextNode;
@ApiModelProperty("总任务开始时间") @ApiModelProperty("总任务开始时间")
private Date taskBeginTime; private Date taskBeginTime;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
<result property="taskNo" column="task_no" jdbcType="VARCHAR"/> <result property="taskNo" column="task_no" jdbcType="VARCHAR"/>
<result property="taskName" column="task_name" jdbcType="VARCHAR"/> <result property="taskName" column="task_name" jdbcType="VARCHAR"/>
<result property="taskStatus" column="task_status" jdbcType="VARCHAR"/> <result property="taskStatus" column="task_status" jdbcType="VARCHAR"/>
<result property="nextNode" column="next_node" jdbcType="VARCHAR"/>
<result property="productName" column="product_name" jdbcType="VARCHAR"/> <result property="productName" column="product_name" jdbcType="VARCHAR"/>
<result property="productModel" column="product_model" jdbcType="VARCHAR"/> <result property="productModel" column="product_model" jdbcType="VARCHAR"/>
<result property="entrustedUnit" column="entrusted_unit" jdbcType="VARCHAR"/> <result property="entrustedUnit" column="entrusted_unit" jdbcType="VARCHAR"/>
...@@ -49,6 +50,7 @@ ...@@ -49,6 +50,7 @@
<result property="taskNo" column="task_no" jdbcType="VARCHAR"/> <result property="taskNo" column="task_no" jdbcType="VARCHAR"/>
<result property="taskName" column="task_name" jdbcType="VARCHAR"/> <result property="taskName" column="task_name" jdbcType="VARCHAR"/>
<result property="taskStatus" column="task_status" jdbcType="VARCHAR"/> <result property="taskStatus" column="task_status" jdbcType="VARCHAR"/>
<result property="nextNode" column="next_node" jdbcType="VARCHAR"/>
<result property="taskBeginTime" column="task_begin_time" jdbcType="TIMESTAMP"/> <result property="taskBeginTime" column="task_begin_time" jdbcType="TIMESTAMP"/>
<result property="systemTaskBeginTime" column="system_task_begin_time" jdbcType="TIMESTAMP"/> <result property="systemTaskBeginTime" column="system_task_begin_time" jdbcType="TIMESTAMP"/>
<result property="systemTaskEndTime" column="system_task_end_time" jdbcType="TIMESTAMP"/> <result property="systemTaskEndTime" column="system_task_end_time" jdbcType="TIMESTAMP"/>
...@@ -62,7 +64,7 @@ ...@@ -62,7 +64,7 @@
<select id="findList" parameterType="com.ruoyi.web.request.TaskListRequest" resultMap="BaseResultMap"> <select id="findList" parameterType="com.ruoyi.web.request.TaskListRequest" resultMap="BaseResultMap">
SELECT id, system_review_task_id, car_review_task_id, SELECT id, system_review_task_id, car_review_task_id,
task_no,task_name,task_status,product_name,product_model, task_no,task_name,task_status,next_node,product_name,product_model,
entrusted_unit,entrusted_unit_address,entrusted_unit_phone, entrusted_unit,entrusted_unit_address,entrusted_unit_phone,
entrusted_unit_code,car_type,car_identification_code, entrusted_unit_code,car_type,car_identification_code,
confidentiality_level,sample_name,production_id,production_enterprise, confidentiality_level,sample_name,production_id,production_enterprise,
...@@ -87,6 +89,7 @@ ...@@ -87,6 +89,7 @@
t.task_no,t.task_name,t.task_status, t.task_no,t.task_name,t.task_status,
t.leader_id,t.leader, t.leader_id,t.leader,
t.task_begin_time, t.task_begin_time,
t.next_node,
srt.task_begin_time system_task_begin_time, srt.task_begin_time system_task_begin_time,
srt.task_end_time system_task_end_time, srt.task_end_time system_task_end_time,
srt.task_status review_status, srt.task_status review_status,
...@@ -128,6 +131,16 @@ ...@@ -128,6 +131,16 @@
</if> </if>
</where> </where>
</select> </select>
<select id="findByCarReviewTaskId" resultType="java.lang.Long">
SELECT id
FROM t_task
WHERE system_review_task_id = #{systemReviewId}
</select>
<select id="findBySystemReviewTaskId" resultType="java.lang.Long">
SELECT id
FROM t_task
WHERE car_review_task_id = #{carReviewId}
</select>
</mapper> </mapper>
...@@ -71,6 +71,12 @@ ...@@ -71,6 +71,12 @@
<version>9.0.0</version> <version>9.0.0</version>
</dependency> </dependency>
<!-- SpringBoot Websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
package com.ruoyi.framework.websocket;
import java.util.concurrent.Semaphore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 信号量相关处理
*
* @author ruoyi
*/
public class SemaphoreUtils
{
/**
* SemaphoreUtils 日志控制器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(SemaphoreUtils.class);
/**
* 获取信号量
*
* @param semaphore
* @return
*/
public static boolean tryAcquire(Semaphore semaphore)
{
boolean flag = false;
try
{
flag = semaphore.tryAcquire();
}
catch (Exception e)
{
LOGGER.error("获取信号量异常", e);
}
return flag;
}
/**
* 释放信号量
*
* @param semaphore
*/
public static void release(Semaphore semaphore)
{
try
{
semaphore.release();
}
catch (Exception e)
{
LOGGER.error("释放信号量异常", e);
}
}
}
package com.ruoyi.framework.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* websocket 配置
*
* @author ruoyi
*/
@Configuration
public class WebSocketConfig
{
@Bean
public ServerEndpointExporter serverEndpointExporter()
{
return new ServerEndpointExporter();
}
}
package com.ruoyi.framework.websocket;
import java.util.concurrent.Semaphore;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* websocket 消息处理
*
* @author ruoyi
*/
@Component
@ServerEndpoint("/websocket/{userid}")
public class WebSocketServer
{
/**
* WebSocketServer 日志控制器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);
/**
* 默认最多允许同时在线人数100
*/
public static int socketMaxOnlineCount = 100;
private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("userid") Long userid) throws Exception
{
boolean semaphoreFlag = false;
// 尝试获取信号量
semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore);
if (!semaphoreFlag)
{
// 未获取到信号量
LOGGER.error("\n 当前在线人数超过限制数- {}", socketMaxOnlineCount);
WebSocketUsers.sendMessageToUserByText(session, "当前在线人数超过限制数:" + socketMaxOnlineCount);
session.close();
}
else
{
// 添加用户
WebSocketUsers.put(session.getId(), session, userid);
LOGGER.info("\n 建立连接 - {}", session);
LOGGER.info("\n 当前人数 - {}", WebSocketUsers.getUsers().size());
WebSocketUsers.sendMessageToUserByText(session, "连接成功");
}
}
/**
* 连接关闭时处理
*/
@OnClose
public void onClose(Session session)
{
LOGGER.info("\n 关闭连接 - {}", session);
// 移除用户
WebSocketUsers.remove(session.getId());
// 获取到信号量则需释放
SemaphoreUtils.release(socketSemaphore);
}
/**
* 抛出异常时处理
*/
@OnError
public void onError(Session session, Throwable exception) throws Exception
{
if (session.isOpen())
{
// 关闭连接
session.close();
}
String sessionId = session.getId();
LOGGER.info("\n 连接异常 - {}", sessionId);
LOGGER.info("\n 异常信息 - {}", exception);
// 移出用户
WebSocketUsers.remove(sessionId);
// 获取到信号量则需释放
SemaphoreUtils.release(socketSemaphore);
}
/**
* 服务器接收到客户端消息时调用的方法
*/
@OnMessage
public void onMessage(String message, Session session)
{
String msg = message.replace("你", "我").replace("吗", "");
WebSocketUsers.sendMessageToUserByText(session, msg);
}
}
package com.ruoyi.framework.websocket;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* websocket 客户端用户集
*
* @author ruoyi
*/
public class WebSocketUsers
{
/**
* WebSocketUsers 日志控制器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketUsers.class);
/**
* 用户集
*/
private static Map<String, WebSocketSession> USERS = new ConcurrentHashMap();
/**
* 存储用户
*
* @param key 唯一键
* @param session 用户信息
*/
public static void put(String key, Session session, Long userId)
{
USERS.put(key, new WebSocketSession(userId, session));
}
/**
* 移出用户
*
* @param key 键
*/
public static boolean remove(String key)
{
LOGGER.info("\n 正在移出用户 - {}", key);
WebSocketSession remove = USERS.remove(key);
if (remove != null)
{
boolean containsValue = USERS.containsValue(remove);
LOGGER.info("\n 移出结果 - {}", containsValue ? "失败" : "成功");
return containsValue;
}
else
{
return true;
}
}
/**
* 获取在线用户列表
*
* @return 返回用户集合
*/
public static Map<String, WebSocketSession> getUsers()
{
return USERS;
}
/**
* 群发消息文本消息
*
* @param message 消息内容
*/
public static void sendMessageToUsersByText(String message)
{
Collection<WebSocketSession> values = USERS.values();
for (WebSocketSession value : values)
{
sendMessageToUserByText(value.getSession(), message);
}
}
/**
* 发送文本消息
*
* @param session 用户session
* @param message 消息内容
*/
public static void sendMessageToUserByText(Session session, String message)
{
if (session != null)
{
try
{
session.getBasicRemote().sendText(message);
}
catch (IOException e)
{
LOGGER.error("\n[发送消息异常]", e);
}
}
else
{
LOGGER.info("\n[你已离线]");
}
}
/**
* 发送文本消息
*
* @param userId 用户id
* @param message 消息内容
*/
public static void sendMessageToUserByUserId(Long userId, String message) {
Map<String, WebSocketSession> users = getUsers();
for(String key : users.keySet()) {
WebSocketSession webSocketSession = users.get(key);
if(webSocketSession.getUserId().equals(userId)) {
sendMessageToUserByText(webSocketSession.getSession(), message);
}
}
}
private static class WebSocketSession {
private Long userId;
private Session session;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WebSocketSession that = (WebSocketSession) o;
return Objects.equals(userId, that.userId) && Objects.equals(session, that.session);
}
@Override
public int hashCode() {
return Objects.hash(userId, session);
}
public WebSocketSession(Long userId, Session session) {
this.userId = userId;
this.session = session;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment