diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..64f4029 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,15 @@ +name: golangci-lint +on: + push: + pull_request: +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: v1.29 \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..dd9582d --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,26 @@ +run: + concurrency: 10 + tests: true + skip-dirs-use-default: false + timeout: 5m + +linters-settings: + golint: + min-confidence: 0.8 + gofmt: + simplify: true + +linters: + enable: + - gofmt + - gosimple + - govet + - unconvert + - misspell + - goimports + - golint + disable-all: false + fast: false + +issues: + exclude-use-default: false \ No newline at end of file diff --git a/examples/gowebsocket/main.go b/examples/gowebsocket/main.go index 444e491..a208e02 100644 --- a/examples/gowebsocket/main.go +++ b/examples/gowebsocket/main.go @@ -2,21 +2,22 @@ package main import ( "log" - "github.com/sacOO7/gowebsocket" "os" "os/signal" + + "github.com/sacOO7/gowebsocket" ) func main() { interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt) - socket := gowebsocket.New("ws://echo.websocket.org/"); + socket := gowebsocket.New("ws://echo.websocket.org/") socket.ConnectionOptions = gowebsocket.ConnectionOptions{ //Proxy: gowebsocket.BuildProxy("http://example.com"), UseSSL: false, UseCompression: false, - Subprotocols: [] string{"chat", "superchat"}, + Subprotocols: []string{"chat", "superchat"}, } socket.RequestHeader.Set("Accept-Encoding", "gzip, deflate, sdch") @@ -25,29 +26,29 @@ func main() { socket.RequestHeader.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36") socket.OnConnectError = func(err error, socket gowebsocket.Socket) { - log.Fatal("Recieved connect error ", err) - }; + log.Fatal("Received connect error ", err) + } socket.OnConnected = func(socket gowebsocket.Socket) { - log.Println("Connected to server"); - }; + log.Println("Connected to server") + } socket.OnTextMessage = func(message string, socket gowebsocket.Socket) { - log.Println("Recieved message " + message) - }; + log.Println("Received message " + message) + } socket.OnPingReceived = func(data string, socket gowebsocket.Socket) { - log.Println("Recieved ping " + data) - }; + log.Println("Received ping " + data) + } socket.OnDisconnected = func(err error, socket gowebsocket.Socket) { log.Println("Disconnected from server ") - return - }; + } socket.Connect() i := 0 - for (i < 10) { + for i < 10 { socket.SendText("This is my sample test message") i++ } + // nolint: gosimple for { select { case <-interrupt: diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9ceeb25 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/sacOO7/gowebsocket + +go 1.16 + +require ( + github.com/gorilla/websocket v1.4.2 + github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..56fb422 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d h1:5T+fbRuQbpi+WZtB2yfuu59r00F6T2HV/zGYrwX8nvE= +github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d/go.mod h1:L5EJe2k8GwpBoGXDRLAEs58R239jpZuE7NNEtW+T7oo= diff --git a/gowebsocket.go b/gowebsocket.go index 57c622b..6cbaf6f 100644 --- a/gowebsocket.go +++ b/gowebsocket.go @@ -1,39 +1,44 @@ package gowebsocket import ( - "github.com/gorilla/websocket" - "net/http" - "errors" "crypto/tls" + "errors" + "fmt" + "net/http" "net/url" - "sync" - "github.com/sacOO7/go-logger" "reflect" + "sync" "time" + + "github.com/gorilla/websocket" + logging "github.com/sacOO7/go-logger" ) -type Empty struct { +type empty struct { } -var logger = logging.GetLogger(reflect.TypeOf(Empty{}).PkgPath()).SetLevel(logging.OFF) +var logger = logging.GetLogger(reflect.TypeOf(empty{}).PkgPath()).SetLevel(logging.OFF) +// EnableLogging enables the logger func (socket Socket) EnableLogging() { logger.SetLevel(logging.TRACE) } +// GetLogger gets the logger object func (socket Socket) GetLogger() logging.Logger { - return logger; + return logger } +// Socket provides a websocket request type Socket struct { Conn *websocket.Conn WebsocketDialer *websocket.Dialer - Url string + URL string ConnectionOptions ConnectionOptions RequestHeader http.Header OnConnected func(socket Socket) OnTextMessage func(message string, socket Socket) - OnBinaryMessage func(data [] byte, socket Socket) + OnBinaryMessage func(data []byte, socket Socket) OnConnectError func(err error, socket Socket) OnDisconnected func(err error, socket Socket) OnPingReceived func(data string, socket Socket) @@ -44,20 +49,23 @@ type Socket struct { receiveMu *sync.Mutex } +// ConnectionOptions contains connection options type ConnectionOptions struct { UseCompression bool UseSSL bool Proxy func(*http.Request) (*url.URL, error) - Subprotocols [] string + Subprotocols []string } -// todo Yet to be done +// ReconnectionOptions provides options for reconnecting to the websocket +// TODO Yet to be done type ReconnectionOptions struct { } +// New creates a new websocket for the given url func New(url string) Socket { return Socket{ - Url: url, + URL: url, RequestHeader: http.Header{}, ConnectionOptions: ConnectionOptions{ UseCompression: false, @@ -77,16 +85,17 @@ func (socket *Socket) setConnectionOptions() { socket.WebsocketDialer.Subprotocols = socket.ConnectionOptions.Subprotocols } +// Connect connects to the websocket server func (socket *Socket) Connect() { - var err error; + var err error var resp *http.Response socket.setConnectionOptions() - socket.Conn, resp, err = socket.WebsocketDialer.Dial(socket.Url, socket.RequestHeader) + socket.Conn, resp, err = socket.WebsocketDialer.Dial(socket.URL, socket.RequestHeader) if err != nil { logger.Error.Println("Error while connecting to server ", err) - logger.Error.Println("HTTP Response %d status: %s", resp.StatusCode, resp.Status) + logger.Error.Println(fmt.Sprintf("HTTP Response %d status: %s", resp.StatusCode, resp.Status)) socket.IsConnected = false if socket.OnConnectError != nil { socket.OnConnectError(err, *socket) @@ -134,19 +143,22 @@ func (socket *Socket) Connect() { for { socket.receiveMu.Lock() if socket.Timeout != 0 { - socket.Conn.SetReadDeadline(time.Now().Add(socket.Timeout)) + err := socket.Conn.SetReadDeadline(time.Now().Add(socket.Timeout)) + if err != nil { + logger.Error.Println(err) + } } messageType, message, err := socket.Conn.ReadMessage() socket.receiveMu.Unlock() if err != nil { - logger.Error.Println("read:", err) + logger.Error.Println(fmt.Sprintf("read: %s", err)) if socket.OnDisconnected != nil { socket.IsConnected = false socket.OnDisconnected(err, *socket) } return } - logger.Info.Println("recv: %s", message) + logger.Info.Println(fmt.Sprintf("recv: %s", message)) switch messageType { case websocket.TextMessage: @@ -162,15 +174,17 @@ func (socket *Socket) Connect() { }() } +// SendText sends a test message to the server func (socket *Socket) SendText(message string) { - err := socket.send(websocket.TextMessage, [] byte (message)) + err := socket.send(websocket.TextMessage, []byte(message)) if err != nil { logger.Error.Println("write:", err) return } } -func (socket *Socket) SendBinary(data [] byte) { +// SendBinary sends a binary message to the websocket +func (socket *Socket) SendBinary(data []byte) { err := socket.send(websocket.BinaryMessage, data) if err != nil { logger.Error.Println("write:", err) @@ -178,19 +192,20 @@ func (socket *Socket) SendBinary(data [] byte) { } } -func (socket *Socket) send(messageType int, data [] byte) error { +func (socket *Socket) send(messageType int, data []byte) error { socket.sendMu.Lock() err := socket.Conn.WriteMessage(messageType, data) socket.sendMu.Unlock() return err } +// Close closese the websocket func (socket *Socket) Close() { err := socket.send(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) if err != nil { logger.Error.Println("write close:", err) } - socket.Conn.Close() + _ = socket.Conn.Close() if socket.OnDisconnected != nil { socket.IsConnected = false socket.OnDisconnected(err, *socket) diff --git a/utils.go b/utils.go index d8702eb..907ab21 100644 --- a/utils.go +++ b/utils.go @@ -1,13 +1,14 @@ package gowebsocket import ( + "log" "net/http" "net/url" - "log" ) -func BuildProxy(Url string) func(*http.Request) (*url.URL, error) { - uProxy, err := url.Parse(Url) +// BuildProxy creates an http proxy +func BuildProxy(rawURL string) func(*http.Request) (*url.URL, error) { + uProxy, err := url.Parse(rawURL) if err != nil { log.Fatal("Error while parsing url ", err) }