Socket logic force disconnect/reconnect when server doesn't properly close it

Amended to fix build
This commit is contained in:
maddiebaka 2023-06-27 18:41:22 -04:00
parent 90be4321b0
commit 33068b99a0
4 changed files with 101 additions and 25 deletions

View File

@ -35,23 +35,27 @@ extension NWBrowser: NetworkDiscoveryEngine {
// MARK: BonjourBrowser
class BonjourBrowser: ObservableObject {
@Published var NDEngineResults: [NWBrowser.Result] = []
@Published var networkResults: [NWBrowser.Result] = []
private let nwBrowser: NetworkDiscoveryEngine
var connection: NWConnection!
private var nwBrowser: NWBrowser!
private var connection: NWConnection!
// TEMPORARY
// var bonjourListener: NWListener?
init(browser: NetworkDiscoveryEngine = NWBrowser(for: .bonjourWithTXTRecord(type: "_moonraker._tcp", domain: "local."), using: .tcp)) {
nwBrowser = browser
init() {
if nwBrowser == nil {
setup()
}
}
func setup() {
nwBrowser = NWBrowser(for: .bonjourWithTXTRecord(type: "_moonraker._tcp", domain: "local."), using: .tcp)
// Bonjour browser results changed handler
nwBrowser.setBrowseResultsChangedHandler({ (newResults, changes) in
print("[update] Results changed.")
self.NDEngineResults.removeAll()
self.networkResults.removeAll()
newResults.forEach { result in
print(result)
self.NDEngineResults.append(result)
self.networkResults.append(result)
}
})
@ -72,4 +76,63 @@ class BonjourBrowser: ObservableObject {
nwBrowser.startScan(queue: DispatchQueue.main)
}
func enableScan(_ queue: DispatchQueue) {
if(nwBrowser.state == .cancelled) {
self.setup()
}
nwBrowser.start(queue: queue)
}
func disableScan() {
if(nwBrowser.state != .cancelled) {
nwBrowser.cancel()
}
}
}
//class BonjourBrowser: ObservableObject {
// @Published var NDEngineResults: [NWBrowser.Result] = []
//
// private let nwBrowser: NetworkDiscoveryEngine
// var connection: NWConnection!
//
// // TEMPORARY
//// var bonjourListener: NWListener?
//
// init(browser: NetworkDiscoveryEngine = NWBrowser(for: .bonjourWithTXTRecord(type: "_moonraker._tcp", domain: "local."), using: .tcp)) {
// nwBrowser = browser
// // Bonjour browser results changed handler
// nwBrowser.setBrowseResultsChangedHandler({ (newResults, changes) in
// print("[update] Results changed.")
// self.NDEngineResults.removeAll()
// newResults.forEach { result in
// print(result)
// self.NDEngineResults.append(result)
// }
// })
//
// // Bonjour browser state update handler
// nwBrowser.setStateUpdateHandler({ newState in
// switch newState {
// case .failed(let error):
// print("[error] nwbrowser: \(error)")
// case .ready:
// print("[ready] nwbrowser")
// case .setup:
// print("[setup] nwbrowser")
// default:
// break
// }
// })
//
// nwBrowser.startScan(queue: DispatchQueue.main)
// }
//
// func startScanning(queue: DispatchQueue.main) {
// if(self.nwBrowser.state == NWBrowser.State.cancelled) {
//
// }
// self.nwBrowser.startScan(queue)
// }
//
//}

View File

@ -74,7 +74,7 @@ class MoonrakerSocketManager: ObservableObject, WebSocketDelegate {
// socket?.disconnect()
// }
//
if connection == nil {
if connection == nil || connection?.state == .cancelled {
connection = NWConnection(to: endpoint, using: .tcp)
}
@ -112,25 +112,29 @@ class MoonrakerSocketManager: ObservableObject, WebSocketDelegate {
func disconnect() {
print("disconnect() called")
isConnected = false
//connection?.cancel()
connection = nil
self.isConnected = false
socket?.disconnect()
socket = nil
}
// MARK: Private functions
// Opens the websocket connection
private func openWebsocket() {
func openWebsocket() {
// Exit function if there is no server to connect to
if socketHost.isEmpty || socketPort.isEmpty {
return
}
if socket != nil {
socket!.connect()
return
}
lastPingDate = Date.now
var request = URLRequest(url: URL(string: "http://\(socketHost):\(socketPort)/websocket")!)
var request = URLRequest(url: URL(string: "ws://\(socketHost):\(socketPort)/websocket")!)
request.timeoutInterval = 30
socket = WebSocket(request: request, engine: starscreamEngine)
socket!.delegate = self
@ -154,7 +158,8 @@ class MoonrakerSocketManager: ObservableObject, WebSocketDelegate {
switch(notification.name) {
case NSWorkspace.screensDidSleepNotification:
print("Screen slept. Disconnecting..")
socket?.disconnect()
self.disconnect()
//socket?.disconnect()
case NSWorkspace.screensDidWakeNotification:
print("Screen awoke. Opening websocket..")
self.openWebsocket()
@ -216,6 +221,15 @@ class MoonrakerSocketManager: ObservableObject, WebSocketDelegate {
case .error(let error):
isConnected = false
print("[error] Starscream: \(error.debugDescription)")
switch(error) {
case .some(HTTPUpgradeError.notAnUpgrade(200)):
print("[debug] Starscream: Forcing disconnect and reconnect..")
self.socket?.forceDisconnect()
self.socket = nil
self.openWebsocket()
default:
break
}
}
}

View File

@ -13,6 +13,8 @@ struct PrinterConfigView: View {
@ObservedObject var printerManager: MoonrakerSocketManager
@ObservedObject var bonjourBrowser = BonjourBrowser()
//@State var bonjourBrowser = NWBrowser(for: .bonjourWithTXTRecord(type: "_moonraker._tcp", domain: "local."), using: .tcp)
@Environment(\.openURL) private var openURL
@ -61,7 +63,7 @@ struct PrinterConfigView: View {
}.buttonStyle(PlainButtonStyle())
}
ForEach(bonjourBrowser.NDEngineResults , id: \.hashValue) { result in
ForEach(bonjourBrowser.networkResults, id: \.hashValue) { result in
HStack {
Text(result.endpoint.toFriendlyString())
Button {
@ -79,6 +81,10 @@ struct PrinterConfigView: View {
}
.onAppear {
NSApplication.shared.activate(ignoringOtherApps: true)
bonjourBrowser.enableScan(DispatchQueue.main)
}
.onDisappear {
bonjourBrowser.disableScan()
}
}
}

View File

@ -86,13 +86,6 @@ struct SoyuzMenuBarExtraView: View {
Text("Printers")
.foregroundColor(Color("ButtonForegroundColor"))
}
/* Debugging Stuff */
Button {
notification.sendNotification(.printComplete)
} label: {
Text("Notify")
}
/* Debugging Stuff */
Spacer()
if(printerManager.isConnected) {
Image(systemName: "network")