当前位置: 首页 > 知识库问答 >
问题:

Spring Websocket服务器在发送大量数据时重置连接

东门阳飇
2023-03-14

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

EDIT-下面的end Edit块是服务器端代码和错误。我现在相信错误是在服务器端引起的。我输入了一些时间戳,结果显示客户端在服务器抛出错误之前收到了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));
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)
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;
}
@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个答案

南门棋
2023-03-14

在做了更多的研究之后,我发现这个问题传入缓冲区大小不能设置为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));
 类似资料:
  • 我的在live server上类似这样的环境文件设置。但当我在的时候 错误是 我使用这个主机和密码通过putty访问我的sshhttp://5.100.156.10:2082我很困惑。

  • 我正在编写一个程序,将数据从服务器连续发送到客户端。在这里,我使用示例的时间戳将其发送给连接的多个客户端。我使用多线程来支持多个客户端。我希望每10秒向客户端发送一次时间。但在我的代码中,客户端在收到第一个数据后停止。如何让客户端连续接收数据。我尝试在客户端添加while循环,但这并不可行。有什么建议吗 以下是示例代码:服务器端: 客户端: 我的输出: 客户端所需输出:

  • 我正在使用JavaNetty开发一个高负载tcp应用程序,该应用程序希望300k并发TCP连接。 它在测试服务器上工作得很好,可以到达300k个连接,但当部署到生产服务器时,它只能支持65387个连接,到达这个数量后,客户端将抛出“java.io.IOException:Connection reset by peer”异常。我尝试了很多次,每次当连接数达到65387时,客户端将无法创建连接。 网

  • 问题内容: 似乎有两种方法可以将数据发送到服务器。一种是用于获取像素数组及其8位颜色值。另一种方法是用于发送文件附件。此方法在此处演示。 我想建立一个人们可以保存其画布图纸的站点。哪种方法对我的用户而言更具可扩展性和更快性? 问题答案: 打开选项:使用fabric.js,您可以将fabric.js画布序列化为JSON。 它不仅提供了附加的编辑功能层,而且还允许您执行以下操作(更不用说以后可以编辑其

  • 我们有一个场景,(UDP客户端程序)向(UP服务器)发送UDP数据包 TCP在数据通信开始之前和结束之后执行握手。UDP没有。 那么,运行在上的应用程序失败的原因是否是上的服务器程序没有准备好(关闭)接收UDP数据包?

  • 我一直在做这个项目,其中一个部分包括从Raspberry向我的服务器发送一些数据。但它不能正常工作,我不知道为什么。我试图通过删除“urllib2”并使用“request”来修复错误。但徒劳的是,一切都没有改变。如果有人能帮助我,我会非常感激的。谢谢! PHP代码: python代码: