我们通过监听器+webSocket实时发送站内审批通知消息,当用户发起审批时,实时发送给下一个审批人审批通知来通知审批人进行审批。
在SpringBoot中要想使用webSocket,首先在启动项中添加注解@EnableWebSocket来启用webSocket。
再进行webSocket服务类的创建。
//通过token来获取用户信息,并将id作为key存储每个用户的session,在用户上线时查询消息并发送
@OnOpen
public void onOpen(@PathParam("token") String token, Session session) throws IOException {
AuthLogic authLogic = new AuthLogic();
LoginUser loginUser = authLogic.getLoginUser(token);
if(loginUser==null){
session.close();
return;
}
this.session = session;
Long userId = loginUser.getSysUser().getUserId();
// 根据 /websocket/{id} 中传入的用户 id 作为键,存储每个用户的 session
WEBSOCKET_MAP.put(userId, session);
//上线查询下线时的消息
List<String> notify = redis.get(String.valueOf(userId));
if(null!=notify){
sendAllMessageByUserId(notify,userId);
}
// 发送后删除redis中的消息
redis.remove(String.valueOf(userId));
}
//通过用户id发送多条消息
public void sendAllMessageByUserId(List<String> messageList,Long userId ){
if (WEBSOCKET_MAP.get(userId) != null){
for (String msg : messageList) {
WEBSOCKET_MAP.get(userId).getAsyncRemote().sendText(gson.toJson(msg));
NotifyMessageVo notifyMessageVo = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.create()
.fromJson(msg, NotifyMessageVo.class);
saveMessageToDataBase(userId,notifyMessageVo);
System.out.println("消息已经发送完");
try {
Thread.sleep(500);
}catch (Exception e){
System.out.println("延迟失败");
e.printStackTrace();
}
}
}
}
//将发送完成的消息存入数据库中方便已发通知列表的查询
private int saveMessageToDataBase(Long userId, NotifyMessageVo msg) {
NotifyMessage notifyMessage = new NotifyMessage();
notifyMessage.setContent(msg.getContent());
notifyMessage.setTitle(msg.getTitle());
notifyMessage.setRevicer(userId);
notifyMessage.setData(msg.getData());
notifyMessage.setRedirect(msg.getRedirect());
notifyMessage.setSendTime(new Date());
notifyMessage.setType(msg.getType());
notifyMessage.setIsDeleted(0);
notifyMessage.setCreateTime(new Date());
notifyMessage.setCreatorName("admin");
notifyMessage.setReadType(0);
int id = notifyMessageMapper.insert(notifyMessage);
return id;
}
//通过userId发送单条消息
public void sendMessageByUserId(NotifyMessageVo message, Long userId){
try {
String s = gson.toJson(message);
WEBSOCKET_MAP.get(userId).getAsyncRemote().sendText(gson.toJson(message));
saveMessageToDataBase(userId,message);
}catch (Exception e){
redis.set(userId.toString(),message);
}
}
//服务器接收到消息时做的操作
@OnMessage
public void onMessage(String message) throws IOException {
//如果加入心跳检测,在这里进行相应
}
//用户推出时的操作
@OnClose
public void onClose() {
// 用户退出时,从 map 中删除信息
for (Map.Entry<Long, Session> entry : WEBSOCKET_MAP.entrySet()) {
if (this.session.getId().equals(entry.getValue().getId())) {
WEBSOCKET_MAP.remove(entry.getKey());
return;
}
}
}
@OnError
public void onError(Throwable error) {
error.printStackTrace();
}
//发送公告通知时将通知发给所有用户的方法
public void sendMessageToAll(NotifyMessageVo message) {
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
List<SysUser> sysUsers = sysUserMapper.selectList(queryWrapper);
sysUsers.forEach(sysUser->{
try {
WEBSOCKET_MAP.get(sysUser.getUserId()).getAsyncRemote().sendText(gson.toJson(message));
saveMessageToDataBase(sysUser.getUserId(),message);
}catch (Exception e){
redis.set(sysUser.getUserId().toString(),message);
}
});
通过postman测试是否连接成功.
连接成功
创建activiti7监听器
//这里运用注解使监听器让spring进行管理,这样可以使用自动注入
@Component("LeaveMangerStartLinstener")
public class LeaveMangerStartLinstener implements ExecutionListener {
//接受参数(要与流程图中传来参数名一致)
private Expression state;
@Autowired
private ISysUserService sysUserService;
@Autowired
private RemoteMessageService sendMessageService;
@Autowired
private RemoteWebSocketService webSocketService;
@Override
public void notify(DelegateExecution execution) {
// 获取审批人userName
String deptLeader =(String) execution.getTransientVariables().get("deptLeader");
List<String> deptLeaders = Arrays.asList(deptLeader.split(","));
String processInstanceId = execution.getProcessInstanceId();
deptLeaders.forEach(item->{
//可以通过远程调用来通过短信或者邮件等方式通知审批人
SysUser sysUser = sysUserService.selectUserByUserName(item);
Long userId = sysUser.getUserId();
String email = sysUser.getEmail();
SendForm sendForm = new SendForm();
sendForm.setSendChannel(10);
//通过邮件进行发送
sendForm.setReceivers(email);
sendForm.setIsExitVariables(2);
sendForm.setVariables("[{\"a_id\":\"11\",\"content\":\"有请假申请待确认\"}]");
sendForm.setIsNeedBreak(false);
sendForm.setMessageTemplateId(5L);
sendMessageService.send(sendForm);
// 通过webSocket 实时通知审批人
NotifyMessageVo notifyMessageVo = new NotifyMessageVo();
notifyMessageVo.setContent("请假通知待确认");
notifyMessageVo.setType("RATIFY");
notifyMessageVo.setTitle("审批通知");
notifyMessageVo.setSendTime(new Date().toString());
notifyMessageVo.setData(processInstanceId);
notifyMessageVo.setRedirect("LEAVE");
String message = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.create()
.toJson(notifyMessageVo);
//通过webSocket发送消息给审批人
webSocketService.sendMessage(userId,message);
});
}
}
在创建流程图时添加监听器
注:如果想要使用自动注入则需要将监听器类型改为代理表达式,字段注入中的参数要与监听器接收参数名相同。
以上就是通过监听器实时发送审批消息的简单代码