Getting `close 1006 (abnormal closure): unexpected EOF` very frequently

I’m trying to send the following command to wss://fstream.binance.com/stream to subscribe all depth messages:

{"id":9527,"method":"SUBSCRIBE","params":["btcusdt@depth@100ms","ethusdt@depth@100ms","bchusdt@depth@100ms","xrpusdt@depth@100ms","eosusdt@depth@100ms","ltcusdt@depth@100ms","trxusdt@depth@100ms","etcusdt@depth@100ms","linkusdt@depth@100ms","xlmusdt@depth@100ms","adausdt@depth@100ms","xmrusdt@depth@100ms","dashusdt@depth@100ms","zecusdt@depth@100ms","xtzusdt@depth@100ms","bnbusdt@depth@100ms","atomusdt@depth@100ms","ontusdt@depth@100ms","iotausdt@depth@100ms","batusdt@depth@100ms","vetusdt@depth@100ms","neousdt@depth@100ms","qtumusdt@depth@100ms","iostusdt@depth@100ms","thetausdt@depth@100ms","algousdt@depth@100ms","zilusdt@depth@100ms","kncusdt@depth@100ms","zrxusdt@depth@100ms","compusdt@depth@100ms","omgusdt@depth@100ms","dogeusdt@depth@100ms","sxpusdt@depth@100ms","kavausdt@depth@100ms","bandusdt@depth@100ms","rlcusdt@depth@100ms","wavesusdt@depth@100ms","mkrusdt@depth@100ms","snxusdt@depth@100ms","dotusdt@depth@100ms","defiusdt@depth@100ms","yfiusdt@depth@100ms","balusdt@depth@100ms","crvusdt@depth@100ms","trbusdt@depth@100ms","runeusdt@depth@100ms","sushiusdt@depth@100ms","srmusdt@depth@100ms","egldusdt@depth@100ms","solusdt@depth@100ms","icxusdt@depth@100ms","storjusdt@depth@100ms","blzusdt@depth@100ms","uniusdt@depth@100ms","avaxusdt@depth@100ms","ftmusdt@depth@100ms","hntusdt@depth@100ms","enjusdt@depth@100ms","flmusdt@depth@100ms","tomousdt@depth@100ms","renusdt@depth@100ms","ksmusdt@depth@100ms","nearusdt@depth@100ms","aaveusdt@depth@100ms","filusdt@depth@100ms","rsrusdt@depth@100ms","lrcusdt@depth@100ms","maticusdt@depth@100ms","oceanusdt@depth@100ms","cvcusdt@depth@100ms","belusdt@depth@100ms","ctkusdt@depth@100ms","axsusdt@depth@100ms","alphausdt@depth@100ms","zenusdt@depth@100ms","sklusdt@depth@100ms","grtusdt@depth@100ms","1inchusdt@depth@100ms","btcbusd@depth@100ms","akrousdt@depth@100ms","chzusdt@depth@100ms","sandusdt@depth@100ms","ankrusdt@depth@100ms","lunausdt@depth@100ms","btsusdt@depth@100ms","litusdt@depth@100ms","unfiusdt@depth@100ms","dodousdt@depth@100ms","reefusdt@depth@100ms","rvnusdt@depth@100ms","sfpusdt@depth@100ms","xemusdt@depth@100ms","cotiusdt@depth@100ms","chrusdt@depth@100ms","manausdt@depth@100ms","aliceusdt@depth@100ms","hbarusdt@depth@100ms","oneusdt@depth@100ms","linausdt@depth@100ms","stmxusdt@depth@100ms","dentusdt@depth@100ms","celrusdt@depth@100ms","hotusdt@depth@100ms","mtlusdt@depth@100ms","ognusdt@depth@100ms","nknusdt@depth@100ms","scusdt@depth@100ms","dgbusdt@depth@100ms","1000shibusdt@depth@100ms","icpusdt@depth@100ms","bakeusdt@depth@100ms","gtcusdt@depth@100ms","ethbusd@depth@100ms","btcdomusdt@depth@100ms","tlmusdt@depth@100ms","bnbbusd@depth@100ms","adabusd@depth@100ms","xrpbusd@depth@100ms","iotxusdt@depth@100ms","dogebusd@depth@100ms","audiousdt@depth@100ms","rayusdt@depth@100ms","c98usdt@depth@100ms","maskusdt@depth@100ms","atausdt@depth@100ms","solbusd@depth@100ms","fttbusd@depth@100ms","dydxusdt@depth@100ms","1000xecusdt@depth@100ms","galausdt@depth@100ms","celousdt@depth@100ms","arusdt@depth@100ms","klayusdt@depth@100ms","arpausdt@depth@100ms","ctsiusdt@depth@100ms","lptusdt@depth@100ms","ensusdt@depth@100ms","peopleusdt@depth@100ms","antusdt@depth@100ms","roseusdt@depth@100ms","duskusdt@depth@100ms","flowusdt@depth@100ms","imxusdt@depth@100ms","api3usdt@depth@100ms","ancusdt@depth@100ms","gmtusdt@depth@100ms","apeusdt@depth@100ms","bnxusdt@depth@100ms","woousdt@depth@100ms","fttusdt@depth@100ms","jasmyusdt@depth@100ms","darusdt@depth@100ms"]}

