Post

Replies

Boosts

Views

Activity

Trouble sending data using Network framework to server.
Hi all,I'm just a beginner wanting to create a client on MacOs for controlling a server (Hyperdeck). After a lot of beginners tutorials about basic Swift and SwiftUI, I started working on the client app.It should be quite basic: Open connection to server via TCP, and once a connection is established send easy text data to the server.After searching a lot, I figured Apple's Network framework (NWframework) would be quite useful. I found some examples and with those examples, i compiled the code below.Now when running the application, I'm able to setup a connection and send a first datastring to the server by calling the initClient function. But then i try to send another string of data by calling functions as stopPlayout or sendData, but nothing happens. When adding client.start() before the client.connection.send() in the functions, it opens a new connection to the server and sends the string. But I want the client to send the data over the first connection which is still open. Hyperdeck only allows 1 connection.Anyone can see what I'm doing wrong here?Thanks a lot!@Eskimo, thanks for your answer on swift forum. I did execute a package recording, nothing is recorded when calling the send function. So apparently no data is send when calling the send function. When initializing a connection and sending the first string in one function, packets are recorded.Client.swiftimport Foundation import Network @available(macOS 10.14, *) class Client { let connection: ClientConnection let host: NWEndpoint.Host let port: NWEndpoint.Port init(host: String, port: UInt16) { self.host = NWEndpoint.Host(host) self.port = NWEndpoint.Port(rawValue: port)! let nwConnection = NWConnection(host: self.host, port: self.port, using: .tcp) connection = ClientConnection(nwConnection: nwConnection) } func start() { print("Client started \(host) \(port)") connection.didStopCallback = didStopCallback(error:) connection.start() } func stop() { connection.stop() } func send(data: Data) { connection.send(data: data) } func didStopCallback(error: Error?) { if error == nil { exit(EXIT_SUCCESS) } else { exit(EXIT_FAILURE) } } }ClientConnection.swiftimport Foundation import Network @available(macOS 10.14, *) class ClientConnection { let nwConnection: NWConnection let queue = DispatchQueue(label: "Client connection Q") init(nwConnection: NWConnection) { self.nwConnection = nwConnection } var didStopCallback: ((Error?) -> Void)? = nil func start() { print("connection will start") nwConnection.stateUpdateHandler = stateDidChange(to:) setupReceive() nwConnection.start(queue: queue) } private func stateDidChange(to state: NWConnection.State) { switch state { case .waiting(let error): connectionDidFail(error: error) case .ready: print("Client connection ready") case .failed(let error): connectionDidFail(error: error) default: break } } private func setupReceive() { nwConnection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { (data, _, isComplete, error) in if let data = data, !data.isEmpty { let message = String(data: data, encoding: .utf8) print("connection did receive, data: \(data as NSData) string: \(message ?? "-" )") } if isComplete { self.connectionDidEnd() } else if let error = error { self.connectionDidFail(error: error) } else { self.setupReceive() } } } func send(data: Data) { nwConnection.send(content: data, completion: .contentProcessed( { error in if let error = error { self.connectionDidFail(error: error) return } print("connection did send, data: \(data as NSData)") })) } func stop() { print("connection will stop") stop(error: nil) } private func connectionDidFail(error: Error) { print("connection did fail, error: \(error)") self.stop(error: error) } private func connectionDidEnd() { print("connection did end") self.stop(error: nil) } private func stop(error: Error?) { self.nwConnection.stateUpdateHandler = nil self.nwConnection.cancel() if let didStopCallback = self.didStopCallback { self.didStopCallback = nil didStopCallback(error) } } }ContentView.swiftimport Foundation import SwiftUI import Network struct ContentView: View { @State var ipAdresHyperdeck1: String = "localhost" @State var ipAdresHyperdeck2: String = "" @State private var commandValue: String = "" @State var dataValue: String = "" let portHyperdeck: UInt16 = 8888 var body: some View { VStack { HStack { Text("IP Hyperdeck 1") .padding(.leading, 60.0) TextField("IP adres", text: $ipAdresHyperdeck1) .frame(width: 90.0) Spacer() } HStack { Button(action: { self.initClient(server: "\(self.ipAdresHyperdeck1)", port: self.portHyperdeck)}) { Text(" Connect Hyperdeck 1 ")} .padding(.leading, 60) Spacer() Button(action: { self.stopConnection(server: "\(self.ipAdresHyperdeck1)", port: self.portHyperdeck)}) { Text(" Stop hyperdeck 1 ")} .padding(.trailing, 55) } Button(action: { self.stopPlayout(server: "\(self.ipAdresHyperdeck1)", port: self.portHyperdeck)}) {Text("STOP")} Button(action: { self.playPlayout(server: "\(self.ipAdresHyperdeck1)", port: self.portHyperdeck)}) {Text("PLAY")} Button(action: { self.goToInPlayout(server: "\(self.ipAdresHyperdeck1)", port: self.portHyperdeck)}) {Text("GO TO IN")} HStack { Text("Data") TextField("Data you want to send", text: $commandValue) Button(action: { self.sendData(server: "\(self.ipAdresHyperdeck1)", port: self.portHyperdeck)}) {Text(" Send Data ")} } } } func initClient(server: String, port: UInt16) { let client = Client(host: server, port: port) var command = "" client.start() switch (command){ case "CRLF": command = "\r\n" case "RETURN": command = "\n" case "exit": client.stop() default: command = "hi server" } client.connection.send(data: (command.data(using: .utf8))!) } func stopConnection(server: String, port: UInt16) { let client = Client(host: server, port: port) client.stop() } func sendData(server: String, port: UInt16) { let client = Client(host: server, port: port) let command = String("\(commandValue)") switch (command) { case "exit": client.stop() commandValue = "" default: client.connection.send(data: (command.data(using: .utf8))!) commandValue = "" } } func stopPlayout(server: String, port: UInt16) { let client = Client(host: server, port: port) let command = String("stop") client.connection.send(data: (command.data(using: .utf8))!) } func playPlayout(server: String, port: UInt16) { let client = Client(host: server, port: port) let command = String("play") client.connection.send(data: (command.data(using: .utf8))!) } func goToInPlayout(server: String, port: UInt16) { let client = Client(host: server, port: port) let command = String("goto: clip: start") client.connection.send(data: (command.data(using: .utf8))!) } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } }
8
0
3.1k
Mar ’20