refactor: replace hardcoded values with constants and standardize mutex naming in WebSocketInterface
This commit is contained in:
@@ -4,10 +4,8 @@
|
|||||||
package interfaces
|
package interfaces
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -15,12 +13,17 @@ import (
|
|||||||
"git.quad4.io/Networks/Reticulum-Go/pkg/debug"
|
"git.quad4.io/Networks/Reticulum-Go/pkg/debug"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
WS_MTU = 1064
|
||||||
|
WS_BITRATE = 10000000
|
||||||
|
WS_RECONNECT_DELAY = 2 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
type WebSocketInterface struct {
|
type WebSocketInterface struct {
|
||||||
BaseInterface
|
BaseInterface
|
||||||
wsURL string
|
wsURL string
|
||||||
ws js.Value
|
ws js.Value
|
||||||
connected bool
|
connected bool
|
||||||
mutex sync.RWMutex
|
|
||||||
messageQueue [][]byte
|
messageQueue [][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,8 +34,8 @@ func NewWebSocketInterface(name string, wsURL string, enabled bool) (*WebSocketI
|
|||||||
messageQueue: make([][]byte, 0),
|
messageQueue: make([][]byte, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.MTU = 1064
|
ws.MTU = WS_MTU
|
||||||
ws.Bitrate = 10000000
|
ws.Bitrate = WS_BITRATE
|
||||||
|
|
||||||
return ws, nil
|
return ws, nil
|
||||||
}
|
}
|
||||||
@@ -50,41 +53,41 @@ func (wsi *WebSocketInterface) GetMode() common.InterfaceMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (wsi *WebSocketInterface) IsOnline() bool {
|
func (wsi *WebSocketInterface) IsOnline() bool {
|
||||||
wsi.mutex.RLock()
|
wsi.Mutex.RLock()
|
||||||
defer wsi.mutex.RUnlock()
|
defer wsi.Mutex.RUnlock()
|
||||||
return wsi.Online && wsi.connected
|
return wsi.Online && wsi.connected
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wsi *WebSocketInterface) IsDetached() bool {
|
func (wsi *WebSocketInterface) IsDetached() bool {
|
||||||
wsi.mutex.RLock()
|
wsi.Mutex.RLock()
|
||||||
defer wsi.mutex.RUnlock()
|
defer wsi.Mutex.RUnlock()
|
||||||
return wsi.Detached
|
return wsi.Detached
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wsi *WebSocketInterface) Detach() {
|
func (wsi *WebSocketInterface) Detach() {
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
defer wsi.mutex.Unlock()
|
defer wsi.Mutex.Unlock()
|
||||||
wsi.Detached = true
|
wsi.Detached = true
|
||||||
wsi.Online = false
|
wsi.Online = false
|
||||||
wsi.closeWebSocket()
|
wsi.closeWebSocket()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wsi *WebSocketInterface) Enable() {
|
func (wsi *WebSocketInterface) Enable() {
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
defer wsi.mutex.Unlock()
|
defer wsi.Mutex.Unlock()
|
||||||
wsi.Enabled = true
|
wsi.Enabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wsi *WebSocketInterface) Disable() {
|
func (wsi *WebSocketInterface) Disable() {
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
defer wsi.mutex.Unlock()
|
defer wsi.Mutex.Unlock()
|
||||||
wsi.Enabled = false
|
wsi.Enabled = false
|
||||||
wsi.closeWebSocket()
|
wsi.closeWebSocket()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wsi *WebSocketInterface) Start() error {
|
func (wsi *WebSocketInterface) Start() error {
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
defer wsi.mutex.Unlock()
|
defer wsi.Mutex.Unlock()
|
||||||
|
|
||||||
if wsi.ws.Truthy() {
|
if wsi.ws.Truthy() {
|
||||||
return fmt.Errorf("WebSocket already started")
|
return fmt.Errorf("WebSocket already started")
|
||||||
@@ -94,18 +97,18 @@ func (wsi *WebSocketInterface) Start() error {
|
|||||||
ws.Set("binaryType", "arraybuffer")
|
ws.Set("binaryType", "arraybuffer")
|
||||||
|
|
||||||
ws.Set("onopen", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
ws.Set("onopen", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
wsi.connected = true
|
wsi.connected = true
|
||||||
wsi.Online = true
|
wsi.Online = true
|
||||||
wsi.mutex.Unlock()
|
wsi.Mutex.Unlock()
|
||||||
|
|
||||||
debug.Log(debug.DEBUG_INFO, "WebSocket connected", "name", wsi.Name, "url", wsi.wsURL)
|
debug.Log(debug.DEBUG_INFO, "WebSocket connected", "name", wsi.Name, "url", wsi.wsURL)
|
||||||
|
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
queue := make([][]byte, len(wsi.messageQueue))
|
queue := make([][]byte, len(wsi.messageQueue))
|
||||||
copy(queue, wsi.messageQueue)
|
copy(queue, wsi.messageQueue)
|
||||||
wsi.messageQueue = wsi.messageQueue[:0]
|
wsi.messageQueue = wsi.messageQueue[:0]
|
||||||
wsi.mutex.Unlock()
|
wsi.Mutex.Unlock()
|
||||||
|
|
||||||
for _, msg := range queue {
|
for _, msg := range queue {
|
||||||
wsi.sendWebSocketMessage(msg)
|
wsi.sendWebSocketMessage(msg)
|
||||||
@@ -122,35 +125,27 @@ func (wsi *WebSocketInterface) Start() error {
|
|||||||
event := args[0]
|
event := args[0]
|
||||||
data := event.Get("data")
|
data := event.Get("data")
|
||||||
|
|
||||||
var packetData []byte
|
var packet []byte
|
||||||
if data.Type() == js.TypeString {
|
if data.Type() == js.TypeString {
|
||||||
packetData = []byte(data.String())
|
packet = []byte(data.String())
|
||||||
} else if data.Type() == js.TypeObject {
|
} else if data.Type() == js.TypeObject {
|
||||||
array := js.Global().Get("Uint8Array").New(data)
|
array := js.Global().Get("Uint8Array").New(data)
|
||||||
length := array.Get("length").Int()
|
length := array.Get("length").Int()
|
||||||
packetData = make([]byte, length)
|
packet = make([]byte, length)
|
||||||
js.CopyBytesToGo(packetData, array)
|
js.CopyBytesToGo(packet, array)
|
||||||
} else {
|
} else {
|
||||||
debug.Log(debug.DEBUG_ERROR, "Unknown WebSocket message type", "type", data.Type().String())
|
debug.Log(debug.DEBUG_ERROR, "Unknown WebSocket message type", "type", data.Type().String())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(packetData) < 4 {
|
if len(packet) < 1 {
|
||||||
debug.Log(debug.DEBUG_ERROR, "WebSocket message too short", "bytes", len(packetData))
|
debug.Log(debug.DEBUG_ERROR, "WebSocket message empty")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
packetLen := binary.BigEndian.Uint32(packetData[:4])
|
wsi.Mutex.Lock()
|
||||||
if len(packetData) < int(packetLen)+4 {
|
|
||||||
debug.Log(debug.DEBUG_ERROR, "WebSocket message incomplete", "expected", packetLen+4, "got", len(packetData))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
packet := packetData[4 : 4+packetLen]
|
|
||||||
|
|
||||||
wsi.mutex.Lock()
|
|
||||||
wsi.RxBytes += uint64(len(packet))
|
wsi.RxBytes += uint64(len(packet))
|
||||||
wsi.mutex.Unlock()
|
wsi.Mutex.Unlock()
|
||||||
|
|
||||||
wsi.ProcessIncoming(packet)
|
wsi.ProcessIncoming(packet)
|
||||||
|
|
||||||
@@ -163,15 +158,15 @@ func (wsi *WebSocketInterface) Start() error {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
ws.Set("onclose", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
ws.Set("onclose", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
wsi.connected = false
|
wsi.connected = false
|
||||||
wsi.Online = false
|
wsi.Online = false
|
||||||
wsi.mutex.Unlock()
|
wsi.Mutex.Unlock()
|
||||||
|
|
||||||
debug.Log(debug.DEBUG_INFO, "WebSocket closed", "name", wsi.Name)
|
debug.Log(debug.DEBUG_INFO, "WebSocket closed", "name", wsi.Name)
|
||||||
|
|
||||||
if wsi.Enabled && !wsi.Detached {
|
if wsi.Enabled && !wsi.Detached {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(WS_RECONNECT_DELAY)
|
||||||
go wsi.Start()
|
go wsi.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,8 +179,8 @@ func (wsi *WebSocketInterface) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (wsi *WebSocketInterface) Stop() error {
|
func (wsi *WebSocketInterface) Stop() error {
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
defer wsi.mutex.Unlock()
|
defer wsi.Mutex.Unlock()
|
||||||
wsi.Enabled = false
|
wsi.Enabled = false
|
||||||
wsi.closeWebSocket()
|
wsi.closeWebSocket()
|
||||||
return nil
|
return nil
|
||||||
@@ -205,14 +200,14 @@ func (wsi *WebSocketInterface) Send(data []byte, addr string) error {
|
|||||||
return fmt.Errorf("interface not enabled")
|
return fmt.Errorf("interface not enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
wsi.TxBytes += uint64(len(data))
|
wsi.TxBytes += uint64(len(data))
|
||||||
wsi.mutex.Unlock()
|
wsi.Mutex.Unlock()
|
||||||
|
|
||||||
if !wsi.connected {
|
if !wsi.connected {
|
||||||
wsi.mutex.Lock()
|
wsi.Mutex.Lock()
|
||||||
wsi.messageQueue = append(wsi.messageQueue, data)
|
wsi.messageQueue = append(wsi.messageQueue, data)
|
||||||
wsi.mutex.Unlock()
|
wsi.Mutex.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,13 +223,8 @@ func (wsi *WebSocketInterface) sendWebSocketMessage(data []byte) error {
|
|||||||
return fmt.Errorf("WebSocket not open")
|
return fmt.Errorf("WebSocket not open")
|
||||||
}
|
}
|
||||||
|
|
||||||
packetLen := uint32(len(data))
|
array := js.Global().Get("Uint8Array").New(len(data))
|
||||||
packet := make([]byte, 4+len(data))
|
js.CopyBytesToJS(array, data)
|
||||||
binary.BigEndian.PutUint32(packet[:4], packetLen)
|
|
||||||
copy(packet[4:], data)
|
|
||||||
|
|
||||||
array := js.Global().Get("Uint8Array").New(len(packet))
|
|
||||||
js.CopyBytesToJS(array, packet)
|
|
||||||
|
|
||||||
wsi.ws.Call("send", array)
|
wsi.ws.Call("send", array)
|
||||||
|
|
||||||
@@ -255,7 +245,7 @@ func (wsi *WebSocketInterface) GetMTU() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (wsi *WebSocketInterface) IsEnabled() bool {
|
func (wsi *WebSocketInterface) IsEnabled() bool {
|
||||||
wsi.mutex.RLock()
|
wsi.Mutex.RLock()
|
||||||
defer wsi.mutex.RUnlock()
|
defer wsi.Mutex.RUnlock()
|
||||||
return wsi.Enabled && wsi.Online && !wsi.Detached
|
return wsi.Enabled && wsi.Online && !wsi.Detached
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user