82 lines
1.3 KiB
Go
82 lines
1.3 KiB
Go
package mempool
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/url"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
var (
|
|
ErrNotWebsocket = errors.New("provided addr was not websocket")
|
|
)
|
|
|
|
type mempool struct {
|
|
addr string
|
|
ws *websocket.Conn
|
|
}
|
|
|
|
func New(addr string) *mempool {
|
|
return &mempool{
|
|
addr: addr,
|
|
}
|
|
}
|
|
|
|
func (m *mempool) Init() error {
|
|
u, err := url.Parse(m.addr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if u.Scheme != "wss" && u.Scheme != "ws" {
|
|
return fmt.Errorf("%w: got %s", ErrNotWebsocket, u.Scheme)
|
|
}
|
|
|
|
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
m.ws = c
|
|
return nil
|
|
}
|
|
|
|
func (m *mempool) Listen(ctx context.Context, blocks chan Block, errs chan error, done chan struct{}) {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
close(blocks)
|
|
close(errs)
|
|
close(done)
|
|
return
|
|
default:
|
|
_, message, err := m.ws.ReadMessage()
|
|
if err != nil {
|
|
errs <- err
|
|
continue
|
|
}
|
|
|
|
var b Block
|
|
err = json.Unmarshal(message, &b)
|
|
if err != nil {
|
|
errs <- err
|
|
continue
|
|
}
|
|
|
|
blocks <- b
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *mempool) Shutdown(ctx context.Context) error {
|
|
err := m.ws.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
m.ws.Close()
|
|
return nil
|
|
}
|