我试图通过WebSocket传输大于4M的文件。我正在使用org.glassfish.tyrus:tyrus-server:1.13.1
和org.glassfish.tyrus:tyrus-container-grizzly-server:1.13.1
作为依赖项。
默认情况下,传入的缓冲区大小约为4m(请参阅:8.4。输入缓冲区大小(。文档清楚地说明,如果我想增加文件的大小,但仍然无法更改传入的缓冲区大小,该怎么办。这是我要做的事情的本质:
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);
但我仍然有相同的错误:
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.
我尝试调试Tyrus项目,并发现incomingBufferSize
变量实际上保留在默认值中。
有人知道我该如何解决?
您是在客户端中设置属性,但是显然会在服务器上抛出例外。
您如何启动服务器?看来您正在使用灰色独立的人 - 如果这样做,可以尝试使用TyrusWebSocketEngengine#incoming_buffer_size属性设置为17_000_000
或您想要的任何值。
(可以通过使用服务器(MAP,类...(或其他构造函数来创建服务器。有关更多详细信息,请参见Server Class Javadoc。
解决方案(感谢@pavel bucek(:
在服务器端:
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);