为什么我在 Mac 一段时间后停止接收 OSC 消息?
Why do I stop receiving OSC messages after a while on Mac?
我正在开发一款从 Muse EEG 耳机接收 OSC 消息的 Unity 游戏。我已经尝试了两个第 3 方 C# 库来处理 OSC 通信,UnityOSC
and unity-OSC-receiver
。两者都实现了与底层 System.Net.Sockets.UdpClient
的 OSC 通信。在Windows上一切运行都很顺利,但是在OSX上,过了一段时间,我就每次都收不到消息了。没有异常或错误消息,没有任何问题的迹象,只是沉默。
我的应用大致如下:
- 启动一个线程,该线程生成一个运行 Muse-IO 的进程。这使耳机开始发送消息。启动进程后,这个线程只是在
process.WaitforExit()
- 另一个线程运行 while 循环 - 不在
MonoBehavior.Update()
中,这不够快 - 不断接收和处理 OSC 消息。在这两个库中,这基本上归结为调用 UdpClient.Receive()
- 游戏在正常的 Unity 更新周期中使用经过处理的消息。
连接初始化后大约 120 到 140 秒,消息流就停止了,到目前为止我还没弄清楚原因。耳机上的连接指示灯常亮,但没有任何迹象表明它实际上仍在发送数据。
我已经排除的事情:
- 不是因为消息的数量或消息的大小。如果我修改对耳机的命令只发送某些类别的消息,将总数减半(从大约 600/s 到 300/s),超时仍然同时发生。
- 这不是 OSC 库。我在两个 OSC 库中得到了完全相同的结果。
- 这不是防火墙。防火墙已关闭。
- 它可能不是其他东西正在使用的端口。我尝试了不同的端口,结果相同。
- 它似乎不是 Muse 的 OSX 驱动程序。当我使用他们的 GUI 来可视化传入的数据时,它会根据我的需要持续接收数据。
我怀疑 Mono、Unity 或 OSX 可能正在关闭(垃圾收集?)Muse-IO 进程或线程,因为问题发生之前的时间似乎几乎是恒定的,无论我尝试什么。但我不确定如何进一步诊断,更不用说现在解决这个问题了。任何线索、建议或惊人的解决方案都将受到欢迎。
找到原因了。
生成 I/O 进程后,线程将执行
print("Process started!");
process.PriorityClass = ProcessPriorityClass.High;
process.WaitforExit();
事后看来,那个打印语句真的放错了地方,唉。它在 Windows 上运行良好。如果您将其增加到实时,则更改进程优先级只需要管理员权限,according to the docs。不过 Mac 不是这样。显然将其设置为“高”还需要提升 OSX 的权限。结果异常是 silent/undetected/uncaught 因为它发生在主线程之外。
然后,几分钟后,线程似乎已被垃圾回收,包括其子进程,尽管它仍然是 运行。那个延迟真的让我失望,让我在所有错误的地方寻找原因。
经验教训:
- 多线程时要更加小心可能出现的异常,
- 如果不是绝对必要,请不要弄乱进程优先级,
- 永远不要相信文档。
我正在开发一款从 Muse EEG 耳机接收 OSC 消息的 Unity 游戏。我已经尝试了两个第 3 方 C# 库来处理 OSC 通信,UnityOSC
and unity-OSC-receiver
。两者都实现了与底层 System.Net.Sockets.UdpClient
的 OSC 通信。在Windows上一切运行都很顺利,但是在OSX上,过了一段时间,我就每次都收不到消息了。没有异常或错误消息,没有任何问题的迹象,只是沉默。
我的应用大致如下:
- 启动一个线程,该线程生成一个运行 Muse-IO 的进程。这使耳机开始发送消息。启动进程后,这个线程只是在
process.WaitforExit()
- 另一个线程运行 while 循环 - 不在
MonoBehavior.Update()
中,这不够快 - 不断接收和处理 OSC 消息。在这两个库中,这基本上归结为调用UdpClient.Receive()
- 游戏在正常的 Unity 更新周期中使用经过处理的消息。
连接初始化后大约 120 到 140 秒,消息流就停止了,到目前为止我还没弄清楚原因。耳机上的连接指示灯常亮,但没有任何迹象表明它实际上仍在发送数据。
我已经排除的事情:
- 不是因为消息的数量或消息的大小。如果我修改对耳机的命令只发送某些类别的消息,将总数减半(从大约 600/s 到 300/s),超时仍然同时发生。
- 这不是 OSC 库。我在两个 OSC 库中得到了完全相同的结果。
- 这不是防火墙。防火墙已关闭。
- 它可能不是其他东西正在使用的端口。我尝试了不同的端口,结果相同。
- 它似乎不是 Muse 的 OSX 驱动程序。当我使用他们的 GUI 来可视化传入的数据时,它会根据我的需要持续接收数据。
我怀疑 Mono、Unity 或 OSX 可能正在关闭(垃圾收集?)Muse-IO 进程或线程,因为问题发生之前的时间似乎几乎是恒定的,无论我尝试什么。但我不确定如何进一步诊断,更不用说现在解决这个问题了。任何线索、建议或惊人的解决方案都将受到欢迎。
找到原因了。
生成 I/O 进程后,线程将执行
print("Process started!");
process.PriorityClass = ProcessPriorityClass.High;
process.WaitforExit();
事后看来,那个打印语句真的放错了地方,唉。它在 Windows 上运行良好。如果您将其增加到实时,则更改进程优先级只需要管理员权限,according to the docs。不过 Mac 不是这样。显然将其设置为“高”还需要提升 OSX 的权限。结果异常是 silent/undetected/uncaught 因为它发生在主线程之外。
然后,几分钟后,线程似乎已被垃圾回收,包括其子进程,尽管它仍然是 运行。那个延迟真的让我失望,让我在所有错误的地方寻找原因。
经验教训:
- 多线程时要更加小心可能出现的异常,
- 如果不是绝对必要,请不要弄乱进程优先级,
- 永远不要相信文档。