Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix websocket: close 1006 (abnormal closure): unexpected EOF errors when calling binance.WsCombinedBookTickerServe() #671

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions v2/futures/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,26 @@ func keepAlive(c *websocket.Conn, timeout time.Duration) {
ticker := time.NewTicker(timeout)

lastResponse := time.Now()
c.SetPongHandler(func(msg string) error {

c.SetPingHandler(func(pingData string) error {
// Respond with Pong using the server's PING payload
err := c.WriteControl(
websocket.PongMessage,
[]byte(pingData),
time.Now().Add(time.Second*10), // Short deadline to ensure timely response
)
if err != nil {
return err
}

lastResponse = time.Now()

return nil
})

go func() {
defer ticker.Stop()
for {
deadline := time.Now().Add(10 * time.Second)
err := c.WriteControl(websocket.PingMessage, []byte{}, deadline)
if err != nil {
return
}
<-ticker.C
if time.Since(lastResponse) > timeout {
c.Close()
Expand Down
2 changes: 1 addition & 1 deletion v2/futures/websocket_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var (
// WebsocketTimeout is an interval for sending ping/pong messages if WebsocketKeepalive is enabled
WebsocketTimeout = time.Second * 60
// WebsocketKeepalive enables sending ping/pong messages to check the connection stability
WebsocketKeepalive = false
WebsocketKeepalive = true
// UseTestnet switch all the WS streams from production to the testnet
UseTestnet = false
// WebsocketTimeoutReadWriteConnection is an interval for sending ping/pong messages if WebsocketKeepalive is enabled
Expand Down
19 changes: 13 additions & 6 deletions v2/options/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,26 @@ func keepAlive(c *websocket.Conn, timeout time.Duration) {
ticker := time.NewTicker(timeout)

lastResponse := time.Now()
c.SetPongHandler(func(msg string) error {

c.SetPingHandler(func(pingData string) error {
// Respond with Pong using the server's PING payload
err := c.WriteControl(
websocket.PongMessage,
[]byte(pingData),
time.Now().Add(time.Second*10), // Short deadline to ensure timely response
)
if err != nil {
return err
}

lastResponse = time.Now()

return nil
})

go func() {
defer ticker.Stop()
for {
deadline := time.Now().Add(10 * time.Second)
err := c.WriteControl(websocket.PingMessage, []byte{}, deadline)
if err != nil {
return
}
<-ticker.C
if time.Since(lastResponse) > timeout {
c.Close()
Expand Down
2 changes: 1 addition & 1 deletion v2/options/websocket_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var (
// WebsocketTimeout is an interval for sending ping/pong messages if WebsocketKeepalive is enabled
WebsocketTimeout = time.Second * 60
// WebsocketKeepalive enables sending ping/pong messages to check the connection stability
WebsocketKeepalive = false
WebsocketKeepalive = true
// UseTestnet switch all the WS streams from production to the testnet
UseTestnet = false

Expand Down
23 changes: 17 additions & 6 deletions v2/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@ var wsServe = func(cfg *WsConfig, handler WsHandler, errHandler ErrHandler) (don
// This function will exit either on error from
// websocket.Conn.ReadMessage or when the stopC channel is
// closed by the client.

defer close(doneC)
if WebsocketKeepalive {
// This function overwrites the default ping frame handler
// sent by the websocket API server
keepAlive(c, WebsocketTimeout)
}

// Wait for the stopC channel to be closed. We do that in a
// separate goroutine because ReadMessage is a blocking
// operation.
Expand Down Expand Up @@ -87,19 +91,26 @@ func keepAlive(c *websocket.Conn, timeout time.Duration) {
ticker := time.NewTicker(timeout)

lastResponse := time.Now()
c.SetPongHandler(func(msg string) error {

c.SetPingHandler(func(pingData string) error {
// Respond with Pong using the server's PING payload
err := c.WriteControl(
websocket.PongMessage,
[]byte(pingData),
time.Now().Add(time.Second*10), // Short deadline to ensure timely response
)
if err != nil {
return err
}

lastResponse = time.Now()

return nil
})

go func() {
defer ticker.Stop()
for {
deadline := time.Now().Add(10 * time.Second)
err := c.WriteControl(websocket.PingMessage, []byte{}, deadline)
if err != nil {
return
}
<-ticker.C
if time.Since(lastResponse) > timeout {
c.Close()
Expand Down
2 changes: 1 addition & 1 deletion v2/websocket_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var (
WebsocketTimeout = time.Second * 60

// WebsocketKeepalive enables sending ping/pong messages to check the connection stability
WebsocketKeepalive = false
WebsocketKeepalive = true
// WebsocketTimeoutReadWriteConnection is an interval for sending ping/pong messages if WebsocketKeepalive is enabled
// using for websocket API (read/write)
WebsocketTimeoutReadWriteConnection = time.Second * 10
Expand Down