but I always get the error close 1006 (abnormal closure): unexpected EOF in a few minutes.

Any ideas? Thanks!

My golang code is as the following:

package main

import (
	"log"
	"os"
	"os/signal"
	"strings"
	"time"

	"github.com/gorilla/websocket"
)

func main() {
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)
	stopCh := make(chan struct{})

	c, _, err := websocket.DefaultDialer.Dial("wss://fstream.binance.com/stream", nil)
	if err != nil {
		log.Fatal("dial:", err)
	}
	defer c.Close()

	err = c.WriteMessage(websocket.TextMessage, []byte(`{"id":9527,"method":"SUBSCRIBE","params":["btcusdt@depth@100ms","ethusdt@depth@100ms","bchusdt@depth@100ms","xrpusdt@depth@100ms","eosusdt@depth@100ms","ltcusdt@depth@100ms","trxusdt@depth@100ms","etcusdt@depth@100ms","linkusdt@depth@100ms","xlmusdt@depth@100ms","adausdt@depth@100ms","xmrusdt@depth@100ms","dashusdt@depth@100ms","zecusdt@depth@100ms","xtzusdt@depth@100ms","bnbusdt@depth@100ms","atomusdt@depth@100ms","ontusdt@depth@100ms","iotausdt@depth@100ms","batusdt@depth@100ms","vetusdt@depth@100ms","neousdt@depth@100ms","qtumusdt@depth@100ms","iostusdt@depth@100ms","thetausdt@depth@100ms","algousdt@depth@100ms","zilusdt@depth@100ms","kncusdt@depth@100ms","zrxusdt@depth@100ms","compusdt@depth@100ms","omgusdt@depth@100ms","dogeusdt@depth@100ms","sxpusdt@depth@100ms","kavausdt@depth@100ms","bandusdt@depth@100ms","rlcusdt@depth@100ms","wavesusdt@depth@100ms","mkrusdt@depth@100ms","snxusdt@depth@100ms","dotusdt@depth@100ms","defiusdt@depth@100ms","yfiusdt@depth@100ms","balusdt@depth@100ms","crvusdt@depth@100ms","trbusdt@depth@100ms","runeusdt@depth@100ms","sushiusdt@depth@100ms","srmusdt@depth@100ms","egldusdt@depth@100ms","solusdt@depth@100ms","icxusdt@depth@100ms","storjusdt@depth@100ms","blzusdt@depth@100ms","uniusdt@depth@100ms","avaxusdt@depth@100ms","ftmusdt@depth@100ms","hntusdt@depth@100ms","enjusdt@depth@100ms","flmusdt@depth@100ms","tomousdt@depth@100ms","renusdt@depth@100ms","ksmusdt@depth@100ms","nearusdt@depth@100ms","aaveusdt@depth@100ms","filusdt@depth@100ms","rsrusdt@depth@100ms","lrcusdt@depth@100ms","maticusdt@depth@100ms","oceanusdt@depth@100ms","cvcusdt@depth@100ms","belusdt@depth@100ms","ctkusdt@depth@100ms","axsusdt@depth@100ms","alphausdt@depth@100ms","zenusdt@depth@100ms","sklusdt@depth@100ms","grtusdt@depth@100ms","1inchusdt@depth@100ms","btcbusd@depth@100ms","akrousdt@depth@100ms","chzusdt@depth@100ms","sandusdt@depth@100ms","ankrusdt@depth@100ms","lunausdt@depth@100ms","btsusdt@depth@100ms","litusdt@depth@100ms","unfiusdt@depth@100ms","dodousdt@depth@100ms","reefusdt@depth@100ms","rvnusdt@depth@100ms","sfpusdt@depth@100ms","xemusdt@depth@100ms","cotiusdt@depth@100ms","chrusdt@depth@100ms","manausdt@depth@100ms","aliceusdt@depth@100ms","hbarusdt@depth@100ms","oneusdt@depth@100ms","linausdt@depth@100ms","stmxusdt@depth@100ms","dentusdt@depth@100ms","celrusdt@depth@100ms","hotusdt@depth@100ms","mtlusdt@depth@100ms","ognusdt@depth@100ms","nknusdt@depth@100ms","scusdt@depth@100ms","dgbusdt@depth@100ms","1000shibusdt@depth@100ms","icpusdt@depth@100ms","bakeusdt@depth@100ms","gtcusdt@depth@100ms","ethbusd@depth@100ms","btcdomusdt@depth@100ms","tlmusdt@depth@100ms","bnbbusd@depth@100ms","adabusd@depth@100ms","xrpbusd@depth@100ms","iotxusdt@depth@100ms","dogebusd@depth@100ms","audiousdt@depth@100ms","rayusdt@depth@100ms","c98usdt@depth@100ms","maskusdt@depth@100ms","atausdt@depth@100ms","solbusd@depth@100ms","fttbusd@depth@100ms","dydxusdt@depth@100ms","1000xecusdt@depth@100ms","galausdt@depth@100ms","celousdt@depth@100ms","arusdt@depth@100ms","klayusdt@depth@100ms","arpausdt@depth@100ms","ctsiusdt@depth@100ms","lptusdt@depth@100ms","ensusdt@depth@100ms","peopleusdt@depth@100ms","antusdt@depth@100ms","roseusdt@depth@100ms","duskusdt@depth@100ms","flowusdt@depth@100ms","imxusdt@depth@100ms","api3usdt@depth@100ms","ancusdt@depth@100ms","gmtusdt@depth@100ms","apeusdt@depth@100ms","bnxusdt@depth@100ms","woousdt@depth@100ms","fttusdt@depth@100ms","jasmyusdt@depth@100ms","darusdt@depth@100ms"]}`))
	if err != nil {
		log.Fatal(err)
	}

	ticker := time.NewTicker(15 * time.Second) // send a unsolicited pong frame every 15 seconds
	begin_time := time.Now()
	for {
		select {
		case <-interrupt:
			log.Println("interrupt")
			close(stopCh)
			ticker.Stop()
			return
		case <-ticker.C:
			log.Printf("%v sending a unsolicited pong frame, has been running for %v seconds", time.Now().Format(time.RFC3339), time.Since(begin_time).Seconds())
			err = c.WriteMessage(websocket.PongMessage, nil)
			if err != nil {
				log.Fatal(err)
			}
		default:
			_, message, err := c.ReadMessage()
			if err != nil {
				log.Fatal("Error reading due to ", err)
			} else {
				txt := string(message)
				if !strings.Contains(txt, "depthUpdate") {
					log.Printf("recv: %s", txt)
				}

			}
		}
	}
}

