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

本功能在以下项目中添加,其它相关的注释,也在此项目中
https://blog.csdn.net/qq_41712271/article/details/115217344?spm=1001.2014.3001.5501

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


 


版权声明:本文为qq_41712271原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。