Websocket: Restructure files and types (#1859)

* Websocket: Rename stream package

* Websocket: Rename Websocket to Manager

* Websocket: Replace explicit errs with common.NilGuard

* Websocket: Move websocket_types.go to types.go

* Websocket: Minor field comment and alignment in types

* Webosocket: Rename WebsocketConnection to Connection

* Alphapoint: Make gorilla ws import explicit

Just to avoid confusion with our own packages.

* Websocket: Move stream_match to match

* Websocket: Move websocket_connection to connection

* Websocket: Move websocket.go to manager.go

* Websocket: Break out all subscription methods into subscriptions.go

* Websocket: Move connection type into its file

* Websocket: Remove PositionUpdated

Type is not used anywhere

* Kraken: Use local constant for pong

Was the only use of websocket.Pong and doesn't really feel right to
represent kraken's api resp in one of our packages

* Websocket: Move connection sub-types to connection package

* Websocket: Move manager types into manager

* Websocket: Move ConnectionWrapper into manager

* Websocket: Move websocket_test to manager_test

* Websocket: Privatise connectionWrapper

* Websocket: Remaining types into types.go

These really belong somewhere else mostly, but this will do for now

* Websocket: Tidy up connection method vars

* Gofumpt: Moving package imports around

* Websocket: Rename errDuplicateConnectionSetup

* Websocket: Fix duplicate import of gws

* Websocket: Fix gofumpt -extra

* Websocket: Standardise import of gws across other pkgs

* Kraken: Remove unused sub conf consts

These were replaced by the generic Levels and Depth fields on all subs

* Websocket: Privitise ConnectioWrapper fields

* Websocket: inline single use var WebsocketNotAuthenticatedUsingRest

* Websocket: Move documentation to template

* Bithumb: Assertify TestWsHandleData
This commit is contained in:
Gareth Kirwan
2025-04-10 08:25:02 +02:00
committed by GitHub
parent 676b2e0367
commit b4e45e9a1b
119 changed files with 3169 additions and 3056 deletions

View File

@@ -4,27 +4,27 @@ import (
"context"
"net/http"
"github.com/gorilla/websocket"
gws "github.com/gorilla/websocket"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
"github.com/thrasher-corp/gocryptotrader/internal/exchange/websocket"
)
// WsInverseConnect connects to inverse websocket feed
func (by *Bybit) WsInverseConnect() error {
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.CoinMarginedFutures) {
return stream.ErrWebsocketNotEnabled
return websocket.ErrWebsocketNotEnabled
}
by.Websocket.Conn.SetURL(inversePublic)
var dialer websocket.Dialer
var dialer gws.Dialer
err := by.Websocket.Conn.Dial(&dialer, http.Header{})
if err != nil {
return err
}
by.Websocket.Conn.SetupPingHandler(request.Unset, stream.PingHandler{
MessageType: websocket.TextMessage,
by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
MessageType: gws.TextMessage,
Message: []byte(`{"op": "ping"}`),
Delay: bybitWebsocketTimer,
})

View File

@@ -4,27 +4,27 @@ import (
"context"
"net/http"
"github.com/gorilla/websocket"
gws "github.com/gorilla/websocket"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
"github.com/thrasher-corp/gocryptotrader/internal/exchange/websocket"
)
// WsLinearConnect connects to linear a websocket feed
func (by *Bybit) WsLinearConnect() error {
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.LinearContract) {
return stream.ErrWebsocketNotEnabled
return websocket.ErrWebsocketNotEnabled
}
by.Websocket.Conn.SetURL(linearPublic)
var dialer websocket.Dialer
var dialer gws.Dialer
err := by.Websocket.Conn.Dial(&dialer, http.Header{})
if err != nil {
return err
}
by.Websocket.Conn.SetupPingHandler(request.Unset, stream.PingHandler{
MessageType: websocket.TextMessage,
by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
MessageType: gws.TextMessage,
Message: []byte(`{"op": "ping"}`),
Delay: bybitWebsocketTimer,
})

View File

@@ -5,22 +5,22 @@ import (
"net/http"
"strconv"
"github.com/gorilla/websocket"
gws "github.com/gorilla/websocket"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/encoding/json"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
"github.com/thrasher-corp/gocryptotrader/internal/exchange/websocket"
)
// WsOptionsConnect connects to options a websocket feed
func (by *Bybit) WsOptionsConnect() error {
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.Options) {
return stream.ErrWebsocketNotEnabled
return websocket.ErrWebsocketNotEnabled
}
by.Websocket.Conn.SetURL(optionPublic)
var dialer websocket.Dialer
var dialer gws.Dialer
err := by.Websocket.Conn.Dial(&dialer, http.Header{})
if err != nil {
return err
@@ -30,8 +30,8 @@ func (by *Bybit) WsOptionsConnect() error {
if err != nil {
return err
}
by.Websocket.Conn.SetupPingHandler(request.Unset, stream.PingHandler{
MessageType: websocket.TextMessage,
by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
MessageType: gws.TextMessage,
Message: pingData,
Delay: bybitWebsocketTimer,
})

View File

@@ -10,7 +10,7 @@ import (
"time"
"github.com/gofrs/uuid"
"github.com/gorilla/websocket"
gws "github.com/gorilla/websocket"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/thrasher-corp/gocryptotrader/common"
@@ -25,9 +25,9 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/margin"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
"github.com/thrasher-corp/gocryptotrader/internal/exchange/websocket"
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
testsubs "github.com/thrasher-corp/gocryptotrader/internal/testing/subscriptions"
testws "github.com/thrasher-corp/gocryptotrader/internal/testing/websocket"
@@ -3177,7 +3177,7 @@ func TestWsLinearConnect(t *testing.T) {
t.Skip(skippingWebsocketFunctionsForMockTesting)
}
err := b.WsLinearConnect()
if err != nil && !errors.Is(err, stream.ErrWebsocketNotEnabled) {
if err != nil && !errors.Is(err, websocket.ErrWebsocketNotEnabled) {
t.Error(err)
}
}
@@ -3188,7 +3188,7 @@ func TestWsInverseConnect(t *testing.T) {
t.Skip(skippingWebsocketFunctionsForMockTesting)
}
err := b.WsInverseConnect()
if err != nil && !errors.Is(err, stream.ErrWebsocketNotEnabled) {
if err != nil && !errors.Is(err, websocket.ErrWebsocketNotEnabled) {
t.Error(err)
}
}
@@ -3199,7 +3199,7 @@ func TestWsOptionsConnect(t *testing.T) {
t.Skip(skippingWebsocketFunctionsForMockTesting)
}
err := b.WsOptionsConnect()
if err != nil && !errors.Is(err, stream.ErrWebsocketNotEnabled) {
if err != nil && !errors.Is(err, websocket.ErrWebsocketNotEnabled) {
t.Error(err)
}
}
@@ -3813,7 +3813,7 @@ func TestAuthSubscribe(t *testing.T) {
require.NoError(t, err, "ExpandTemplates must not error")
b.Features.Subscriptions = subscription.List{}
success := true
mock := func(tb testing.TB, msg []byte, w *websocket.Conn) error {
mock := func(tb testing.TB, msg []byte, w *gws.Conn) error {
tb.Helper()
var req SubscriptionArgument
require.NoError(tb, json.Unmarshal(msg, &req), "Unmarshal must not error")
@@ -3825,7 +3825,7 @@ func TestAuthSubscribe(t *testing.T) {
Operation: req.Operation,
})
require.NoError(tb, err, "Marshal must not error")
return w.WriteMessage(websocket.TextMessage, msg)
return w.WriteMessage(gws.TextMessage, msg)
}
b = testexch.MockWsInstance[Bybit](t, testws.CurryWsMockUpgrader(t, mock))
b.Websocket.AuthConn = b.Websocket.Conn

View File

@@ -9,7 +9,7 @@ import (
"text/template"
"time"
"github.com/gorilla/websocket"
gws "github.com/gorilla/websocket"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/common/crypto"
"github.com/thrasher-corp/gocryptotrader/currency"
@@ -21,10 +21,10 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
"github.com/thrasher-corp/gocryptotrader/exchanges/trade"
"github.com/thrasher-corp/gocryptotrader/internal/exchange/websocket"
)
const (
@@ -80,15 +80,15 @@ var subscriptionNames = map[string]string{
// WsConnect connects to a websocket feed
func (by *Bybit) WsConnect() error {
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.Spot) {
return stream.ErrWebsocketNotEnabled
return websocket.ErrWebsocketNotEnabled
}
var dialer websocket.Dialer
var dialer gws.Dialer
err := by.Websocket.Conn.Dial(&dialer, http.Header{})
if err != nil {
return err
}
by.Websocket.Conn.SetupPingHandler(request.Unset, stream.PingHandler{
MessageType: websocket.TextMessage,
by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{
MessageType: gws.TextMessage,
Message: []byte(`{"op": "ping"}`),
Delay: bybitWebsocketTimer,
})
@@ -107,14 +107,14 @@ func (by *Bybit) WsConnect() error {
// WsAuth sends an authentication message to receive auth data
func (by *Bybit) WsAuth(ctx context.Context) error {
var dialer websocket.Dialer
var dialer gws.Dialer
err := by.Websocket.AuthConn.Dial(&dialer, http.Header{})
if err != nil {
return err
}
by.Websocket.AuthConn.SetupPingHandler(request.Unset, stream.PingHandler{
MessageType: websocket.TextMessage,
by.Websocket.AuthConn.SetupPingHandler(request.Unset, websocket.PingHandler{
MessageType: gws.TextMessage,
Message: []byte(`{"op":"ping"}`),
Delay: bybitWebsocketTimer,
})
@@ -214,7 +214,7 @@ func (by *Bybit) handleSpotSubscription(operation string, channelsToSubscribe su
return fmt.Errorf("%s with request ID %s msg: %s", resp.Operation, resp.RequestID, resp.RetMsg)
}
var conn stream.Connection
var conn websocket.Connection
if payloads[a].auth {
conn = by.Websocket.AuthConn
} else {
@@ -250,7 +250,7 @@ func (by *Bybit) GetSubscriptionTemplate(_ *subscription.Subscription) (*templat
}
// wsReadData receives and passes on websocket messages for processing
func (by *Bybit) wsReadData(assetType asset.Item, ws stream.Connection) {
func (by *Bybit) wsReadData(assetType asset.Item, ws websocket.Connection) {
defer by.Websocket.Wg.Done()
for {
select {
@@ -285,7 +285,7 @@ func (by *Bybit) wsHandleData(assetType asset.Item, respRaw []byte) error {
}
case "ping", "pong":
default:
by.Websocket.DataHandler <- stream.UnhandledMessageWarning{
by.Websocket.DataHandler <- websocket.UnhandledMessageWarning{
Message: string(respRaw),
}
return nil
@@ -487,13 +487,13 @@ func (by *Bybit) wsProcessLeverageTokenKline(assetType asset.Item, resp *Websock
if err != nil {
return err
}
ltKline := make([]stream.KlineData, len(result))
ltKline := make([]websocket.KlineData, len(result))
for x := range result {
interval, err := stringToInterval(result[x].Interval)
if err != nil {
return err
}
ltKline[x] = stream.KlineData{
ltKline[x] = websocket.KlineData{
Timestamp: result[x].Timestamp.Time(),
Pair: cp,
AssetType: assetType,
@@ -531,13 +531,13 @@ func (by *Bybit) wsProcessKline(assetType asset.Item, resp *WebsocketResponse, t
if err != nil {
return err
}
spotCandlesticks := make([]stream.KlineData, len(result))
spotCandlesticks := make([]websocket.KlineData, len(result))
for x := range result {
interval, err := stringToInterval(result[x].Interval)
if err != nil {
return err
}
spotCandlesticks[x] = stream.KlineData{
spotCandlesticks[x] = websocket.KlineData{
Timestamp: result[x].Timestamp.Time(),
Pair: cp,
AssetType: assetType,

View File

@@ -25,10 +25,10 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/protocol"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream/buffer"
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
"github.com/thrasher-corp/gocryptotrader/exchanges/trade"
"github.com/thrasher-corp/gocryptotrader/internal/exchange/websocket"
"github.com/thrasher-corp/gocryptotrader/internal/exchange/websocket/buffer"
"github.com/thrasher-corp/gocryptotrader/log"
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
)
@@ -206,7 +206,7 @@ func (by *Bybit) SetDefaults() {
log.Errorln(log.ExchangeSys, err)
}
by.Websocket = stream.NewWebsocket()
by.Websocket = websocket.NewManager()
by.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
by.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout
by.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit
@@ -234,7 +234,7 @@ func (by *Bybit) Setup(exch *config.Exchange) error {
}
err = by.Websocket.Setup(
&stream.WebsocketSetup{
&websocket.ManagerSetup{
ExchangeConfig: exch,
DefaultURL: spotPublic,
RunningURL: wsRunningEndpoint,
@@ -253,7 +253,7 @@ func (by *Bybit) Setup(exch *config.Exchange) error {
if err != nil {
return err
}
err = by.Websocket.SetupNewConnection(&stream.ConnectionSetup{
err = by.Websocket.SetupNewConnection(&websocket.ConnectionSetup{
URL: by.Websocket.GetWebsocketURL(),
ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout,
ResponseMaxLimit: bybitWebsocketTimer,
@@ -262,7 +262,7 @@ func (by *Bybit) Setup(exch *config.Exchange) error {
return err
}
return by.Websocket.SetupNewConnection(&stream.ConnectionSetup{
return by.Websocket.SetupNewConnection(&websocket.ConnectionSetup{
URL: websocketPrivate,
ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout,
ResponseMaxLimit: exch.WebsocketResponseMaxLimit,