Disconnection after a few minutes is often caused by failing to comply with the ping pong protocol.

I send an unsolicited pong every 15 seconds, according to the doc:

The websocket server will send a ping frame every 5 minutes. If the websocket server does not receive a pong frame back from the connection within a 15 minute period, the connection will be disconnected. Unsolicited pong frames are allowed.

My way of sending an unsolicited pong every 15 seconds should be valid

An unsolicited pong every 15 seconds should be sufficient to keep the connection alive. Do you receive messages before being disconnected or is there no communication from connection to disconnection?

Moved the process of sending unsolicited pong frames to a standalone goroutine, still has the same issue:

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"os/signal"
	"time"

	"github.com/gorilla/websocket"
)

func main() {
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)
	stopCh := make(chan struct{})

	c, _, err := websocket.DefaultDialer.Dial("wss://fstream.binance.com/stream", nil)
	if err != nil {
		log.Fatal("dial:", err)
	}
	defer c.Close()

	err = c.WriteMessage(websocket.TextMessage, []byte(`{"id":9527,"method":"SUBSCRIBE","params":["btcusdt@depth@100ms","ethusdt@depth@100ms","bchusdt@depth@100ms","xrpusdt@depth@100ms","eosusdt@depth@100ms","ltcusdt@depth@100ms","trxusdt@depth@100ms","etcusdt@depth@100ms","linkusdt@depth@100ms","xlmusdt@depth@100ms","adausdt@depth@100ms","xmrusdt@depth@100ms","dashusdt@depth@100ms","zecusdt@depth@100ms","xtzusdt@depth@100ms","bnbusdt@depth@100ms","atomusdt@depth@100ms","ontusdt@depth@100ms","iotausdt@depth@100ms","batusdt@depth@100ms","vetusdt@depth@100ms","neousdt@depth@100ms","qtumusdt@depth@100ms","iostusdt@depth@100ms","thetausdt@depth@100ms","algousdt@depth@100ms","zilusdt@depth@100ms","kncusdt@depth@100ms","zrxusdt@depth@100ms","compusdt@depth@100ms","omgusdt@depth@100ms","dogeusdt@depth@100ms","sxpusdt@depth@100ms","kavausdt@depth@100ms","bandusdt@depth@100ms","rlcusdt@depth@100ms","wavesusdt@depth@100ms","mkrusdt@depth@100ms","snxusdt@depth@100ms","dotusdt@depth@100ms","defiusdt@depth@100ms","yfiusdt@depth@100ms","balusdt@depth@100ms","crvusdt@depth@100ms","trbusdt@depth@100ms","runeusdt@depth@100ms","sushiusdt@depth@100ms","srmusdt@depth@100ms","egldusdt@depth@100ms","solusdt@depth@100ms","icxusdt@depth@100ms","storjusdt@depth@100ms","blzusdt@depth@100ms","uniusdt@depth@100ms","avaxusdt@depth@100ms","ftmusdt@depth@100ms","hntusdt@depth@100ms","enjusdt@depth@100ms","flmusdt@depth@100ms","tomousdt@depth@100ms","renusdt@depth@100ms","ksmusdt@depth@100ms","nearusdt@depth@100ms","aaveusdt@depth@100ms","filusdt@depth@100ms","rsrusdt@depth@100ms","lrcusdt@depth@100ms","maticusdt@depth@100ms","oceanusdt@depth@100ms","cvcusdt@depth@100ms","belusdt@depth@100ms","ctkusdt@depth@100ms","axsusdt@depth@100ms","alphausdt@depth@100ms","zenusdt@depth@100ms","sklusdt@depth@100ms","grtusdt@depth@100ms","1inchusdt@depth@100ms","btcbusd@depth@100ms","akrousdt@depth@100ms","chzusdt@depth@100ms","sandusdt@depth@100ms","ankrusdt@depth@100ms","lunausdt@depth@100ms","btsusdt@depth@100ms","litusdt@depth@100ms","unfiusdt@depth@100ms","dodousdt@depth@100ms","reefusdt@depth@100ms","rvnusdt@depth@100ms","sfpusdt@depth@100ms","xemusdt@depth@100ms","cotiusdt@depth@100ms","chrusdt@depth@100ms","manausdt@depth@100ms","aliceusdt@depth@100ms","hbarusdt@depth@100ms","oneusdt@depth@100ms","linausdt@depth@100ms","stmxusdt@depth@100ms","dentusdt@depth@100ms","celrusdt@depth@100ms","hotusdt@depth@100ms","mtlusdt@depth@100ms","ognusdt@depth@100ms","nknusdt@depth@100ms","scusdt@depth@100ms","dgbusdt@depth@100ms","1000shibusdt@depth@100ms","icpusdt@depth@100ms","bakeusdt@depth@100ms","gtcusdt@depth@100ms","ethbusd@depth@100ms","btcdomusdt@depth@100ms","tlmusdt@depth@100ms","bnbbusd@depth@100ms","adabusd@depth@100ms","xrpbusd@depth@100ms","iotxusdt@depth@100ms","dogebusd@depth@100ms","audiousdt@depth@100ms","rayusdt@depth@100ms","c98usdt@depth@100ms","maskusdt@depth@100ms","atausdt@depth@100ms","solbusd@depth@100ms","fttbusd@depth@100ms","dydxusdt@depth@100ms","1000xecusdt@depth@100ms","galausdt@depth@100ms","celousdt@depth@100ms","arusdt@depth@100ms","klayusdt@depth@100ms","arpausdt@depth@100ms","ctsiusdt@depth@100ms","lptusdt@depth@100ms","ensusdt@depth@100ms","peopleusdt@depth@100ms","antusdt@depth@100ms","roseusdt@depth@100ms","duskusdt@depth@100ms","flowusdt@depth@100ms","imxusdt@depth@100ms","api3usdt@depth@100ms","ancusdt@depth@100ms","gmtusdt@depth@100ms","apeusdt@depth@100ms","bnxusdt@depth@100ms","woousdt@depth@100ms","fttusdt@depth@100ms","jasmyusdt@depth@100ms","darusdt@depth@100ms"]}`))
	if err != nil {
		log.Fatal(err)
	}

	_, message, err := c.ReadMessage()
	if err != nil {
		log.Fatal("Error reading due to ", err)
	}
	jsonObj := make(map[string]interface{})
	json.Unmarshal(message, &jsonObj)
	if _, ok := jsonObj["error"]; ok {
		log.Fatal("Subscription failed, error: {}", string(message))
	}

	go func() {
		// send a unsolicited pong frame every 15 seconds
		ticker := time.NewTicker(15 * time.Second)
		for {
			select {
			case <-stopCh:
				return
			case <-ticker.C:
				err = c.WriteMessage(websocket.PongMessage, nil)
				if err != nil {
					log.Fatal(err)
				}
			}
		}
	}()

	ticker := time.NewTicker(15 * time.Second)
	begin_time := time.Now()
	count := 0
	for {
		select {
		case <-interrupt:
			log.Println("interrupt")
			close(stopCh)
			return
		case <-ticker.C:
			log.Printf("%v received %v messages, has been running for %v seconds", time.Now().Format(time.RFC3339), count, time.Since(begin_time).Seconds())
		default:
			_, message, err := c.ReadMessage()
			if err != nil {
				log.Fatal("Error reading due to ", err)
			}

			count += 1
		}
	}
}

