Commit ddfd4488 authored by shangtx's avatar shangtx

feat: SSE引入

parent 3b36b6b6
package com.onsiteservice.admin.message;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.onsiteservice.core.exception.ServiceException;
import com.onsiteservice.core.result.ResultCodeEnum;
import com.onsiteservice.core.security.jwt.JwtManager;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* SSE(server sent event) 服务器到客户端单向传输数据
*/
@ConditionalOnProperty(prefix = "project.sse", name = {"enabled"}, matchIfMissing = true)
@Component
@Slf4j
public class SseHandler {
private static final Map<Long, SseEmitter> sseMap;
static {
sseMap = Collections.synchronizedMap(new HashMap<>());
}
public SseEmitter connect(HttpServletRequest request) {
String token = request.getParameter("token");
if (token == null) {
throw new ServiceException(ResultCodeEnum.UNAUTHORIZED.getCode(), "认证信息为空");
}
Claims claims = JwtManager.parseToken(token.replaceAll(JwtManager.BEARER, ""));
if(claims == null) {
throw new ServiceException(ResultCodeEnum.UNAUTHORIZED.getCode(), "认证错误");
}
long userId = JSON.parseObject(claims.getSubject()).getLong(JwtManager.USER_ID);
SseEmitter emitter = new SseEmitter(3600_000L);
emitter.onError((e) -> {
log.error("sse 连接异常 id=" + userId, e);
remove(userId);
});
emitter.onCompletion(() -> remove(userId));
emitter.onTimeout(() -> {
log.error("sse 连接超时 id=" + userId);
remove(userId);
});
sseMap.put(userId, emitter);
return emitter;
}
public void send(Object param, Long userId) {
var emitter = sseMap.get(userId);
if (emitter != null) {
try {
emitter.send(SseEmitter.event().data(param));
} catch (Exception e) {
log.error("发送sse消息错误 userId=" + userId + "; param=" + JSONObject.toJSONString(param), e);
}
}
}
public void remove(Long userId) {
sseMap.remove(userId);
}
}
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