根据 iOS (Swift 2) 中的消息 ID 将传入的网络消息分派到特定线程

Dispatch incoming network messages to specific threads based on message IDs in iOS (Swift 2)

我正在使用 Swift 深入研究 iOS 编码,所以我是新手。

我的 iOS 应用程序(实际上是一个游戏)使用单个套接字连接和自定义 JSON 协议与游戏服务器通信。消息是单向的(通知)和 request/reply(可以在双方发起)。 Request/Replies 通过使用全球唯一的消息 ID 绑定在一起。所以这与简单的 HTTP/REST 请求完全不同。

现在可能发生的事情(实际上是我需要解决的问题)例如:

目前我的 iOS 游戏使用 SocketConnection class 连接到服务器并能够发送和接收 (JSON) notifications/request/replies。但是,缺少将响应分派到发起请求的线程的部分。

我浏览了 iOS 文档并加载了 blogs/tutorials。它们似乎都涵盖了 GCD 以及如何将其用于并发(将工作加载到 worker 等)

然而,我需要的是某种类似于 Java 的 wait/notify。游戏服务器在Java中实现,在向客户端发起请求时大致做了以下工作:

在后台有一个专用(私有)接收线程,它确实接收所有传入消息:

同时(!终止){

}

我想将连接分成 3 个或更多,这样根本不会出现交错的 request/response 消息 - 但我认为这个想法不是很好,因为 a) 处理多个连接会使它变得更加困难为了保持游戏稳定和 b) 从长远来看,应该可以在同一个 iOS 应用程序实例中并行玩多个游戏会话。

目前我认为信号量和 sleep() 可以工作,这类似于在服务器上实现的模式。但在尝试实施之前,我想知道这是否可行。信号量似乎非常快,但我需要数百万个信号量 - 每个唯一消息 ID 一个)。 如果使用信号量:我将如何实现 wait() ?使用带睡眠的繁忙循环并轮询信号量? 我认为 wait() 只需在信号量上使用 wait()。

提前感谢您的任何反馈或想法。

What I need however is some kind of wait/notify like in Java.

这在 iOS 中效果不佳。它会生成过多的阻塞线程,从而导致整个系统死锁。相反,您需要考虑队列,而不是线程。

一般来说,iOS 中的处理方式是在请求中包含一个完成处理程序或委托。所以你的请求看起来像:

conn.sendRequest(request, completion: {
   // thing to do when it completes
})

这不阻塞。 sendRequest 会将 completion 放入请求标识符的字典中 -> 完成处理程序。当响应返回时,您然后查找完成处理程序并执行它。例如:

if let handler = self.handlers[identifier] {
    handler(response)
} else {
    // We got a response we weren't expecting... This may be an error, or we might ignore.
}

有关 async/await 模型为何在 iOS 中表现不佳的更多详细信息,请参阅 使用 GCD 构建响应迅速且高效的应用程序 。另请参阅 Concurrency Programming Guide,尤其是 "Migrating Away from Threads."

部分