Implement reconnection logic and improve server connection handling
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/getlantern/systray"
|
"github.com/getlantern/systray"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
@@ -15,6 +16,7 @@ var (
|
|||||||
lastClipboard []byte
|
lastClipboard []byte
|
||||||
identification string
|
identification string
|
||||||
isConnected bool
|
isConnected bool
|
||||||
|
serverURL string
|
||||||
)
|
)
|
||||||
|
|
||||||
func onReady() {
|
func onReady() {
|
||||||
@@ -58,7 +60,7 @@ func startClient(statusItem *systray.MenuItem) {
|
|||||||
identification = EmbeddedIdentification
|
identification = EmbeddedIdentification
|
||||||
server_ip := EmbeddedServerIP
|
server_ip := EmbeddedServerIP
|
||||||
server_port := EmbeddedServerPort
|
server_port := EmbeddedServerPort
|
||||||
server_connection := "ws://" + server_ip + ":" + server_port + "/ws"
|
serverURL = "ws://" + server_ip + ":" + server_port + "/ws"
|
||||||
|
|
||||||
if identification == "" || server_ip == "" || server_port == "" {
|
if identification == "" || server_ip == "" || server_port == "" {
|
||||||
log.Println("Missing configuration")
|
log.Println("Missing configuration")
|
||||||
@@ -66,29 +68,70 @@ func startClient(statusItem *systray.MenuItem) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect to the server
|
// Reconnection loop with exponential backoff
|
||||||
var connectErr error
|
backoff := 1 * time.Second
|
||||||
conn, _, connectErr = websocket.DefaultDialer.Dial(server_connection, nil)
|
maxBackoff := 60 * time.Second
|
||||||
if connectErr != nil {
|
|
||||||
log.Println("Error connecting to server:", connectErr)
|
for {
|
||||||
|
if connectToServer(statusItem) {
|
||||||
|
// Successfully connected, reset backoff
|
||||||
|
backoff = 1 * time.Second
|
||||||
|
|
||||||
|
// Listen for messages until connection drops
|
||||||
|
listenForMessages(statusItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection failed or dropped, wait before retry
|
||||||
|
isConnected = false
|
||||||
|
statusItem.SetTitle(fmt.Sprintf("Status: Reconnecting in %ds...", int(backoff.Seconds())))
|
||||||
|
log.Printf("Reconnecting in %s...", backoff)
|
||||||
|
time.Sleep(backoff)
|
||||||
|
|
||||||
|
// Increase backoff exponentially
|
||||||
|
backoff *= 2
|
||||||
|
if backoff > maxBackoff {
|
||||||
|
backoff = maxBackoff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func connectToServer(statusItem *systray.MenuItem) bool {
|
||||||
|
statusItem.SetTitle("Status: Connecting...")
|
||||||
|
|
||||||
|
var err error
|
||||||
|
conn, _, err = websocket.DefaultDialer.Dial(serverURL, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error connecting to server:", err)
|
||||||
statusItem.SetTitle("Status: Connection failed")
|
statusItem.SetTitle("Status: Connection failed")
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send identification to the server
|
// Send identification to the server
|
||||||
sendMessage(conn, websocket.TextMessage, []byte(identification))
|
err = conn.WriteMessage(websocket.TextMessage, []byte(identification))
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error sending identification:", err)
|
||||||
|
conn.Close()
|
||||||
|
conn = nil
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
isConnected = true
|
isConnected = true
|
||||||
statusItem.SetTitle(fmt.Sprintf("Status: Connected (%s)", identification))
|
statusItem.SetTitle(fmt.Sprintf("Status: Connected (%s)", identification))
|
||||||
log.Println("Connected to server")
|
log.Println("Connected to server")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Listen for messages from the server
|
func listenForMessages(statusItem *systray.MenuItem) {
|
||||||
for {
|
for {
|
||||||
messageType, message, err := conn.ReadMessage()
|
messageType, message, err := conn.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error reading message:", err)
|
log.Println("Error reading message:", err)
|
||||||
isConnected = false
|
isConnected = false
|
||||||
statusItem.SetTitle("Status: Disconnected")
|
statusItem.SetTitle("Status: Disconnected")
|
||||||
|
if conn != nil {
|
||||||
|
conn.Close()
|
||||||
|
conn = nil
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
handleMessage(messageType, message)
|
handleMessage(messageType, message)
|
||||||
@@ -109,6 +152,7 @@ func sendMessage(conn *websocket.Conn, messageType int, message []byte) {
|
|||||||
err := conn.WriteMessage(messageType, message)
|
err := conn.WriteMessage(messageType, message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error sending message:", err)
|
log.Println("Error sending message:", err)
|
||||||
|
isConnected = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user