All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cudoy.framework.websocket.WebSocketAutoConfiguration Maven / Gradle / Ivy

The newest version!
package com.cudoy.framework.websocket;

import com.cudoy.framework.core.annotation.RsWebsocket;
import com.cudoy.framework.core.utils.StringUtils;
import com.cudoy.framework.websocket.interceptor.DefaultSpringWebSocketHandlerInterceptor;
import com.cudoy.framework.websocket.interceptor.SpringWebSocketHandlerInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.servlet.resource.ResourceResolver;
import org.springframework.web.servlet.resource.ResourceResolverChain;
import org.springframework.web.servlet.resource.VersionResourceResolver;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.*;
import org.springframework.web.socket.server.HandshakeHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Configuration
public class WebSocketAutoConfiguration{

    @EnableWebSocket
    @Configuration
    public class WebSocketConfiguration implements WebSocketConfigurer{

        private Logger logger = LoggerFactory.getLogger(WebSocketAutoConfiguration.class);

        @Value("${spring.web.token.name:_token}")
        private String tokenName;

        @Value("${server.servlet.context-path:/}")
        private String contextPath;

        @Autowired
        private DefaultListableBeanFactory beanFactory;

        @Autowired(required = false)
        private ResourceHttpRequestHandler resourceHttpRequestHandler;

        @Autowired
        private ResourceProperties resourceProperties;

//        @Bean
//        public WebSocketFilter webSocketFilter(){
//            return new WebSocketFilter();
//        }

        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

            VersionResourceResolver resourceResolver = getVersionResourceResolver(resourceProperties);
            DefaultResourceResolverChain chain = new DefaultResourceResolverChain(resourceHttpRequestHandler != null?resourceHttpRequestHandler.getResourceResolvers():new ArrayList());


            Map map = beanFactory.getBeansWithAnnotation(RsWebsocket.class);
            List printed = new ArrayList();
            for(Object object : map.values()){
                RsWebsocket socket = object.getClass().getAnnotation(RsWebsocket.class);

                List interceptors = new ArrayList();
                if(socket.interceptor() != null) {
                    for(Class clazz : socket.interceptor()){
                        if (clazz != null && SpringWebSocketHandlerInterceptor.class.isAssignableFrom(clazz)) {
                            try {
                                SpringWebSocketHandlerInterceptor handshakeInterceptor = (SpringWebSocketHandlerInterceptor)clazz.newInstance();
                                handshakeInterceptor.setTokenName(tokenName);
                                interceptors.add(handshakeInterceptor);
                            } catch (InstantiationException e) {
                                e.printStackTrace();
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                if(interceptors.isEmpty()) {
                    SpringWebSocketHandlerInterceptor interceptor = new DefaultSpringWebSocketHandlerInterceptor();
                    interceptor.setTokenName(tokenName);
                    interceptors.add(interceptor);
                }
                WebSocketHandlerRegistration registration = registry.addHandler((WebSocketHandler)object, socket.url());

                registration.addInterceptors(interceptors.toArray(new HandshakeInterceptor[interceptors.size()]));

                registration.setAllowedOrigins(socket.allowedOrigins());

                if(socket.handshakeHandler() != null && HandshakeHandler.class.isAssignableFrom(socket.handshakeHandler())){
                    try{
                        HandshakeHandler handshakeHandler = (HandshakeHandler)socket.handshakeHandler().newInstance();
                        registration.setHandshakeHandler(handshakeHandler);
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
                if(!StringUtils.isEmpty(socket.sockJS())){
                    String sockjs = socket.sockJS();
                    if (!socket.absolute()) {
                        if(resourceHttpRequestHandler != null){
                            String temp = resourceResolver.resolveUrlPath(sockjs, resourceHttpRequestHandler.getLocations(), chain);
                            if (!StringUtils.isEmpty(temp)){
                                sockjs = temp;
                            }
                        }
                        if (!StringUtils.isEmpty(contextPath) && !"/".equals(contextPath)) {
                            sockjs = contextPath + sockjs;
                        }
                    }
                    if(!printed.contains(sockjs)) {
                        printed.add(sockjs);
                        logger.warn("register sockJs is :" + sockjs);
                    }
                    registration.withSockJS().setClientLibraryUrl(sockjs);
                }

//            registry.addHandler((WebSocketHandler)object, socket.url())
//                    .setAllowedOrigins("*")
//                    .addInterceptors(new WebSocketHandlerInterceptor())
//                    .withSockJS()
//                    .setClientLibraryUrl("/websocket/sockjs.js");

                logger.info("Register : " + socket.url() + ">" + object);
            }
        }

        private VersionResourceResolver getVersionResourceResolver(ResourceProperties resourceProperties) {
            ResourceProperties.Chain chain = resourceProperties.getChain();
            ResourceProperties.Strategy properties = chain.getStrategy();
            VersionResourceResolver resolver = new VersionResourceResolver();
            if (properties.getFixed().isEnabled()) {
                String version = properties.getFixed().getVersion();
                String[] paths = properties.getFixed().getPaths();
                resolver.addFixedVersionStrategy(version, paths);
            }
            if (properties.getContent().isEnabled()) {
                String[] paths = properties.getContent().getPaths();
                resolver.addContentVersionStrategy(paths);
            }
            return resolver;
        }


        class DefaultResourceResolverChain implements ResourceResolverChain {

            private final List resolvers = new ArrayList<>();

            private int index = -1;


            public DefaultResourceResolverChain(@Nullable List resolvers) {
                if (resolvers != null) {
                    this.resolvers.addAll(resolvers);
                }
            }


            @Override
            @Nullable
            public Resource resolveResource(
                    @Nullable HttpServletRequest request, String requestPath, List locations) {

                ResourceResolver resolver = getNext();
                if (resolver == null) {
                    return null;
                }

                try {
                    return resolver.resolveResource(request, requestPath, locations, this);
                }
                finally {
                    this.index--;
                }
            }

            @Override
            @Nullable
            public String resolveUrlPath(String resourcePath, List locations) {
                ResourceResolver resolver = getNext();
                if (resolver == null) {
                    return null;
                }

                try {
                    return resolver.resolveUrlPath(resourcePath, locations, this);
                }
                finally {
                    this.index--;
                }
            }

            @Nullable
            private ResourceResolver getNext() {
                Assert.state(this.index <= this.resolvers.size(),
                        "Current index exceeds the number of configured ResourceResolvers");

                if (this.index == (this.resolvers.size() - 1)) {
                    return null;
                }
                this.index++;
                return this.resolvers.get(this.index);
            }

        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy