-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
wip fix: rename pkg wip feat: update building block
- Loading branch information
1 parent
fa8ec13
commit 5c4061f
Showing
4 changed files
with
187 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package wss | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
|
||
"github.com/rs/zerolog/log" | ||
"nhooyr.io/websocket" | ||
"nhooyr.io/websocket/wsjson" | ||
) | ||
|
||
type wsConn struct { | ||
*websocket.Conn | ||
} | ||
|
||
type ConnectionConfig struct { | ||
Endpoint string | ||
ProxyUrl string | ||
} | ||
|
||
type ConnectionOption func(*ConnectionConfig) | ||
|
||
func WithEndpoint(endpoint string) ConnectionOption { | ||
return func(c *ConnectionConfig) { | ||
c.Endpoint = endpoint | ||
} | ||
} | ||
|
||
func WithProxyUrl(proxyUrl string) ConnectionOption { | ||
return func(c *ConnectionConfig) { | ||
c.ProxyUrl = proxyUrl | ||
} | ||
} | ||
|
||
func NewConnection(ctx context.Context, opts ...ConnectionOption) (*wsConn, error) { | ||
config := &ConnectionConfig{} | ||
for _, opt := range opts { | ||
opt(config) | ||
} | ||
|
||
if config.Endpoint == "" { | ||
log.Error().Msg("endpoint is required") | ||
return nil, fmt.Errorf("endpoint is required") | ||
} | ||
|
||
dialOption := &websocket.DialOptions{} | ||
|
||
if config.ProxyUrl != "" { | ||
proxyURL, err := url.Parse(config.ProxyUrl) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
proxyTransport := http.DefaultTransport.(*http.Transport).Clone() | ||
proxyTransport.Proxy = http.ProxyURL(proxyURL) | ||
|
||
dialOption = &websocket.DialOptions{ | ||
HTTPClient: &http.Client{ | ||
Transport: proxyTransport, | ||
}, | ||
} | ||
} | ||
|
||
conn, _, err := websocket.Dial(ctx, config.Endpoint, dialOption) | ||
if err != nil { | ||
log.Error().Err(err).Msg("error opening websocket connection") | ||
return nil, err | ||
} | ||
return &wsConn{conn}, nil | ||
} | ||
|
||
func (ws *wsConn) Write(ctx context.Context, message interface{}) error { | ||
err := wsjson.Write(ctx, ws.Conn, message) | ||
if err != nil { | ||
log.Error().Err(err).Msg("error writing to websocket") | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (ws *wsConn) Read(ctx context.Context, ch chan interface{}) { | ||
for { | ||
var t interface{} | ||
err := wsjson.Read(ctx, ws.Conn, &t) | ||
if err != nil { | ||
log.Error().Err(err).Msg("error reading from websocket") | ||
break | ||
} | ||
ch <- t | ||
} | ||
} | ||
|
||
func (ws *wsConn) Close(ctx context.Context) error { | ||
err := ws.Conn.Close(websocket.StatusNormalClosure, "") | ||
if err != nil { | ||
log.Error().Err(err).Msg("error closing websocket") | ||
return err | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package wss | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"sync" | ||
|
||
"nhooyr.io/websocket" | ||
) | ||
|
||
type Connections struct { | ||
m map[string]*websocket.Conn | ||
lock sync.RWMutex | ||
} | ||
|
||
var ( | ||
connections *Connections | ||
) | ||
|
||
func init() { | ||
connections = &Connections{ | ||
m: make(map[string]*websocket.Conn), | ||
} | ||
} | ||
|
||
func (c *Connections) Update(key string, conn *websocket.Conn) error { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
|
||
if c.m[key] != nil { | ||
err := c.m[key].Close(websocket.StatusNormalClosure, "") | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
c.m[key] = conn | ||
return nil | ||
} | ||
|
||
func (c *Connections) Remove(key string) error { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
|
||
if c.m[key] != nil { | ||
err := c.m[key].Close(websocket.StatusNormalClosure, "") | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
delete(c.m, key) | ||
return nil | ||
} | ||
|
||
func (c *Connections) Get(key string) (*websocket.Conn, error) { | ||
c.lock.RLock() | ||
defer c.lock.RUnlock() | ||
|
||
conn, ok := c.m[key] | ||
if !ok { | ||
return nil, fmt.Errorf("connection not found") | ||
} | ||
return conn, nil | ||
} | ||
|
||
func getConnections() *Connections { | ||
return connections | ||
} | ||
|
||
func UpdateConnection(ctx context.Context, key string, conn *websocket.Conn) error { | ||
connections := getConnections() | ||
return connections.Update(key, conn) | ||
} | ||
|
||
func GetConnection(key string) (*websocket.Conn, error) { | ||
connections := getConnections() | ||
return connections.Get(key) | ||
} | ||
|
||
func RemoveConnection(key string) error { | ||
connections := getConnections() | ||
return connections.Remove(key) | ||
} |