Bump for the above question.

@tantialex No other error messages, only got close 1006 (abnormal closure): unexpected EOF

Did you receive data, not errors, while you were connected?

@tantialex Yes, I can receive data during connected

It should be network issue, the code above disconnects very frequently, while it can run for hours without disconnection on another machine in AWS

Same problem! Very often disconnect, found it today with older code (2 week ago is working properly)

Some logs may help resolve it:

{"alevel":"info","file":"binance/subscribe.go:193","func":"send","msg":"SUBSCRIBE [eosusdt@kline_1m dogeusdt@kline_1m solusdt@kline_1m dotusdt@kline_1m apeusdt@kline_1m galausdt@kline_1m xrpusdt@kline_1m ftmusdt@kline_1m trxusdt@kline_1m nearusdt@kline_1m bnbusdt@kline_1m adausdt@kline_1m avaxusdt@kline_1m lunausdt@kline_1m bchusdt@kline_1m kncusdt@kline_1m wavesusdt@kline_1m etcusdt@kline_1m ethusdt@kline_1m zilusdt@kline_1m btcusdt@kline_1m ltcusdt@kline_1m gmtusdt@kline_1m xmrusdt@kline_1m]","time":"2022-05-08T16:00:59.242675614Z"}
{"alevel":"info","file":"binance/subscribe.go:193","func":"send","msg":"SUBSCRIBE [etcusdt@kline_1h ethusdt@kline_1h avaxusdt@kline_1h lunausdt@kline_1h bchusdt@kline_1h kncusdt@kline_1h wavesusdt@kline_1h gmtusdt@kline_1h xmrusdt@kline_1h zilusdt@kline_1h btcusdt@kline_1h ltcusdt@kline_1h apeusdt@kline_1h galausdt@kline_1h eosusdt@kline_1h dogeusdt@kline_1h solusdt@kline_1h dotusdt@kline_1h bnbusdt@kline_1h adausdt@kline_1h xrpusdt@kline_1h ftmusdt@kline_1h trxusdt@kline_1h nearusdt@kline_1h]","time":"2022-05-08T16:00:59.445145632Z"}
{"alevel":"info","file":"binance/subscribe.go:193","func":"send","msg":"SUBSCRIBE [zilusdt@bookTicker btcusdt@bookTicker ltcusdt@bookTicker gmtusdt@bookTicker xmrusdt@bookTicker dogeusdt@bookTicker solusdt@bookTicker dotusdt@bookTicker apeusdt@bookTicker galausdt@bookTicker eosusdt@bookTicker ftmusdt@bookTicker trxusdt@bookTicker nearusdt@bookTicker bnbusdt@bookTicker adausdt@bookTicker xrpusdt@bookTicker lunausdt@bookTicker bchusdt@bookTicker kncusdt@bookTicker wavesusdt@bookTicker etcusdt@bookTicker ethusdt@bookTicker avaxusdt@bookTicker]","time":"2022-05-08T16:00:59.647320437Z"}
{"alevel":"info","file":"binance/wss.go:241","func":"listen","msg":"start listen...","time":"2022-05-08T16:00:59.647636295Z"}
{"alevel":"error","file":"binance/wss.go:282","func":"func3","msg":"read all func","time":"2022-05-08T16:01:15.678613945Z"}
{"alevel":"error","file":"binance/wss.go:341","func":"listen","msg":"failed read data: unexpected EOF","time":"2022-05-08T16:01:15.679084297Z"}
{"alevel":"info","file":"binance/wss.go:291","func":"func4","msg":"list loop is finished","time":"2022-05-08T16:01:15.67930843Z"}
{"alevel":"info","file":"binance/wss.go:176","func":"Infof","msg":"public connection closed","time":"2022-05-08T16:01:15.679652188Z"}

