package com.kospo.talk.config.ws; import com.kospo.talk.config.interceptor.ChatInfoInterceptor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry; import org.springframework.messaging.simp.broker.SubscriptionRegistry; import org.springframework.messaging.simp.config.ChannelRegistration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.util.AntPathMatcher; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration; import org.springframework.web.socket.handler.WebSocketHandlerDecorator; import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean; @Configuration @EnableWebSocketMessageBroker // 문자 채팅용 @RequiredArgsConstructor @Slf4j public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer { private final ChatInfoInterceptor chatInfoInterceptor; // private final CustomWebSocketHandler customWebSocketHandler; @Value("${rabbitmq.connection.host}") private String host; @Value("${rabbitmq.connection.username}") private String username; @Value("${rabbitmq.connection.password}") private String password; @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/stomp/talk", "/stomp/file") .setAllowedOriginPatterns("*") .withSockJS() .setHeartbeatTime(20000) .setStreamBytesLimit(512 * 1024) // 5MB .setHttpMessageCacheSize(1000) .setWebSocketEnabled(true) .setSessionCookieNeeded(true) .setDisconnectDelay(15000); // 연결 해지시 체크 시간 registry.addEndpoint("/stomp/ws") .setAllowedOriginPatterns("*"); } @Override public void configureMessageBroker(MessageBrokerRegistry config) { log.debug("websocketbrokerConfigurer"); config.setPathMatcher((new AntPathMatcher("."))); config.setApplicationDestinationPrefixes("/pub"); config.enableStompBrokerRelay("/queue", "/topic", "/exchange", "/amq/queue") .setRelayHost(host) .setRelayPort(61613) .setSystemLogin(username) .setSystemPasscode(password) .setClientLogin(username) .setClientPasscode(password) .setSystemHeartbeatSendInterval(20000) .setSystemHeartbeatReceiveInterval(20000); } @Override public void configureWebSocketTransport(WebSocketTransportRegistration registration) { registration.setMessageSizeLimit(1024 * 1024); // 1mb registration.setSendBufferSizeLimit(1024 * 1024); // 1mb registration.setSendTimeLimit(20 * 1000); // 20 seconds // registration.setDecoratorFactories(customWebSocketHandler); } @Override public void configureClientInboundChannel(ChannelRegistration registration) { registration.interceptors(chatInfoInterceptor); registration.taskExecutor().corePoolSize(16) .maxPoolSize(32) .keepAliveSeconds(360); } @Override public void configureClientOutboundChannel(ChannelRegistration registration) { registration.interceptors(chatInfoInterceptor); registration.taskExecutor().corePoolSize(16) .maxPoolSize(32); } @Bean public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() { ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); container.setMaxTextMessageBufferSize(1024 * 1024); container.setMaxBinaryMessageBufferSize(1024 * 1024); container.setMaxSessionIdleTimeout(60000L); return container; } @Bean public SubscriptionRegistry subscriptionRegistry() { return new DefaultSubscriptionRegistry(); } }