websocket http握手拦截器 介绍和使用

本功能在以下项目中添加,其它相关的注释,也在此项目中
springboot整合websocket基础入门,常见注解使用 Demo (基于stomp协议发布订阅方式实现)_nginx配置stomp协议推送-CSDN博客

1、编写一个类,实现一个接口HandshakeInterceptor,注意没有加 @Component

package cn.huawei.interceptor;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * 注意这里没有加 @Component,否则会报错,可能是加载顺序的关系,没有详细研究
 * 调用的时候,使用 new DiyWoShouLanJieQi() 的方式
 */
public class DiyWoShouLanJieQi implements HandshakeInterceptor {

    /**
     * 在握手之前执行该方法, 继续握手返回true, 中断握手返回false
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {

        if(serverHttpRequest instanceof ServletServerHttpRequest){
            ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) serverHttpRequest;
            //获取sessionId传递
            HttpSession session =  serverRequest.getServletRequest().getSession();
            String sessionId = session.getId();
            map.put("sessionId",sessionId);
            System.out.println("握手拦截器: beforeHandshake:"+sessionId);
        }

        return true;
    }

    /**
     * 在握手之后执行该方法
     */
    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {

        if(serverHttpRequest instanceof ServletServerHttpRequest){
            ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) serverHttpRequest;
            //获取sessionId传递
            HttpSession session =  serverRequest.getServletRequest().getSession();
            String sessionId = session.getId();
            System.out.println("握手拦截器: afterHandshake:"+sessionId);
        }
    }
}

WebsocketConfig添加拦截器 addInterceptors(new HttpHandShakeIntecepter())

package cn.huawei.config;
import cn.huawei.interceptor.DiyWoShouLanJieQi;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    public void registerStompEndpoints(StompEndpointRegistry registry) {

        registry.addEndpoint("/endpoint-websocket")
                // 配置拦截器
                .addInterceptors(new DiyWoShouLanJieQi())
                .setAllowedOrigins("*")
                .withSockJS();
    }

    public void configureMessageBroker(MessageBrokerRegistry registry) {

        registry.enableSimpleBroker("/topic_1", "/topic_2", "/topic_3");

        registry.setApplicationDestinationPrefixes("/server_1", "/server_2");
    }
}

3 在两个监听器里面获取到拦截器传递的参数

package cn.huawei.listener;

import org.springframework.context.ApplicationListener;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectEvent;

/**
 * 监听器演示
 * 建立连接事件
 */
@Component
public class ConnectEventListener implements ApplicationListener<SessionConnectEvent>{

	public void onApplicationEvent(SessionConnectEvent event) {

		StompHeaderAccessor headerAccessor =  StompHeaderAccessor.wrap(event.getMessage());
		System.out.println("【ConnectEventListener监听器事件 类型】"+headerAccessor.getCommand().getMessageType());

		Object sessionId = headerAccessor.getSessionAttributes().get("sessionId");
		System.out.println("【ConnectEventListener监听器事件 获取sessionId为】"+sessionId);
	}
}
package cn.huawei.listener;

import org.springframework.context.ApplicationListener;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionSubscribeEvent;

/**
 * 监听器演示
 * 订阅事件
 */
@Component
public class SubscribeEventListener implements ApplicationListener<SessionSubscribeEvent>{

	public void onApplicationEvent(SessionSubscribeEvent event) {

		StompHeaderAccessor headerAccessor =  StompHeaderAccessor.wrap(event.getMessage());
		System.out.println("【SubscribeEventListener监听器事件 类型】"+headerAccessor.getCommand().getMessageType());

		Object sessionId = headerAccessor.getSessionAttributes().get("sessionId");
		System.out.println("【SubscribeEventListener 监听器类 获取sessionId为】"+sessionId);
	}
}

4 启用客户端开始测试,在springboot的控制台,可以看出执行的顺序和结果