Private data with order and positions is working correct!

Hi, I’m having the same issue with Gorilla websockets when subscribing to more than ~200 streams at once. I found out that this behaviour is somehow tied to the WriteBufferSize, but there are more problems. The error message is basically an unexpected EOF at WriteBufferSize.

  1. When your message is larger than the WriteBufferSize it will return an EOF, because I assume binance websockets do not support fragmented messages.
  2. When your message is bigger than 4096 bytes it will take insanely long time to actually process the subscribe request. In range between 4KB and 8KB it will take up to about a minute, more than 8KB and I couldn’t even bother to wait to check how long exactly it takes. I always set my WriteBufferSize to be equal to my message size, because if it’s smaller it will get fragmented(I suppose) and EOF error will be returned.

I found a guy who reported the same issue but in .NET: Socket live subscribing server delay

Still no answer, my workaround is to split the message into chunks of max 4096 bytes and send them one by one.

Interesting thing is: Someone here answered that there is a limit of 200 streams per connection, which is actually about as much as you can subscribe to right now in a single request without going above the magical 4096 bytes. That answer was from July 2021, which is weird, because the documentation states that there was an update in April 2020 “A single connection can listen to a maximum of 1024 streams”. So I guess they increased the maximum number of streams that one connection can listen to, but they didn’t increase the message size that is supported, to be able to actually be large enough to fit 1024 streams.

