@@ -12,9 +12,11 @@ import SwiftUI
1212
1313class Bridge {
1414 var webview : WebViewController ?
15- let listener : NWListener
15+ var listener : NWListener ?
1616 let home : URL
1717 var lastURL : URL ?
18+ static public var instance : Bridge ?
19+ var erlangStarted = false
1820
1921 func setWebView( view : WebViewController ) {
2022 self . webview = view
@@ -38,10 +40,8 @@ class Bridge {
3840 private var connectionsByID : [ Int : ServerConnection ] = [ : ]
3941
4042 init ( ) throws {
43+ print ( " bridge init() " )
4144 home = FileManager . default. urls ( for: . libraryDirectory, in: . userDomainMask) [ 0 ] . appendingPathComponent ( Bundle . main. bundleIdentifier!)
42- listener = try ! NWListener ( using: . tcp, on: NWEndpoint . Port. any)
43- listener. stateUpdateHandler = self . stateDidChange ( to: )
44- listener. newConnectionHandler = self . didAccept ( nwConnection: )
4545
4646 // Extracting the app
4747 let infoAttr = try FileManager . default. attributesOfItem ( atPath: zipFile ( ) . path)
@@ -87,7 +87,30 @@ class Bridge {
8787 //}
8888
8989 print ( " Server starting... " )
90- listener. start ( queue: . global( ) )
90+ // setupListener()
91+ Bridge . instance = self
92+ }
93+
94+ func setupListener( ) {
95+ let l = try ! NWListener ( using: . tcp, on: Bridge . port ( ) )
96+ l. stateUpdateHandler = self . stateDidChange ( to: )
97+ l. newConnectionHandler = self . didAccept ( nwConnection: )
98+ l. start ( queue: . global( ) )
99+ listener = l
100+ }
101+
102+ func reinit( ) {
103+ print ( " Server re-init called " )
104+ let conn = connectionsByID. first
105+ if conn == nil ||
106+ conn? . value. connection. state == . cancelled {
107+ stopListener ( )
108+ setupListener ( )
109+ }
110+ }
111+
112+ static func port( ) -> NWEndpoint . Port {
113+ return NWEndpoint . Port ( " 23115 " ) !
91114 }
92115
93116 func setEnv( name: String , value: String ) {
@@ -105,11 +128,17 @@ class Bridge {
105128 }
106129
107130 func stateDidChange( to newState: NWListener . State ) {
131+ print ( " Server new state: \( newState) " )
132+
108133 switch newState {
109134 case . ready:
135+ if erlangStarted {
136+ break
137+ }
138+ erlangStarted = true
110139 print ( " Bridge Server ready. Starting Elixir " )
111140 setEnv ( name: " ELIXIR_DESKTOP_OS " , value: " ios " ) ;
112- setEnv ( name: " BRIDGE_PORT " , value: ( listener. port? . rawValue. description) !) ;
141+ setEnv ( name: " BRIDGE_PORT " , value: ( listener? . port? . rawValue. description) !) ;
113142 // not really the home directory, but persistent between app upgrades (yes?)
114143 setEnv ( name: " HOME " , value: home. path)
115144 // BINDIR not used on iOS but needs to be defined
@@ -125,7 +154,11 @@ class Bridge {
125154 case . failed( let error) :
126155 print ( " Server failure, error: \( error. localizedDescription) " )
127156 exit ( EXIT_FAILURE)
157+ case . cancelled:
158+ print ( " Server failure, cancelled " )
159+ exit ( EXIT_FAILURE)
128160 default :
161+ print ( " Server unknown new state: \( newState) " )
129162 break
130163 }
131164 }
@@ -137,19 +170,32 @@ class Bridge {
137170 self . connectionDidStop ( connection)
138171 }
139172 connection. start ( )
140- // connection.send(data: "Welcome you are connection: \(connection.id)".data(using: .utf8)!)
173+ let payload = " \0 \0 \0 \0 \0 \0 \0 \0 \" :reconnect \" " . data ( using: . utf8) !
174+
175+ let size : UInt32 = CFSwapInt32 ( UInt32 ( payload. count) )
176+ var message = withUnsafeBytes ( of: size) { Data ( $0) }
177+ message. append ( payload)
178+ connection. send ( data: message)
141179 print ( " server did open connection \( connection. id) " )
142180 }
143181
144182 private func connectionDidStop( _ connection: ServerConnection ) {
145183 self . connectionsByID. removeValue ( forKey: connection. id)
146184 print ( " server did close connection \( connection. id) " )
147185 }
186+
187+ private func stopListener( ) {
188+ if let l = listener {
189+ l. stateUpdateHandler = nil
190+ l. newConnectionHandler = nil
191+ l. cancel ( )
192+ }
193+ }
148194
149195 private func stop( ) {
150- self . listener . stateUpdateHandler = nil
151- self . listener . newConnectionHandler = nil
152- self . listener . cancel ( )
196+ print ( " stop() called " )
197+
198+ stopListener ( )
153199 for connection in self . connectionsByID. values {
154200 connection. didStopCallback = nil
155201 connection. stop ( )
0 commit comments