rstoyanchev / spring-websocket-portfolio

740 stars 443 forks source link

sock timeout #40

Open MarkoVranic opened 10 years ago

MarkoVranic commented 10 years ago

Hi,

I am using stomp over sockjs in my spring application. I have two issues with it.

  1. When I use chrome and send big messages and lot of it, I get

org.springframework.web.socket.sockjs.SockJsTransportFailureException: Failed to write SockJsFrame content='a["MESSAGE\ncontent-type:application/json;charset=UT F-8\nsubscription:sub-0\nmes...(truncated)'; nested exception is ClientAbortExce ption: java.io.IOException at org.springframework.web.socket.sockjs.transport.session.AbstractSockJ sSession.writeFrame(AbstractSockJsSession.java:343) at org.springframework.web.socket.sockjs.transport.session.StreamingSock JsSession.flushCache(StreamingSockJsSession.java:70) at org.springframework.web.socket.sockjs.transport.session.AbstractHttpS ockJsSession.tryFlushCache(AbstractHttpSockJsSession.java:310) at org.springframework.web.socket.sockjs.transport.session.AbstractHttpS ockJsSession.startAsyncRequest(AbstractHttpSockJsSession.java:286) at org.springframework.web.socket.sockjs.transport.session.AbstractHttpS ockJsSession.handleSuccessiveRequest(AbstractHttpSockJsSession.java:278) at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpS endingTransportHandler.handleRequestInternal(AbstractHttpSendingTransportHandler .java:81) at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpS endingTransportHandler.handleRequest(AbstractHttpSendingTransportHandler.java:58 ) at org.springframework.web.socket.sockjs.transport.TransportHandlingSock JsService.handleTransportRequest(TransportHandlingSockJsService.java:254) at org.springframework.web.socket.sockjs.support.AbstractSockJsService.h andleRequest(AbstractSockJsService.java:317) at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandle r.handleRequest(SockJsHttpRequestHandler.java:88) at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle( HttpRequestHandlerAdapter.java:51) at org.springframework.web.servlet.DispatcherServlet.doDispatch(Dispatch erServlet.java:938) at org.springframework.web.servlet.DispatcherServlet.doService(Dispatche rServlet.java:870) at org.springframework.web.servlet.FrameworkServlet.processRequest(Frame workServlet.java:961) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServ let.java:863) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkSer vlet.java:837) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl icationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF ilterChain.java:208) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52 ) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl icationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF ilterChain.java:208) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:330) at org.springframework.security.web.access.intercept.FilterSecurityInter ceptor.invoke(FilterSecurityInterceptor.java:118) at org.springframework.security.web.access.intercept.FilterSecurityInter ceptor.doFilter(FilterSecurityInterceptor.java:84) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.access.ExceptionTranslationFilter.do Filter(ExceptionTranslationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.session.SessionManagementFilter.doFi lter(SessionManagementFilter.java:103) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.AnonymousAuthenticati onFilter.doFilter(AnonymousAuthenticationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.servletapi.SecurityContextHolderAwar eRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter .doFilter(RequestCacheAwareFilter.java:45) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.www.BasicAuthenticati onFilter.doFilter(BasicAuthenticationFilter.java:150) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.AbstractAuthenticatio nProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.logout.LogoutFilter.d oFilter(LogoutFilter.java:110) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.request.async.WebAsyncManage rIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerR equestFilter.java:108) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.SecurityContextPersistenceFi lter.doFilter(SecurityContextPersistenceFilter.java:87) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain. doFilter(FilterChainProxy.java:342) at org.springframework.security.web.FilterChainProxy.doFilterInternal(Fi lterChainProxy.java:192) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChai nProxy.java:160) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(D elegatingFilterProxy.java:344) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(Delegat ingFilterProxy.java:261) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl icationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF ilterChain.java:208) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInterna l(HiddenHttpMethodFilter.java:77) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerR equestFilter.java:108) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl icationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF ilterChain.java:208) at org.springframework.web.filter.CharacterEncodingFilter.doFilterIntern al(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerR equestFilter.java:108) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl icationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF ilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV alve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV alve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authentica torBase.java:501) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j ava:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j ava:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java: 950) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal ve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav a:408) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp 11Processor.java:1040) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process( AbstractProtocol.java:607) at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpo int.java:2441) at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoin t.java:2430) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor. java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor .java:615) at java.lang.Thread.run(Thread.java:722) Caused by: ClientAbortException: java.io.IOException at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java: 371) at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:33 3) at org.apache.catalina.connector.Response.flushBuffer(Response.java:568)

   at org.apache.catalina.connector.ResponseFacade.flushBuffer(ResponseFaca

de.java:306) at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapp er.java:160) at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapp er.java:160) at org.springframework.security.web.context.SaveContextOnUpdateOrErrorRe sponseWrapper.flushBuffer(SaveContextOnUpdateOrErrorResponseWrapper.java:135) at org.springframework.http.server.ServletServerHttpResponse.flush(Servl etServerHttpResponse.java:90) at org.springframework.web.socket.sockjs.transport.session.StreamingSock JsSession.writeFrameInternal(StreamingSockJsSession.java:99) at org.springframework.web.socket.sockjs.transport.session.AbstractSockJ sSession.writeFrame(AbstractSockJsSession.java:332) ... 76 more Caused by: java.io.IOException at org.apache.coyote.http11.InternalAprOutputBuffer.flushBuffer(Internal AprOutputBuffer.java:205) at org.apache.coyote.http11.InternalAprOutputBuffer.flush(InternalAprOut putBuffer.java:109) at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp1 1Processor.java:799) at org.apache.coyote.Response.action(Response.java:174) at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java: 366) at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:33 3) at org.apache.catalina.connector.Response.flushBuffer(Response.java:568)

   at org.apache.catalina.connector.ResponseFacade.flushBuffer(ResponseFaca

de.java:306) at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapp er.java:160) at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapp er.java:160) at org.springframework.security.web.context.SaveContextOnUpdateOrErrorRe sponseWrapper.flushBuffer(SaveContextOnUpdateOrErrorResponseWrapper.java:135) at org.springframework.http.server.ServletServerHttpResponse.flush(Servl etServerHttpResponse.java:90) at org.springframework.web.socket.sockjs.transport.session.StreamingSock JsSession.writeFrameInternal(StreamingSockJsSession.java:99) at org.springframework.web.socket.sockjs.transport.session.AbstractSockJ sSession.writeFrame(AbstractSockJsSession.java:332) at org.springframework.web.socket.sockjs.transport.session.StreamingSock JsSession.flushCache(StreamingSockJsSession.java:70) at org.springframework.web.socket.sockjs.transport.session.AbstractHttpS ockJsSession.tryFlushCache(AbstractHttpSockJsSession.java:310) at org.springframework.web.socket.sockjs.transport.session.AbstractHttpS ockJsSession.sendMessageInternal(AbstractHttpSockJsSession.java:297) at org.springframework.web.socket.sockjs.transport.session.AbstractSockJ sSession.sendMessage(AbstractSockJsSession.java:247) at org.springframework.web.socket.handler.ConcurrentWebSocketSessionDeco rator.tryFlushMessageBuffer(ConcurrentWebSocketSessionDecorator.java:121) at org.springframework.web.socket.handler.ConcurrentWebSocketSessionDeco rator.sendMessage(ConcurrentWebSocketSessionDecorator.java:98) at org.springframework.web.socket.messaging.StompSubProtocolHandler.hand leMessageToClient(StompSubProtocolHandler.java:275) at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler. handleMessage(SubProtocolWebSocketHandler.java:306) at org.springframework.messaging.support.ExecutorSubscribableChannel$1.r un(ExecutorSubscribableChannel.java:

I use tomcat 7.0.53. I suspect that some buffer size is small, so messages are broken...

Is there some way for configuring this?

  1. Every 10 minutes(if nothing happens) socket closes. Is there some way for disabling this timeout? Or is this done over heartbeats?

Regards, Marko

rstoyanchev commented 10 years ago

The STOMP layer has a heartbeat that will close the connection if no heartbeat is received but that's for cases where the connection is lost. Sounds like what you want is to close when there are no actual messages on a given STOMP session. You can register a ChannelInterceptor on the "clientInboundChannel" and the "clientOutboundChannel" and keeps track of this. If a session has not had any messages other than heartbeats, send a DISCONNECT on the clientInboundChannel (see how StompSubProtocolHandler does it in afterSessionEnded).

MarkoVranic commented 10 years ago

Hi, Thanks for quick reply. Actually. I want to keep connections even if there is no traffic. Heartbeats are going every 25s and it is fine. There must ne some other reason fo losing connection.

I have debugged my application more today. When I send big mesages and lots of them In chrome I get close simple event with reason permanent. Stack trace says that it was line 1017 of sockjs 0.3.4. Server lost connection. It seems that server is callimg onOpen to already opened client socket. Whar may be the reson for lossing connections?

Basically I am sending messages from thread and simple messages template to my browser which is connexted to controller similar to this example. I configuref only simple broker with endpoints. Can you please suggest what can be the reason for losing connections?

Thank you, Marko On Jun 16, 2014 2:57 PM, "Rossen Stoyanchev" notifications@github.com wrote:

The STOMP layer has a heartbeat that will close the connection if no heartbeat is received but that's for cases where the connection is lost. Sounds like what you want is to close when there are no actual messages on a given STOMP session. You can register a ChannelInterceptor on the "clientInboundChannel" and the "clientOutboundChannel" and keeps track of this. If a session has not had any messages other than heartbeats, send a DISCONNECT on the clientInboundChannel (see how StompSubProtocolHandler does it in afterSessionEnded).

— Reply to this email directly or view it on GitHub https://github.com/rstoyanchev/spring-websocket-portfolio/issues/40#issuecomment-46174333 .