200 streams per connection

This is not the case for the current websocket connections. The stream limit per connection is 1024 streams.

  1. When your message is bigger than 4096 bytes it will take insanely long time to actually process the subscribe request. In range between 4KB and 8KB it will take up to about a minute, more than 8KB and I couldn’t even bother to wait to check how long exactly it takes. I always set my WriteBufferSize to be equal to my message size, because if it’s smaller it will get fragmented(I suppose) and EOF error will be returned.

Websockets have an inbound message size limits. For Spot, incoming messages are limited to 4KB compressed data and 8KB decompressed data, while Futures incoming messages are limited to 1KB compressed data and 4KB decompressed data. I do suggest taking these bounds into consideration before sending messages to the websocket.

1 Like

Hi, thanks for answering, what you’re saying about those limits seems to be true and consistent with reality, but I haven’t seen any mention about that in the documentation (Binance API Documentation). Could you provide a source of such information?

Could you provide a source of such information?

Unfortunately I do not have a public source for such statement.

1 Like

Thank you very much anyways, now I at least know why this is happening and that it’s not a bug on either side.

I have the same here with another exchange. Using Go too. Tried a lot of suggestions without success. Ping, WriteBufferSize. It closes after ±36min.

I also encountered this error when I used gorilla/websocket to subscribe to the order book data of 1257 trading pairs of Binance spot:
close 1006 (abnormal closure): unexpected EOF

