11package binance
22
33import (
4+ "context"
45 "net/http"
56 "net/url"
67 "time"
@@ -28,7 +29,14 @@ func newWsConfig(endpoint string) *WsConfig {
2829 }
2930}
3031
31- var wsServe = func (cfg * WsConfig , handler WsHandler , errHandler ErrHandler ) (doneC , stopC chan struct {}, err error ) {
32+ func wsServe (cfg * WsConfig , handler WsHandler , errHandler ErrHandler ) (doneC , stopC chan struct {}, err error ) {
33+ return wsServeWithConnHandler (cfg , handler , errHandler , nil )
34+ }
35+
36+ type ConnHandler func (context.Context , * websocket.Conn )
37+
38+ // WsServeWithConnHandler serves websocket with custom connection handler, useful for custom keepalive
39+ var wsServeWithConnHandler = func (cfg * WsConfig , handler WsHandler , errHandler ErrHandler , connHandler ConnHandler ) (doneC , stopC chan struct {}, err error ) {
3240 proxy := http .ProxyFromEnvironment
3341 if cfg .Proxy != nil {
3442 u , err := url .Parse (* cfg .Proxy )
@@ -62,6 +70,13 @@ var wsServe = func(cfg *WsConfig, handler WsHandler, errHandler ErrHandler) (don
6270 keepAlive (c , WebsocketTimeout )
6371 }
6472
73+ // Custom connection handling, useful in active keepalive scenarios
74+ if connHandler != nil {
75+ ctx , cancel := context .WithCancel (context .Background ())
76+ defer cancel ()
77+ go connHandler (ctx , c )
78+ }
79+
6580 // Wait for the stopC channel to be closed. We do that in a
6681 // separate goroutine because ReadMessage is a blocking
6782 // operation.
@@ -88,6 +103,21 @@ var wsServe = func(cfg *WsConfig, handler WsHandler, errHandler ErrHandler) (don
88103 return
89104}
90105
106+ func keepAliveHandler (duration time.Duration ) ConnHandler {
107+ return func (ctx context.Context , c * websocket.Conn ) {
108+ ticker := time .NewTicker (duration )
109+ for {
110+ select {
111+ case <- ctx .Done ():
112+ ticker .Stop ()
113+ return
114+ case <- ticker .C :
115+ c .WriteMessage (websocket .PingMessage , []byte {})
116+ }
117+ }
118+ }
119+ }
120+
91121func keepAlive (c * websocket.Conn , timeout time.Duration ) {
92122 ticker := time .NewTicker (timeout )
93123
@@ -137,7 +167,7 @@ var WsGetReadWriteConnection = func(cfg *WsConfig) (*websocket.Conn, error) {
137167 EnableCompression : false ,
138168 }
139169
140- c , _ , err := Dialer .Dial (cfg .Endpoint , nil )
170+ c , _ , err := Dialer .Dial (cfg .Endpoint , * cfg . Header )
141171 if err != nil {
142172 return nil , err
143173 }
0 commit comments