我正在将Swift MacOS命令行工具/守护进程转换为使用Swift-NIO进行联网。这是我的第一个Swift-NIO项目。
该工具每0.1秒触发一个计时器。下面是main.swift底部的一行代码,它在Swift-NIO转换之前启动守护进程/运行循环:
RunLoop.current.run()下面是我的Universe.swift类init()中的计时器。此类始终只有一个实例:
timer = Timer(timeInterval: 1.0 / updatesPerSecond, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
timer?.tolerance = 0.3 / updatesPerSecond
debugPrint("Timer initialized")
if let timer = timer {
RunLoop.current.add(timer, forMode: RunLoop.Mode.common)
}在此配置中,计时器按预期每秒触发10次。但是如果我得到任何网络输入,我的Swift-NIO库就会崩溃,因为它不在预期的事件循环中。

在Swift-NIO中,我应该在main.swift的底部添加一行channel.closeFuture.wait():
// This will never unblock as we don't close the ServerChannel.
try channel.closeFuture.wait()
RunLoop.current.run()这解决了Swift-NIO崩溃的问题,但是我从来没有到达我的计时器RunLoop,所以我的计时器不会触发。
如何使用Swift-NIO接收(和发送)网络数据,同时计时器仍在运行?
如果有帮助的话,这个项目的完整开源可以在https://github.com/darrellroot/netrek-server-swift上找到。
发布于 2020-07-10 06:49:13
卢卡萨是对的。我遗漏了(也不理解)一些重要的上下文。
我的计时器最终尝试使用SwiftNIO发送数据,如下所示:
if let context = context {
let buffer = context.channel.allocator.buffer(bytes: data)
_ = context.channel.writeAndFlush(buffer)
}修复方法是将流量的发送“分派”到上下文相关的EventLoop:
if let context = context {
context.eventLoop.execute {
let buffer = context.channel.allocator.buffer(bytes: data)
_ = context.channel.writeAndFlush(buffer)
}
}它感觉非常类似于在iOS应用程序中更新图形用户界面的DispatchQueue.main.async {},但使用了不同的Swift-NIO相关术语。
https://stackoverflow.com/questions/62804380
复制相似问题