注意需要添加注解
@EnableAsync

配置

  1. @Slf4j
  2. @Configuration
  3. @EnableWebSocketMessageBroker
  4. public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
  5. @Bean
  6. public ServerEndpointExporter serverEndpointExporter() {
  7. return new ServerEndpointExporter();
  8. }
  9. /**
  10. * 注册STOMP协议的节点(endpoint) 将每个节点映射到一个特定的URL
  11. *
  12. * @param registry
  13. */
  14. @Override
  15. public void registerStompEndpoints(StompEndpointRegistry registry) {
  16. //建立连接端点,注册一个STOMP的协议节点,并指定使用SockJS协议
  17. registry.addEndpoint("/-websocket")
  18. .setAllowedOrigins("*")
  19. .setHandshakeHandler(new MyHandshakeHandler())
  20. .addInterceptors(new SessionAuthHandshakeInterceptor())
  21. .withSockJS();
  22. }
  23. }

拦截器

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.springframework.http.server.ServerHttpRequest;
  3. import org.springframework.http.server.ServerHttpResponse;
  4. import org.springframework.http.server.ServletServerHttpRequest;
  5. import org.springframework.web.socket.WebSocketHandler;
  6. import org.springframework.web.socket.server.HandshakeInterceptor;
  7. import javax.servlet.http.HttpSession;
  8. import java.util.Map;
  9. @Slf4j
  10. public class SessionAuthHandshakeInterceptor implements HandshakeInterceptor {
  11. @Override
  12. public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
  13. HttpSession session = getSession(request);
  14. // if(session == null || session.getAttribute(Constants.SESSION_USER) == null){
  15. // log.error("websocket权限拒绝");
  16. //// return false;
  17. // throw new CmiException("websocket权限拒绝");
  18. // }
  19. // attributes.put(Constants.WEBSOCKET_USER_KEY,session.getAttribute(Constants.SESSION_USER));
  20. return true;
  21. }
  22. @Override
  23. public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
  24. }
  25. private HttpSession getSession(ServerHttpRequest request) {
  26. if (request instanceof ServletServerHttpRequest) {
  27. ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) request;
  28. return serverRequest.getServletRequest().getSession(false);
  29. }
  30. return null;
  31. }
  32. }

处理器

  1. import com.tinet.assistant.gateway.api.entity.UserSession;
  2. import org.apache.commons.lang3.StringUtils;
  3. import org.springframework.http.HttpHeaders;
  4. import org.springframework.http.server.ServerHttpRequest;
  5. import org.springframework.http.server.ServletServerHttpRequest;
  6. import org.springframework.web.socket.WebSocketHandler;
  7. import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpSession;
  10. import java.security.Principal;
  11. import java.util.Map;
  12. import java.util.Objects;
  13. /**
  14. * 握手处理
  15. *
  16. * @author zhaojianyu
  17. */
  18. public class MyHandshakeHandler extends DefaultHandshakeHandler {
  19. private final String sessionName = "session-assitant";
  20. @Override
  21. protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler,
  22. Map<String, Object> attributes) {
  23. HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
  24. String userAgent = servletRequest.getHeader(HttpHeaders.USER_AGENT);
  25. if(StringUtils.isNotEmpty(userAgent)) {
  26. String clientOs = getClientOs(userAgent);
  27. String clientBrowser = getClientBrowser(userAgent);
  28. }
  29. String clientIp = servletRequest.getHeader("X-Forwarded-For");
  30. String host = servletRequest.getHeader(HttpHeaders.ORIGIN);
  31. HttpSession session = servletRequest.getSession(false);
  32. if (Objects.nonNull(session)){
  33. UserSession loginEntity = (UserSession) session.getAttribute(sessionName);
  34. if (loginEntity != null) {
  35. UserContext.set(loginEntity);
  36. }
  37. }
  38. UserSession userSession = new UserSession();
  39. userSession.setUniqueId("00009999zjy");
  40. userSession.setAccountLoginName("啊");
  41. userSession.setAccountId(host);
  42. return userSession;
  43. }
  44. private String getClientOs(String userAgent) {
  45. if (userAgent.contains("Windows")) {
  46. return "Windows";
  47. }
  48. if (userAgent.contains("Mac OS")) {
  49. return "Mac OS";
  50. }
  51. return "Other";
  52. }
  53. private String getClientBrowser(String userAgent) {
  54. if (userAgent.contains("Edge")) {
  55. return "Edge";
  56. }
  57. if (userAgent.contains("Chrome")) {
  58. return "Chrome";
  59. }
  60. if (userAgent.contains("Firefox")) {
  61. return "Firefox";
  62. }
  63. if (userAgent.contains("Safari")) {
  64. return "Safari";
  65. }
  66. return "Other";
  67. }
  68. }

心跳

image.png
https://docs.spring.io/spring-framework/docs/5.1.5.RELEASE/spring-framework-reference/web.html#websocket-stomp-handle-simple-broker

http://stomp.github.io/stomp-specification-1.2.html#Heart-beating