socket.io-client-java icon indicating copy to clipboard operation
socket.io-client-java copied to clipboard

Transport close when using 2.1.0 client send big message to 4.5.2 NodeJS server

Open conan13101998 opened this issue 3 years ago • 6 comments

Describe the bug When i try to send message to NodeJS Socket.io Server, small message (< 32MB) is succeed but when payload more than 32MB => disconnect event fired with reason transport close. Sometime it send 1st big message succeed and another fail because timeout (client auto reconnect after disconnected)

Note: I also implemented ACK in both server and client

To Reproduce

Socket.IO server version: 4.5.2 with Express

Server

import { Server } from "socket.io";

const io = new Server(http, {
	cors: {
		origin: "*"
	},
	maxHttpBufferSize: 1e8,
	pingTimeout: 60000,
	pingInterval: 60000,
	upgradeTimeout: 30000,
	transport: ["websocket", "polling"]
})

Socket.IO java client version: 2.1.0

Client

public class MyApplication {
    public static void main(String[] args) throws URISyntaxException {
        IO.Options options = IO.Options.builder().build();
        Socket socket = IO.socket("http://localhost:8081", options);
        socket.connect();
        socket.on(Socket.EVENT_DISCONNECT, msg -> log.info("Disconnected with socket server. Reason: {}", msg));
	String msg = generateStringSize(1024 * 1024 * 32);
	for(int i=0; i<10; i++) {
		socket.emit("test", msg, new AckWithTimeout(20000) {
			@Override
			public void onSuccess(Object ...args) {
				log.info("Send succeed");
			}
			
			@Override
			public void onTimeout() {
				log.info("Send failed");
			}
		});
	}
	socket.close();
    }

    private String generateStringSize(int bytes) {
	    StringBuilder builder = new StringBuiler;
	    for(int i=0; i<bytes/2; i++) {
		    builder.append("a");
	    }
	    return builder.toString();
    }
}

conan13101998 avatar Oct 19 '22 03:10 conan13101998

Hi! You are right, we need to take in account the maxPayload field sent by the server, like the JS client: https://github.com/socketio/engine.io-client/commit/46fdc2f0ed352b454614247406689edc9d908927 (added in version 4.5.0)

darrachequesne avatar Oct 19 '22 06:10 darrachequesne

So is there a way we can send a big payload now or will your fix be released in the near future?

conan13101998 avatar Oct 19 '22 07:10 conan13101998

The problem here is that when the client is using HTTP long-polling, the packets are concatenated and the total size is over the maxHttpBufferSize limit of the server.

So as a workaround you can either:

  • increase the maxHttpBufferSize limit of the server
  • add a delay between several bit emits (so that each packet is sent in its own HTTP request)
  • or force the client to use WebSocket (with the transports option)

darrachequesne avatar Oct 19 '22 07:10 darrachequesne

I have tried all methods you said:

  • Increase maxHttpBufferSize: in server i configured maxHttpBufferSize to 1e8 ~ 100MB, it's much more bigger than 32MB but why i still faced the transport close error
  • Force use WebSocket: i just tried options.transport = new String[]{"websocket"} in java client but no change in result. Still transport close
  • Add a delay between emits: Use semaphore to wait till the message is delivered to server or timeout before emit next message also can't solve the problem

conan13101998 avatar Oct 19 '22 07:10 conan13101998

i have same problem but im using java server. have you found any solution ?

ixi0n3k avatar Dec 11 '23 17:12 ixi0n3k

@conan13101998 were you able to figure out any solution for this?

Rits1272 avatar May 10 '24 14:05 Rits1272