如何在应用程序终止时发送网络请求?

How to send a web request at application termination?

我的任务是关于 Unity 游戏引擎,但一般来说可能适用于所有游戏或所有应用程序。

我正在为 Unity 编写一个插件,它需要在游戏会话的某些时候 yield return UnityWebRequest.SendWebRequest()。理想情况下,如果用户关闭游戏(例如,从游戏 运行s 所在的操作系统关闭 window),我还需要发送此类请求。

Unity 的 onApplicationQuit 预定义回调可以,但似乎我无法在那里启动协程(异步操作),因为在应用程序终止时所有游戏对象都被销毁并且根本不够处理 Web 请求的时间:不是在一帧内,如果在应用程序关闭时有 "grace period",甚至不会在几帧内。

游戏是如何解决这些问题的?应用程序一般是怎么解决的?它是关于在一切都被破坏并且操作系统不会等待您的应用程序接收结果甚至首先发送请求时启动异步操作。


想到的一个解决方案是尝试定期发送数据。但是,我已经在这样做了。所以,问题在于最后一个请求没有发送,因为应用程序突然关闭。


我能想到的另一个解决方案是存储需要发送的数据(例如,发送到 PlayerPrefs 或简单地发送到我自己格式的一些自定义文件)并在下次应用启动时 检查是否有任何待发送的数据。 但是,这并不总是适用于我的情况,因为:

  1. 游戏可能再也不会启动了。用户可能只是卸载它。所以,数据会丢失
  2. 我的服务器有一个最大允许时间,在此之后请求将被拒绝,所以它必须在游戏会话内或之后不久发送,而不是 1 个月后

另一种解决方案:下载一个可执行文件,当游戏关闭时,然后在 onApplicationQuit 中使用 System.Diagnostics.Process 到 运行 该可执行文件并在后台执行请求。所以,基本上,在游戏 window 关闭后,我会有另一个进程进行清理和报告。然而,这在两个方面是不好的:

  1. 无法跨平台工作(Windows、Mac、Linux 和其他平台需要单独的可执行文件 - 理想情况下我希望插件 运行在 Unity 可以构建的每个平台上)
  2. 每个可执行文件都需要以自己的方式处理网络逻辑——与 Unity 提供的简单、统一的界面相比,这是一项工作开销。

还有其他解决方案吗?

(顺便说一句,我已经放弃了应用程序崩溃的情况 - 除了我已经定期发送的请求外,我不希望在那个时候发送任何东西)

另一种可能的解决方案是 https://docs.unity3d.com/ScriptReference/Application-wantsToQuit.html

Unity raises this event when the player application wants to quit.

Add an event handler to this event to receive a notification that application is attempting to quit.

When this event is raised the quit process has started but can be cancelled. This means the player is not guaranteed to quit. For a guaranteed quit event take a look at Application.quitting.

Return true and the quit process will continue. Return false and the quit process will cancel.

您会发现用户想要退出,发送您的 Web 请求,完成后,您自己致电 Application.Quit