握手拦截器: beforeHandshake:2F31F2B59E534C8FEF5D972E62291DB3
握手拦截器: afterHandshake:2F31F2B59E534C8FEF5D972E62291DB3
【ConnectEventListener监听器事件 类型】CONNECT
【ConnectEventListener监听器事件 获取sessionId为】2F31F2B59E534C8FEF5D972E62291DB3
【SubscribeEventListener监听器事件 类型】SUBSCRIBE
【SubscribeEventListener 监听器类 获取sessionId为】2F31F2B59E534C8FEF5D972E62291DB3


 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是在Spring Boot项目中整合WebSocket的步骤,包括拦截器、消息处理器和WebSocket实现类的编写: 1. 添加依赖 在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 编写WebSocket配置类 创建一个WebSocketConfig类,用于配置WebSocket相关的内容,包括注册WebSocket处理器、拦截器等。 ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Autowired private MyWebSocketHandler myWebSocketHandler; @Autowired private MyHandshakeInterceptor myHandshakeInterceptor; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myWebSocketHandler, "/websocket") .addInterceptors(myHandshakeInterceptor); } } ``` 在这个配置类中,我们注册了一个WebSocket处理器和一个握手拦截器WebSocket处理器用于处理WebSocket连接和消息,握手拦截器用于拦截WebSocket连接请求并进行一些处理。 3. 编写WebSocket处理器 创建一个WebSocket处理器类,用于处理WebSocket连接和消息。 ```java @Component public class MyWebSocketHandler extends TextWebSocketHandler { private static final Logger logger = LoggerFactory.getLogger(MyWebSocketHandler.class); private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { logger.info("WebSocket连接建立成功:{}", session.getId()); sessions.put(session.getId(), session); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { logger.info("收到消息:{}", message.getPayload()); // 处理消息 } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { logger.info("WebSocket连接关闭:{},状态:{}", session.getId(), status); sessions.remove(session.getId()); } public static void sendMessage(String sessionId, String message) throws IOException { WebSocketSession session = sessions.get(sessionId); if (session != null && session.isOpen()) { session.sendMessage(new TextMessage(message)); } } } ``` 在这个处理器类中,我们重写了WebSocket处理器的三个方法:afterConnectionEstablished、handleTextMessage和afterConnectionClosed。afterConnectionEstablished方法在WebSocket连接建立成功后被调用,handleTextMessage方法用于处理收到的消息,afterConnectionClosed方法在WebSocket连接关闭后被调用。 4. 编写握手拦截器 创建一个握手拦截器类,用于拦截WebSocket连接请求并进行一些处理。 ```java @Component public class MyHandshakeInterceptor implements HandshakeInterceptor { private static final Logger logger = LoggerFactory.getLogger(MyHandshakeInterceptor.class); @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { logger.info("WebSocket握手拦截器:beforeHandshake"); // 进行一些处理 return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { logger.info("WebSocket握手拦截器:afterHandshake"); } } ``` 在这个握手拦截器类中,我们重写了握手拦截器的两个方法:beforeHandshake和afterHandshake。beforeHandshake方法在WebSocket连接请求到达服务器端时被调用,afterHandshake方法在WebSocket连接握手成功后被调用。 5. 编写WebSocket实现类 创建一个WebSocket实现类,用于实现WebSocket的具体业务逻辑。 ```java @Controller public class MyWebSocketController { @MessageMapping("/hello") @SendTo("/topic/greetings") public String greeting(String message) throws Exception { Thread.sleep(1000); // 模拟处理时间 return "Hello, " + message + "!"; } } ``` 在这个WebSocket实现类中,我们使用了@MessageMapping注解来指定处理消息的路径,使用@SendTo注解来指定返回消息的路径。 6. 测试WebSocket连接 在客户端中,可以使用JavaScript代码来测试WebSocket连接: ```javascript var socket = new WebSocket("ws://localhost:8080/websocket"); socket.onopen = function(event) { console.log("WebSocket连接已建立"); socket.send("Hello, WebSocket!"); }; socket.onmessage = function(event) { console.log("收到消息:" + event.data); }; socket.onclose = function(event) { console.log("WebSocket连接已关闭"); }; ``` 以上就是在Spring Boot项目中整合WebSocket的步骤,包括拦截器、消息处理器和WebSocket实现类的编写。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值