Incoming buffer size cannot be set to Tyrus client

有些话、适合烂在心里 提交于 2019-12-23 19:55:51

问题


I trying to transfer a file bigger than 4M via WebSocket. I'm using org.glassfish.tyrus:tyrus-server:1.13.1 and org.glassfish.tyrus:tyrus-container-grizzly-server:1.13.1 as dependencies.

By default the incoming buffer size is about 4M (see: 8.4. Incoming buffer size). The documentation clearly says what needs to be done if I want to increase the size of the file but still can not change the incoming buffer size. Here is the essence of what I'm trying to do:

CountDownLatch messageLatch = new CountDownLatch(1);

final ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();
ClientManager client = ClientManager.createClient();

client.getProperties().put(ClientProperties.INCOMING_BUFFER_SIZE, new Integer(17_000_000));
Integer tyrusIncomingBufferSize = Utils.getProperty(client.getProperties(), ClientProperties.INCOMING_BUFFER_SIZE, Integer.class);
System.out.println("tyrusIncomingBufferSize: " + tyrusIncomingBufferSize); // 17000000

client.connectToServer(new Endpoint() {
    @Override
    public void onOpen(Session session, EndpointConfig config) {
        try {
            session.addMessageHandler(new MessageHandler.Whole<ByteBuffer>() {

                @Override
                public void onMessage(ByteBuffer message) {
                    System.out.println("Received message: " + message);
                    messageLatch.countDown();
                }
            });

            File pic = new File(TEST_PIC); // the size is more than 4M
            FileInputStream fileReader = new FileInputStream(pic);
            final long sizeOfScreenshotFile = pic.length();
            System.out.println(sizeOfScreenshotFile); // 4734639
            byte[] screenshotData = new byte[(int) sizeOfScreenshotFile];
            fileReader.read(screenshotData);
            fileReader.close();

            ByteBuffer bb = ByteBuffer.wrap(screenshotData);
            session.getBasicRemote().sendBinary(bb);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}, cec, new URI(URI));
messageLatch.await(100, TimeUnit.SECONDS);

But I still have the same error:

17000000
4734639
V 30, 2017 1:39:58 PM org.glassfish.tyrus.core.TyrusEndpointWrapper onError
WARNING: Unexpected error, closing connection.
java.lang.IllegalArgumentException: Buffer overflow.
    at org.glassfish.tyrus.core.Utils.appendBuffers(Utils.java:346)
    at org.glassfish.tyrus.core.TyrusWebSocketEngine$TyrusReadHandler.handle(TyrusWebSocketEngine.java:523)
    at org.glassfish.tyrus.container.grizzly.server.GrizzlyServerFilter$ProcessTask.execute(GrizzlyServerFilter.java:379)
    at org.glassfish.tyrus.container.grizzly.client.TaskProcessor.processTask(TaskProcessor.java:114)
    at org.glassfish.tyrus.container.grizzly.client.TaskProcessor.processTask(TaskProcessor.java:91)
    at org.glassfish.tyrus.container.grizzly.server.GrizzlyServerFilter.handleRead(GrizzlyServerFilter.java:215)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:526)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)

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:51)
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
    at org.glassfish.grizzly.nio.transport.TCPNIOUtils.flushByteBuffer(TCPNIOUtils.java:149)
    at org.glassfish.grizzly.nio.transport.TCPNIOUtils.writeSimpleBuffer(TCPNIOUtils.java:133)
    at org.glassfish.grizzly.nio.transport.TCPNIOAsyncQueueWriter.write0(TCPNIOAsyncQueueWriter.java:126)
    at org.glassfish.grizzly.nio.transport.TCPNIOAsyncQueueWriter.write0(TCPNIOAsyncQueueWriter.java:106)
    at org.glassfish.grizzly.nio.AbstractNIOAsyncQueueWriter.processAsync(AbstractNIOAsyncQueueWriter.java:344)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:108)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:526)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.executeIoEvent(WorkerThreadIOStrategy.java:103)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.executeIoEvent(AbstractIOStrategy.java:89)
    at org.glassfish.grizzly.nio.SelectorRunner.iterateKeyEvents(SelectorRunner.java:415)
    at org.glassfish.grizzly.nio.SelectorRunner.iterateKeys(SelectorRunner.java:384)
    at org.glassfish.grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:348)
    at org.glassfish.grizzly.nio.SelectorRunner.run(SelectorRunner.java:279)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)
-9.8634088E7
V 30, 2017 1:41:38 PM org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [0.0.0.0:8025]
V 30, 2017 1:41:38 PM org.glassfish.tyrus.server.Server stop
INFO: Websocket Server stopped.

I tried to debug the Tyrus project and saw that the incomingBufferSize variable actually remained with the default value.

Does anyone have any idea how can I fix this?


回答1:


You are setting the property in the client, but the exception is clearly thrown on the server.

How are you starting the server? It almost seems like you are using Grizzly standalone - if you do, you can try starting the server with TyrusWebSocketEngine#INCOMING_BUFFER_SIZE property set to 17_000_000 or whatever value you want.

(That can be done by creating the server by using Server(Map, Class ...) or other constructors. See Server class javadoc for more details.




回答2:


Solution (thanks to @Pavel Bucek):

On the Server side:

Map<String,Object> properties = new HashMap<String, Object>();
properties.put("org.glassfish.tyrus.incomingBufferSize", 17000000);
Server server = new org.glassfish.tyrus.server.Server("localhost", 8025, null, 
                                               properties, TestServer.class);


来源:https://stackoverflow.com/questions/44260241/incoming-buffer-size-cannot-be-set-to-tyrus-client

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!