2017-08-02 48 views
0

我在尝试从Spring Websocket服务器发送数据(托管在Tomcat上)时似乎在尝试发送消息的过程中重置连接。当发送大量的二进制数据时(这里的示例中的字节数为5526584字节),错误似乎会发生得更多,但我已经看到它发生在文本通道上,并且数据量也较少。然而,发送更多5个左右的MB似乎使其相对一致地崩溃。Spring Websocket服务器在发送大量数据时重置连接

编辑 - 下面的结束编辑块是服务器端的代码和错误。我现在认为错误是由服务器端造成的。我输入了一些时间戳,看起来客户端在服务器抛出错误之前收到onClose错误。关闭的原因是缓冲区溢出。下面是代码,我设置WebSocket的容器​​,并启动会话:

WebSocketContainer c = ContainerProvider.getWebSocketContainer(); 


    c.setDefaultMaxTextMessageBufferSize(128000000); // Should we enable these on the client? 
    c.setDefaultMaxBinaryMessageBufferSize(128000000); // Should we enable these on the client? 
    c.setDefaultMaxSessionIdleTimeout(500000); 
    c.setAsyncSendTimeout(50000); 
    session = c.connectToServer(this, config, new URI("wss://" + SERVER + ":" + PORT + WEBSOCKETENDPOINT)); 

后来我打印出会议MaxBuffer大小,他们都被设置为1.28预期。

末编辑

这里是堆栈跟踪:

java.io.IOException: An established connection was aborted by the software in your host machine 
at sun.nio.ch.SocketDispatcher.write0(Native Method) 
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51) 
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) 
at sun.nio.ch.IOUtil.write(IOUtil.java:65) 
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471) 
at org.apache.tomcat.util.net.SecureNioChannel.flush(SecureNioChannel.java:143) 
at org.apache.tomcat.util.net.SecureNioChannel.close(SecureNioChannel.java:494) 
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.close(NioEndpoint.java:1201) 
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doClose(WsRemoteEndpointImplServer.java:167) 
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.close(WsRemoteEndpointImplBase.java:710) 
at org.apache.tomcat.websocket.WsSession.sendCloseMessage(WsSession.java:599) 
at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:480) 
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:313) 
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:258) 
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPartialBytes(WsRemoteEndpointImplBase.java:161) 
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendBinary(WsRemoteEndpointBasic.java:56) 
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.sendBinaryMessage(StandardWebSocketSession.java:202) 
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:107) 
at org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator.tryFlushMessageBuffer(ConcurrentWebSocketSessionDecorator.java:132) 
at org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator.sendMessage(ConcurrentWebSocketSessionDecorator.java:104) 
at myHandlerpart2.handleBinaryMessage(myHandlerpart2.java:252) 
at myHandler.handleMessageFromClient(myHandler.java:200) 
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.handleMessage(SubProtocolWebSocketHandler.java:307) 
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75) 
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.handleMessage(LoggingWebSocketHandlerDecorator.java:56) 
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.handleMessage(ExceptionWebSocketHandlerDecorator.java:58) 
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleBinaryMessage(StandardWebSocketHandlerAdapter.java:120) 
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access$100(StandardWebSocketHandlerAdapter.java:42) 
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$4.onMessage(StandardWebSocketHandlerAdapter.java:87) 
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$4.onMessage(StandardWebSocketHandlerAdapter.java:84) 
at org.apache.tomcat.websocket.WsFrameBase.sendMessageBinary(WsFrameBase.java:576) 
at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageBinary(WsFrameServer.java:122) 
at org.apache.tomcat.websocket.WsFrameBase.processDataBinary(WsFrameBase.java:535) 
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:294) 
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:127) 
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:73) 
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148) 
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54) 
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) 
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) 
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Thread.java:748) 

在我的WebSocket配置者我设置非常宽松的缓冲区和超时

public ServletServerContainerFactoryBean createWebSocketContainer() { 

ServletServerContainerFactoryBean container = new 
ServletServerContainerFactoryBean(); 
container.setMaxTextMessageBufferSize(128000000); //128 MB 
container.setMaxBinaryMessageBufferSize(128000000); //128 MB 
container.setMaxSessionIdleTimeout(500000); 
container.setAsyncSendTimeout(50000); 

return container; 
} 

我还设置了限制SubProtoclHandler

@Override 
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 


    SubProtocolWebSocketHandler test = new SubProtocolWebSocketHandler(new DirectChannel(), clientInboundChannel()); 
    test.setSendBufferSizeLimit(128000000); 
    test.setSendTimeLimit(50000); 
    for(SubProtocolHandler handler : handlers) 
    { 
     test.addProtocolHandler(handler); 
    } 


    MyWebSocketHandshakeHandler handshaker = new MyWebSocketHandshakeHandler(); 


    handshaker.setSupportedProtocols(test.getSubProtocols().toArray(new String[0])); 
    registry.addHandler(test, websocketEndpoint).setHandshakeHandler(handshaker) 
      .addInterceptors(new HttpSessionHandshakeInterceptor()).setAllowedOrigins("*"); 

} 

最后导致该错误的实际发送看起来像这样

byte[] tbuf = null; 
     try { 
      tbuf = jsonMapper.writeValueAsBytes(demoLists.get(stage)); 
      ByteBuffer buf = ByteBuffer.allocate(tbuf.length); 
      buf.put(tbuf); 
      buf.flip(); 
      WebSocketMessage<ByteBuffer> ret = new BinaryMessage(buf); 
      System.out.println("Binary limit: " + session.getBinaryMessageSizeLimit()); 
      System.out.println("Sending bytes: " + ret.getPayloadLength()); 
      if(session.isOpen()) { 
       session.sendMessage(ret); 

      } else { 
       System.out.println("Session is closed already."); 
      } 

有很多代码运动件,所以让我知道如果你需要的任何其他信息。

回答

1

经过更多的研究,我发现这个问题Incoming buffer size cannot be set to Tyrus client这导致我https://tyrus-project.github.io/documentation/1.12/user-guide.html#d0e1197。显然,在客户端上设置默认缓冲区大小不能正常工作。在添加指南后,推荐一切正常工作。

ClientManager client = ClientManager.createClient(c); 
    client.getProperties().put("org.glassfish.tyrus.incomingBufferSize", 128000000); 
    session = client.connectToServer(this, config, new URI("wss://" + SERVER + ":" + PORT + WEBSOCKETENDPOINT)); 
相关问题