Codebase list golang-github-tmc-grpc-websocket-proxy / 3cfed13
Merge pull request #21 from TvdBrink/ping_pong Allow usage of the ping and pong handling of Gorilla websocket. Travis Cline authored 4 years ago GitHub committed 4 years ago
1 changed file(s) with 41 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
55 "io"
66 "net/http"
77 "strings"
8 "time"
89
910 "github.com/gorilla/websocket"
1011 "github.com/sirupsen/logrus"
3334 tokenCookieName string
3435 requestMutator RequestMutatorFunc
3536 headerForwarder func(header string) bool
37 pingInterval time.Duration
38 pingWait time.Duration
39 pongWait time.Duration
3640 }
3741
3842 // Logger collects log messages.
9397 func WithLogger(logger Logger) Option {
9498 return func(p *Proxy) {
9599 p.logger = logger
100 }
101 }
102
103 // WithPingControl allows specification of ping pong control. The interval
104 // parameter specifies the pingInterval between pings. The allowed wait time
105 // for a pong response is (pingInterval * 10) / 9.
106 func WithPingControl(interval time.Duration) Option {
107 return func(proxy *Proxy) {
108 proxy.pingInterval = interval
109 proxy.pongWait = (interval * 10) / 9
110 proxy.pingWait = proxy.pongWait / 6
96111 }
97112 }
98113
210225
211226 // read loop -- take messages from websocket and write to http request
212227 go func() {
228 if p.pingInterval > 0 && p.pingWait > 0 && p.pongWait > 0 {
229 conn.SetReadDeadline(time.Now().Add(p.pongWait))
230 conn.SetPongHandler(func(string) error { conn.SetReadDeadline(time.Now().Add(p.pongWait)); return nil })
231 }
213232 defer func() {
214233 cancelFn()
215234 }()
241260 }
242261 }
243262 }()
263 // ping write loop
264 if p.pingInterval > 0 && p.pingWait > 0 && p.pongWait > 0 {
265 go func() {
266 ticker := time.NewTicker(p.pingInterval)
267 defer func() {
268 ticker.Stop()
269 conn.Close()
270 }()
271 for {
272 select {
273 case <-ctx.Done():
274 p.logger.Debugln("ping loop done")
275 return
276 case <-ticker.C:
277 conn.SetWriteDeadline(time.Now().Add(p.pingWait))
278 if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
279 return
280 }
281 }
282 }
283 }()
284 }
244285 // write loop -- take messages from response and write to websocket
245286 scanner := bufio.NewScanner(responseBodyR)
246287