Merge pull request #2 from loeffel-io/feature/keep-alive
fixed data race
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
package recws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type keepAliveResponse struct {
|
||||||
|
lastResponse time.Time
|
||||||
|
sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *keepAliveResponse) setLastResponse() {
|
||||||
|
k.Lock()
|
||||||
|
defer k.Unlock()
|
||||||
|
|
||||||
|
k.lastResponse = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *keepAliveResponse) getLastResponse() time.Time {
|
||||||
|
k.RLock()
|
||||||
|
defer k.RUnlock()
|
||||||
|
|
||||||
|
return k.lastResponse
|
||||||
|
}
|
||||||
@@ -308,27 +308,33 @@ func (rc *RecConn) getKeepAliveTimeout() time.Duration {
|
|||||||
return rc.KeepAliveTimeout
|
return rc.KeepAliveTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rc *RecConn) writeControlPingMessage() error {
|
||||||
|
rc.mu.Lock()
|
||||||
|
defer rc.mu.Unlock()
|
||||||
|
|
||||||
|
return rc.Conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(10*time.Second))
|
||||||
|
}
|
||||||
|
|
||||||
func (rc *RecConn) keepAlive() {
|
func (rc *RecConn) keepAlive() {
|
||||||
var (
|
var (
|
||||||
lastResponse = time.Now()
|
keepAliveResponse = new(keepAliveResponse)
|
||||||
ticker = time.NewTicker(rc.getKeepAliveTimeout())
|
ticker = time.NewTicker(rc.getKeepAliveTimeout())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
rc.mu.Lock()
|
||||||
rc.Conn.SetPongHandler(func(msg string) error {
|
rc.Conn.SetPongHandler(func(msg string) error {
|
||||||
lastResponse = time.Now()
|
keepAliveResponse.setLastResponse()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
rc.mu.Unlock()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if err := rc.Conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(10*time.Second)); err != nil {
|
rc.writeControlPingMessage()
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
<-ticker.C
|
<-ticker.C
|
||||||
if time.Now().Sub(lastResponse) > rc.getKeepAliveTimeout() {
|
if time.Now().Sub(keepAliveResponse.getLastResponse()) > rc.getKeepAliveTimeout() {
|
||||||
rc.closeAndReconnect()
|
rc.closeAndReconnect()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user