AndroidAsync icon indicating copy to clipboard operation
AndroidAsync copied to clipboard

Sending semi-large (~5MB) JSON payloads over web socket not working

Open tab1293 opened this issue 8 years ago • 9 comments

I am trying to send a semi-large JSON payload over a web socket but it doesn't seem to work. The size of the message is about 5MB; it contains some Base64 encoded images. The WebSocket.send(String string) method is not throwing any errors.

Is this a known issue and are there any work arounds? Does it have something to do with the frame size of a websocket message?

@koush

tab1293 avatar Jun 29 '17 05:06 tab1293

After doing some more testing, I found that there is a hard limit on a string that is greater than or equal to 175199 bytes in length. So a string that is 175198 will arrive over the wire using Websocket.send(String string) in tact, but anything greater than that will not.

I know you are probably busy @koush but do you know why this may be happening? Do you need me to provide any more information about how I am testing? If you have an idea what the issue may be I'd be more than happy to help develop a fix for it.

tab1293 avatar Jul 06 '17 02:07 tab1293

No idea. Check what is happening in the WebSocket code. Could also be Android choking on strings over a certain length.

koush avatar Jul 06 '17 04:07 koush

My first suggestion is to make sure that the frame length is being properly parsed/calculated, and work with it from there.

koush avatar Jul 06 '17 04:07 koush

I have a similar problem, I am sending an image as Base64 encoded in parts of 512kB, 5 first parts go without a problem, but after that nothing comes through. And no errors from the send method. Also tried to send it as binary data with the same results. With some android devices the limit where it stops working is even lower. With localhost address there was no issues. @koush have you seen this kind of behaviour?

ghost avatar Oct 11 '17 10:10 ghost

I'm currently having this problem as well, with binary payloads as small as 110 kb.

ghost avatar Feb 05 '19 23:02 ghost

Thanks alot

meandyou2022 avatar Feb 06 '19 21:02 meandyou2022

can this problem solved?

gupengcheng avatar Nov 07 '20 14:11 gupengcheng

I believed to find out the reason why websocket not working when sending large text.

  // File: AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java
 public WebSocketImpl(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
        this(request.getSocket());

        ......

        /**
         * Below method will create a new BufferedDataSink Object and bind the wrong callback
         */
        response.writeHead();

        /**
         * Correct the buffer & callback modified by response.writeHead
         */
        mSink = new BufferedDataSink(mSocket);
        setupParser(false, false);
    }

It lies in WebSocketImpl. In the response.writeHead method, the mSocket's onDataWritable callback is modified by the ChunkedOutputFilter. And after that, when you try sending large text, the mSink will cache part of your text and wait for the next loop. But because the ChunkedOutputFilter has modified the onDataWritable callback, your cached data won't get sent. Thus, the websocket stops working...

A simple way to fix it is to rebind the correct onDataWritable callback, thus I add a new line shortly after response.writeHead:

        /**
         * Correct the buffer & callback modified by response.writeHead
         */
        mSink = new BufferedDataSink(mSocket);

I believe this could fix the problem lasting 5 years long...

dreamer2q avatar Oct 11 '22 14:10 dreamer2q

@dreamer2q I have found the same issue, But your solution is not work. With your solution or without your solution. I send a file about 500KB is ok ,but it will fail to send about 15MB file. The connection will always close about 36 seconds , the Exception message of "onCompleted" is null.

rockmany2000 avatar Jul 08 '23 16:07 rockmany2000