Skip to content

Commit 3cfed13

Browse files
authored
Merge pull request #21 from TvdBrink/ping_pong
Allow usage of the ping and pong handling of Gorilla websocket.
2 parents 3419fae + 9171788 commit 3cfed13

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

wsproxy/websocket_proxy.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io"
77
"net/http"
88
"strings"
9+
"time"
910

1011
"github.com/gorilla/websocket"
1112
"github.com/sirupsen/logrus"
@@ -34,6 +35,9 @@ type Proxy struct {
3435
tokenCookieName string
3536
requestMutator RequestMutatorFunc
3637
headerForwarder func(header string) bool
38+
pingInterval time.Duration
39+
pingWait time.Duration
40+
pongWait time.Duration
3741
}
3842

3943
// Logger collects log messages.
@@ -97,6 +101,17 @@ func WithLogger(logger Logger) Option {
97101
}
98102
}
99103

104+
// WithPingControl allows specification of ping pong control. The interval
105+
// parameter specifies the pingInterval between pings. The allowed wait time
106+
// for a pong response is (pingInterval * 10) / 9.
107+
func WithPingControl(interval time.Duration) Option {
108+
return func(proxy *Proxy) {
109+
proxy.pingInterval = interval
110+
proxy.pongWait = (interval * 10) / 9
111+
proxy.pingWait = proxy.pongWait / 6
112+
}
113+
}
114+
100115
var defaultHeadersToForward = map[string]bool{
101116
"Origin": true,
102117
"origin": true,
@@ -211,6 +226,10 @@ func (p *Proxy) proxy(w http.ResponseWriter, r *http.Request) {
211226

212227
// read loop -- take messages from websocket and write to http request
213228
go func() {
229+
if p.pingInterval > 0 && p.pingWait > 0 && p.pongWait > 0 {
230+
conn.SetReadDeadline(time.Now().Add(p.pongWait))
231+
conn.SetPongHandler(func(string) error { conn.SetReadDeadline(time.Now().Add(p.pongWait)); return nil })
232+
}
214233
defer func() {
215234
cancelFn()
216235
}()
@@ -242,6 +261,28 @@ func (p *Proxy) proxy(w http.ResponseWriter, r *http.Request) {
242261
}
243262
}
244263
}()
264+
// ping write loop
265+
if p.pingInterval > 0 && p.pingWait > 0 && p.pongWait > 0 {
266+
go func() {
267+
ticker := time.NewTicker(p.pingInterval)
268+
defer func() {
269+
ticker.Stop()
270+
conn.Close()
271+
}()
272+
for {
273+
select {
274+
case <-ctx.Done():
275+
p.logger.Debugln("ping loop done")
276+
return
277+
case <-ticker.C:
278+
conn.SetWriteDeadline(time.Now().Add(p.pingWait))
279+
if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
280+
return
281+
}
282+
}
283+
}
284+
}()
285+
}
245286
// write loop -- take messages from response and write to websocket
246287
scanner := bufio.NewScanner(responseBodyR)
247288

0 commit comments

Comments
 (0)