Phenomenon:
When subscribing one symbol, it behaves normally, and the depth stream data is consistent with Binance.
When subscribing 1257 symbols, there is no error message within 21 minutes, and most connections have 1006 errors exactly at 21 minutes. (Repeated test still the same) And I saved the pushed messages to files and found that about 90% of the data may be lost.

After troubleshooting, I found that it was caused by my code logic problem.
I used 20 connections, 50 as a group to send a subscription message, a total of 26 times, and each connection subscribed to 50~100 order book streams.
My expected logic: After receiving the subscription success message, request rest api for 1257 pairs in order to obtain a depth snapshot, and then temporarily store it and monitor the depth stream data.
Due to a logical error, the actual execution logic in the program is:
A total of 26 subscriptions were made. After each successful subscription, rest api requests were repeatedly made for 1257 trading pairs;
bug1: It is possible that some trading pairs have obtained snapshots before receiving depth msg;
bug2: 26 requests were repeated for 1257 trading pairs, but actually only one request should be made.

After I found this error, I modified it to the following logic:
Every time a depth message of a trading pair is received, check whether there is a local order book object. If not, request rest api asynchronously and temporarily cache the depth message before the request is completed.
After the rest snapshot is completed, apply the valid cached messages and filter the invalid ones.
After I modified it, it ran for an hour without any errors, and the data saved in the file was normal.
I used the default configuration of gorilla/websocket, without setting the ping/pong processing callback, and without setting any parameters of the Dialer.