I.K.Picture & IT Info.

[websocket] Java WebSocket 사이즈 제한 늘리기 STOMP 본문

Development/Java/Android

[websocket] Java WebSocket 사이즈 제한 늘리기 STOMP

helpful-intruder 2021. 4. 12. 12:47
반응형

기본적으로 WebSocket은 한번에 64kb 이상 데이터를 보낼 경우 보내지지 않는 경우가 있습니다.

 

이런 경우 여러가지 상황이 생기는데요 

아주 친절한 debug 모드에서는 

  message buffer size limit 65536

이런 형태로 초과되었다고 얘기를 해줄 것 같은데,,

저 같은 경우 일반 모드에서 할 경우 접속 자체가 끊켜버리더군요...

 

그렇기 때문에 소스에 아무 이상이 없는데 보낼 때마다 자꾸 끊킨다 라고생각하면 

사이즈가 넘었나?? 라는 것도 의심해봐야 합니다.

 

 

자 여기서,

일반적으로 메시지 브로커를 통해 WebSocket을 사용했다면 (상속 받은 클래스 AbstractWebSocketMessageBrokerConfigurer)

그냥 아래와 같이 override 코드를 추가하면 된다고 합니다.

@Override
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
        registration.setMessageSizeLimit(160 * 64 * 1024); // default : 64 * 1024
        registration.setSendTimeLimit(100 * 10000); // default : 10 * 10000
        registration.setSendBufferSizeLimit(3* 512 * 1024); // default : 512 * 1024

 

그런데,,

만약, STOMP을 사용했다면...

얘기가 살짝 바뀝니다.. (조금 더 복잡해져요...)

 

STOMP을 사용할 경우 단순히 위 해당 메시지로는 사이즈가 변경되지 않고 

추가로 클래스를 만들어주고 저 함수에 세팅을 해줘야합니다. 

 

일단 만들어야되는 클래스부터 적어보도록 하겠습니다. 

총 2개를 만들어야되는데,

 

먼저, DelegatingIntroductionInterceptor 을 상속한 클래스를 만들어줍니다. 

여기에 실제 사이즈 제한에 대해 적어줍니다. 

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
import org.springframework.web.socket.WebSocketSession;

public class SubProtocolWebSocketHandlerInterceptor extends DelegatingIntroductionInterceptor {

    @Override
    protected Object doProceed(MethodInvocation mi) throws Throwable {
        if(mi.getMethod().getName().equals("afterConnectionEstablished") ) {
            WebSocketSession session = (WebSocketSession) mi.getArguments()[0];
            session.setTextMessageSizeLimit(50*1024*1024);
        }
        return super.doProceed(mi);
    }
}

 

두번째로 만들어야되는 것은 추상 클래스(WebSocketHandlerDecoratorFactory)를 활용한 DecoratorFactory 클래스입니다. 

 

그 다음 아래와 같이 클래스를 하나 더 만들어줍니다.

전 클리스 이름을 AgentWebSocketHandlerDecoratorFactory  로 하였습니다.

import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;
import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.DefaultIntroductionAdvisor;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;

public class AgentWebSocketHandlerDecoratorFactory  implements WebSocketHandlerDecoratorFactory  {
  @Override
  public WebSocketHandler decorate(WebSocketHandler handler) {
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.setTargetClass(AopUtils.getTargetClass(handler));
    proxyFactory.setTargetSource(new SingletonTargetSource(handler));
    proxyFactory.addAdvisor(new DefaultIntroductionAdvisor(new SubProtocolWebSocketHandlerInterceptor()));
    proxyFactory.setOptimize(true);
    proxyFactory.setExposeProxy(true);
    return (WebSocketHandler) proxyFactory.getProxy();
  }
}

 

마지막에 AbstractWebSocketMessageBrokerConfigurer 상속한(설정) 파일에 아래와 같이 

만든 클래스를 세팅해줍니다. 

    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
        registration.setDecoratorFactories(agentWebSocketHandlerDecoratorFactory());
    } 

 

맨 처음 작업한 함수와 동일하지만 

WebSocketTrapsortRegistration에 대한 클래스에 직접 setTextMessageSizeLimit을 설정한 것이 아닌

별도 클래스를 만들어서 작업한 것입니다. 

 

반응형
Comments