我有以下设置:
- 一台运行轻量级服务器(Node.js/Express)的笔记本电脑,假设服务器监听端口3000,并使用JSON响应
GET /hello
。 - iOS应用
笔记本电脑和iOS设备通过以太网电缆连接到一个本地网络。服务器在网络上使用名称(比如说,“simply.server”)(使用mdns节点包)来自我验证。
iOS应用程序能够在网络框架的帮助下发现此服务器:
// in the beginning of the class declaration
private var browser: NWBrowser?
func discoverServer() {
let parameters = NWParameters()
self?.browser = NWBrowser(for: .bonjour(type: "_http._tcp", domain: "local."), using: parameters)
self?.browser?.stateUpdateHandler = { [weak self] newState in
switch newState {
case .failed(let error):
self?.browser?.cancel()
default:
break
}
}
self?.browser?.browseResultsChangedHandler = { [weak self] results, changes in
for change in changes {
switch change {
case .added(let result):
switch result.endpoint {
case .service(let name, _, _, _):
if name == "simple.server" {
let connection = NWConnection(to: result.endpoint, using: .tcp)
connection.stateUpdateHandler = { newState in
switch newState {
case .ready:
if let innerEndpoint = connection.currentPath?.remoteEndpoint,
case .hostPort(let host, let port) = innerEndpoint {
let content =
"GET /hello HTTP/1.1\r\n" +
"Host: \(host)\r\n" +
"\r\n"
let completion = ... just print an error if any
connection.receive(minimumIncompleteLength: 1, maximumLength: 10000) { content, _, _, _ in
if let content = content {
print(String(data: content, encoding: .utf8))
}
}
connection.send(content: content.data(using: .utf8), completion: completion)
... the rest of closing brackets are here
}
这成功地发送了HTTP GET请求(我假设也适用于POST,我还没有测试过),并接收响应。
问题是response是一个原始字符串,像这样:
"HTTP/1.1 200 OK\r\nX-Powered-By: Express\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: 215\r\nETag: W/\"d7-/V8YoIpwjOAIzkBGCymxNZtfrTw\"\r\nDate: Thu, 19 Oct 2023 12:58:08 GMT\r\nConnection: keep-alive\r\nKeep-Alive: timeout=5\r\n\r\n{\"items\":\" 1: \\\"something\\\"\\r\\n 2: \\\"something else\\\"\\r\\n 3: \\\"yet another one\\\"\\r\\n 4: \\\"and so on\\\"\\r\\n 5: \\\"and so forth\\\"\\r\\n 6: \\\"the end\\\"\\r\\n\\n\"}"
为了理解这样的响应,我必须手动解析它(例如,通过换行符拆分,解析出响应代码,头,主体等),这有点麻烦。
所以我的问题是我怎么才能让它更好
- 有没有一种方法可以很好地将其解析为HTTPURLResponse?
- 也许一开始就有更好的方法来完成请求
- 也许我不应该通过NWConnection这样做,而是在发现服务后使用URLSession?
提前感谢您的任何建议。
1条答案
按热度按时间1tu0hz3e1#
更新:
最后我成功地发送了一个HTTP请求。
正如@Paulw11在评论中提到的,可以用我们已经从
connection.currentPath?.remoteEndpoint
解析的主机和端口构建一个URL。有几件事要注意:
host
是一个ipv6地址(在我的情况下;我试图在服务器端进行更改以强制IPv4,但它不起作用;我还没有深入研究),所以它应该包含在[]
中,我完全错过了。我们还可以打开host
来查看它是ipv4还是ipv6,并相应地构建url。1.由于某种原因,
URLSession.shared.dataTask
调用完成从来没有调用完成。但是URLSession.shared.data(for:)
,运行得很好(同样,甚至还没有尝试弄清楚)。1.如果plist中禁止任意加载,请求将失败。这还有待我去解决。
下面是工作代码: