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 extends ResourceResolver> resolvers) {
if (resolvers != null) {
this.resolvers.addAll(resolvers);
}
}
@Override
@Nullable
public Resource resolveResource(
@Nullable HttpServletRequest request, String requestPath, List extends Resource> 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 extends Resource> 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);
}
}
}
}