Socket live subscribing server delay

I’ve noticed that when using the Live subscribing functionality described at Binance API Documentation there is some weird delay from the server when requests exceed ± 4000 bytes.
The subscribe requests can exceed this when a lot of symbols are subscribed in a single request.

When a subscribe request of < 4000 bytes is sent the server responds with success in ± 260ms which is normal latency. However, when the request is > 4000 bytes suddenly there is a 10s delay before the server answers. This happens again when the request size is > 8000 bytes, making the total response time > 20 seconds.

When not using the live subscribing functionality, ie putting all subscribe details in the request URL this doesn’t seem to happen.

Is this some sort of security measure against malicious large requests? Any tips on working with it?

Is this some sort of security measure against malicious large requests? Any tips on working with it?

No such routine is in place, request size is not a factor in the process flow.

When a subscribe request of < 4000 bytes is sent the server responds with success in ± 260ms which is normal latency. However, when the request is > 4000 bytes suddenly there is a 10s delay before the server answers. This happens again when the request size is > 8000 bytes, making the total response time > 20 seconds.

We are unable to reproduce this scenario. I suggest providing the raw request sent and the full url used to connect.

Hm it seems like it’s tied to the socket KeepAlive frame. However, this is something that’s in the Dotnet framework, so I’m not sure if it is an issue in the framework, or an issue of the Binance server socket implementation.

Basically, every ± 4000 bytes it waits for 1 KeepAlive interval. If I set the KeepAlive interval to 10 seconds it will wait 10 seconds every 4000 bytes, If I set it to 1 second it waits 1 second for each 4000 bytes, and if I don’t specify it it is 30 seconds every 4000 bytes (as 30 seconds is the default). I’ve created a minimal example reproducing this (Dotnet 6 Console app):

Changing the KeepAlive interval on line 6 will determine the delay in response. There might be some issue with data being sent in chunks, but again I’m not sure which side has the issue.

Let me know if you can reproduce this and/or you need more info.

Note that I haven’t seen this behavior on other socket servers

It appears to be exclusive to the Dotnet websocket framework.

The KeepAliveInterval controls the timing at which ping/pong messages are sent to the server in moments when no response has been received for a period of time. The correlation between the size of the message and the time elapsed from invoking the method suggests that the client has a pre-determined buffer size of 4096B and processes each chunk at the given interval.

The elapsed time between invocation and the received response is not due to the server or the network, it is most likely a cause of the framework.

That said, you may either communicate the issue with the owner of the framework, or handle buffering subscriptions manually to ensure each message sent is less than the assumed 4096 buffer size.

Alright, I’ll have a look at the dotnet github and see if I can get anyone to look into this.

Another issue I found while investigating this, which I do think is on Binance side, is that the server doesn’t seem to support fragmented messages. As a work around for the previous issue I tried to split the messages up in chucks of 2048 bytes to see if that would help, but when sending data over the socket in multiple parts, with only the last of the chunks signaling endOfMessage the server still seems to interpret the chunks separately, as I get a unexpected EOF in json data error.

Is there a reason for this?

The server expects the full JSON object in a single message, it’s not possible to stream the JSON object.

Hi, have you figured this out? I’m having the same issue with Gorilla websockets for Go language. I have also never seen such behaviour when listening to other websockets. Right now what I do is split my message into <=4096b chunks and send them individually