@@ -5,6 +5,7 @@ package recws
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
@@ -44,6 +45,8 @@ type RecConn struct {
|
||||
// KeepAliveTimeout is an interval for sending ping/pong messages
|
||||
// disabled if 0
|
||||
KeepAliveTimeout time.Duration
|
||||
// LogHandler handles all log messages
|
||||
LogHandler func(v LogValues)
|
||||
// NonVerbose suppress connecting/reconnecting messages.
|
||||
NonVerbose bool
|
||||
|
||||
@@ -58,6 +61,18 @@ type RecConn struct {
|
||||
*websocket.Conn
|
||||
}
|
||||
|
||||
// LogValues type includes values for send to logger
|
||||
type LogValues struct {
|
||||
// Msg is main message
|
||||
Msg string
|
||||
// Err is error for separate and display it
|
||||
Err error
|
||||
// Url is connection url
|
||||
Url string
|
||||
// Fatal is tag of fatal error
|
||||
Fatal bool
|
||||
}
|
||||
|
||||
// CloseAndReconnect will try to reconnect.
|
||||
func (rc *RecConn) CloseAndReconnect() {
|
||||
rc.Close()
|
||||
@@ -97,7 +112,7 @@ func (rc *RecConn) Shutdown(writeWait time.Duration) {
|
||||
err := rc.WriteControl(websocket.CloseMessage, msg, time.Now().Add(writeWait))
|
||||
if err != nil && err != websocket.ErrCloseSent {
|
||||
// If close message could not be sent, then close without the handshake.
|
||||
log.Printf("Shutdown: %v", err)
|
||||
rc.log(LogValues{Err: err, Msg: "Shutdown"})
|
||||
rc.Close()
|
||||
}
|
||||
}
|
||||
@@ -314,7 +329,7 @@ func (rc *RecConn) Dial(urlStr string, reqHeader http.Header) {
|
||||
urlStr, err := rc.parseURL(urlStr)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Dial: %v", err)
|
||||
rc.log(LogValues{Msg: "Dial", Err: err, Fatal: true})
|
||||
}
|
||||
|
||||
// Config
|
||||
@@ -342,6 +357,16 @@ func (rc *RecConn) GetURL() string {
|
||||
return rc.url
|
||||
}
|
||||
|
||||
func (rc *RecConn) log(v LogValues) {
|
||||
if rc.LogHandler != nil {
|
||||
rc.LogHandler(v)
|
||||
} else if v.Err != nil {
|
||||
log.Printf("ERROR: %+v: %+v (%+v)\n", v.Msg, v.Err, v.Url)
|
||||
} else {
|
||||
log.Printf("%+v (%+v)\n", v.Msg, v.Url)
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RecConn) getNonVerbose() bool {
|
||||
rc.mu.RLock()
|
||||
defer rc.mu.RUnlock()
|
||||
@@ -404,12 +429,13 @@ func (rc *RecConn) keepAlive() {
|
||||
}
|
||||
|
||||
if err := rc.writeControlPingMessage(); err != nil {
|
||||
log.Println(err)
|
||||
rc.log(LogValues{Err: err})
|
||||
}
|
||||
|
||||
<-ticker.C
|
||||
timeoutOffset := time.Millisecond * 500
|
||||
if time.Since(keepAliveResponse.getLastResponse()) > rc.getKeepAliveTimeout()+timeoutOffset {
|
||||
rc.log(LogValues{Err: errors.New("keepalive timeout"), Msg: "Reconnect", Url: rc.url})
|
||||
rc.CloseAndReconnect()
|
||||
return
|
||||
}
|
||||
@@ -434,15 +460,15 @@ func (rc *RecConn) connect() {
|
||||
|
||||
if err == nil {
|
||||
if !rc.getNonVerbose() {
|
||||
log.Printf("Dial: connection was successfully established with %s\n", rc.url)
|
||||
rc.log(LogValues{Msg: "Dial: connection was successfully established", Url: rc.url})
|
||||
}
|
||||
|
||||
if rc.hasSubscribeHandler() {
|
||||
if err := rc.SubscribeHandler(); err != nil {
|
||||
log.Fatalf("Dial: connect handler failed with %s", err.Error())
|
||||
rc.log(LogValues{Msg: "Dial: connect handler failed", Err: err, Fatal: true})
|
||||
}
|
||||
if !rc.getNonVerbose() {
|
||||
log.Printf("Dial: connect handler was successfully established with %s\n", rc.url)
|
||||
rc.log(LogValues{Msg: "Dial: connect handler was successfully established with %s", Url: rc.url})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,8 +480,7 @@ func (rc *RecConn) connect() {
|
||||
}
|
||||
|
||||
if !rc.getNonVerbose() {
|
||||
log.Println(err)
|
||||
log.Println("Dial: will try again in", nextItvl, "seconds.")
|
||||
rc.log(LogValues{Err: err, Msg: fmt.Sprintf("Dial: will try again in %+v seconds", nextItvl)})
|
||||
}
|
||||
|
||||
time.Sleep(nextItvl)
|
||||
|
||||
Reference in New Issue
Block a user