iOS 没有握手的 websocket
iOS websocket without handshake
我想在 iOS 上建立简单的本地 Socket 通信。在查看其他库后,我发现自去年以来 Swift 原生的 websocket 库运行良好,但带有我想禁用的讨厌的握手(否则我将不得不调整服务器响应ETC。)。我的代码如下所示:
let webSocketDelegate = WebSocket()
let session = URLSession(configuration: .default, delegate: webSocketDelegate, delegateQueue: OperationQueue())
let url = URL(string: "ws://192.168.43.1:6000")!
let webSocketTask = session.webSocketTask(with: url)
func send() {
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
send()
webSocketTask.send(.string("New Message")) { error in
if let error = error {
print("Error when sending a message \(error)")
}
}
}
}
webSocketTask.receive { result in
switch result {
case .success(let message):
switch message {
case .data(let data):
print("Data received \(data)")
case .string(let text):
print("Text received \(text)")
}
case .failure(let error):
print("Error when receiving \(error)")
}
}
webSocketTask.resume()
我用谷歌搜索并找到 nw_ws_options_set_skip_handshake,但我找不到如何使用它的示例。有什么想法吗?
正如@SteffenUllrich 所建议的,我更多地研究了 TCP 套接字通信并找到了一种简单的通信方式。这是我的解决方案,希望它能帮助别人:
let queue = DispatchQueue(label: "TCP Client Queue")
let connection = NWConnection(to: NWEndpoint.hostPort(host: "192.168.99.1", port: 7000), using: NWParameters.init(tls: nil))
func connect() {
connection.stateUpdateHandler = { (newState) in
switch (newState) {
case .ready:
print("Socket: ready")
sendString(text: "Hello server!")
receiveMsg()
default: print("Socket: \(newState)")
}
}
connection.start(queue: queue)
}
func receiveMsg() {
connection.receive(minimumIncompleteLength: 1, maximumLength: 1000, completion: { (data, context, isComplete, error) in
if((data) != nil){
let text:String = String(decoding: data!, as: UTF8.self)
//send string to handler function, trim linebreak for single line commands
handleMsg(msg: text.trimmingCharacters(in: .newlines))
}
else{receiveMsg()//go back to receiving}
})
}
func receiveFile() {
print("Receiving file...")
//fileSize was sent before submission
connection.receive(minimumIncompleteLength: Int(fileSize), maximumLength: Int(fileSize)+1000, completion: { (data, context, isComplete, error) in
saveFile(data: data!)//save data to file
})
}
func sendString(text:String) {
let data:Data? = "\(text)\n".data(using: .utf8)//add linebreak to single line string, otherwise it does not release transmission
connection.send(content: data, completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
if (NWError == nil) {
print("Data was sent to TCP destination ")
} else {
print("ERROR! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
}
})))
}
您只需调用connect() 来启动连接,使用sendString() 发送一些文本。接收应该运行不断。我没有共享命令处理程序,但它在常规命令上重新 运行s receiveMsg() ,并在服务器启动文件传输时 receiveFile() (init还包含设置所需的fileSize receive() 函数中的预期字节大小!)。
我想在 iOS 上建立简单的本地 Socket 通信。在查看其他库后,我发现自去年以来 Swift 原生的 websocket 库运行良好,但带有我想禁用的讨厌的握手(否则我将不得不调整服务器响应ETC。)。我的代码如下所示:
let webSocketDelegate = WebSocket()
let session = URLSession(configuration: .default, delegate: webSocketDelegate, delegateQueue: OperationQueue())
let url = URL(string: "ws://192.168.43.1:6000")!
let webSocketTask = session.webSocketTask(with: url)
func send() {
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
send()
webSocketTask.send(.string("New Message")) { error in
if let error = error {
print("Error when sending a message \(error)")
}
}
}
}
webSocketTask.receive { result in
switch result {
case .success(let message):
switch message {
case .data(let data):
print("Data received \(data)")
case .string(let text):
print("Text received \(text)")
}
case .failure(let error):
print("Error when receiving \(error)")
}
}
webSocketTask.resume()
我用谷歌搜索并找到 nw_ws_options_set_skip_handshake,但我找不到如何使用它的示例。有什么想法吗?
正如@SteffenUllrich 所建议的,我更多地研究了 TCP 套接字通信并找到了一种简单的通信方式。这是我的解决方案,希望它能帮助别人:
let queue = DispatchQueue(label: "TCP Client Queue")
let connection = NWConnection(to: NWEndpoint.hostPort(host: "192.168.99.1", port: 7000), using: NWParameters.init(tls: nil))
func connect() {
connection.stateUpdateHandler = { (newState) in
switch (newState) {
case .ready:
print("Socket: ready")
sendString(text: "Hello server!")
receiveMsg()
default: print("Socket: \(newState)")
}
}
connection.start(queue: queue)
}
func receiveMsg() {
connection.receive(minimumIncompleteLength: 1, maximumLength: 1000, completion: { (data, context, isComplete, error) in
if((data) != nil){
let text:String = String(decoding: data!, as: UTF8.self)
//send string to handler function, trim linebreak for single line commands
handleMsg(msg: text.trimmingCharacters(in: .newlines))
}
else{receiveMsg()//go back to receiving}
})
}
func receiveFile() {
print("Receiving file...")
//fileSize was sent before submission
connection.receive(minimumIncompleteLength: Int(fileSize), maximumLength: Int(fileSize)+1000, completion: { (data, context, isComplete, error) in
saveFile(data: data!)//save data to file
})
}
func sendString(text:String) {
let data:Data? = "\(text)\n".data(using: .utf8)//add linebreak to single line string, otherwise it does not release transmission
connection.send(content: data, completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
if (NWError == nil) {
print("Data was sent to TCP destination ")
} else {
print("ERROR! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
}
})))
}
您只需调用connect() 来启动连接,使用sendString() 发送一些文本。接收应该运行不断。我没有共享命令处理程序,但它在常规命令上重新 运行s receiveMsg() ,并在服务器启动文件传输时 receiveFile() (init还包含设置所需的fileSize receive() 函数中的预期字节大小!)。