none
DownloadOperation是否支持真正的断点续传? RRS feed

  • 问题

  • 前提:服务器支持断点续传(range)

    1.DownloadOperation下载特别大的内容时候,比如100M,下载到99M,如果应用被关闭了,再进来是否是重新下载?

    2.DownloadOperation的方式下,有没有办法在退出时保存住已下载东西到本地文件,下次开启应用时候继续下载?

    3.如果我用HttpClient实现,有没有可能实现真正的断点续传,下一点存在本地一点,下次继续这种?能否指点一二?

    2013年1月22日 11:22

答案

  • Hi,

    请参考这两个文档:

    DownLoadOperation:

    http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.downloadoperation

    Background Transfer:

    http://msdn.microsoft.com/en-us/library/windows/apps/xaml/Hh452975(v=win.10)

    1)Background Tranfer有这样一段话:

    Use the Windows.Networking.BackgroundTransfer APIs provided in the Windows Runtime to enhance your Windows Store app with advanced file download and upload features that run in the background during app suspension, demonstrate per operation lifecycle management, and persist beyond app termination.

    虽然这里面没有说过这个运行在BackgroundTask中但实际上这句话就是说明了这一点,即使是应用挂起或者是终结也不会对下载造成影响。因此应用关闭或者是刮起等需要对Background Tranfer进行什么操作需要你自己来做。而DownloadOperation文档中也给出了到底应该怎么样做:

    After app termination, an app should enumerate all existing DownloadOperation instances at next start-up usingGetCurrentDownloadsAsync. When a Windows Store app using Background Transfer is terminated, incomplete downloads will persist in the background. If the app is restarted after termination and these incomplete operations are not enumerated and re-introduced to the current session, they will go stale and continue to occupy device resources.

    2)断点续传是支持的,不过也需要服务器支持:

    Note  Paused or incomplete download operations can only be resumed if the server accepts range-requests.

    也可以参考这个帖子(有时候资源会重定向这样断点续传就不行了):

    http://social.msdn.microsoft.com/forums/zh-cn/winstoreappzhcn/thread/09a1a4eb-2c6c-4beb-bd24-b56f8b0fd92d

    3)HttpClient 如果你用GetStreamAsync()不行,因为这个只有在全部读完之后返回不存储buffer。如果使用断点续传最好用Background transfer


    Aaron
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 zengluyang 2013年1月24日 11:01
    2013年1月23日 9:59
    版主

  • zengluyang 你好,

    关于您提到的用backgroundTransfer来实现断点续传功能的问题,以下是我的一些看法和建议。

    传统意义上的断点续传诸如“网络蚂蚁","flashget"等软件做的那种是需要服务端HTTP支持的,并不是光客户端就可以做到的。这种断点续传的目的是针对网络断开,或者认为终止HTTP下载后仍然可以在下次从指定的位置继续下载。具体实现应该是通过一些特定的http header 以及协议的规范来做的。如果您要实现的是这类功能,那么您不妨从以下的角度来考虑您目前需要处理的问题:

    * 您的windows 商店应用中要下载的服务端资源是否支持断点续传?
    * 如果支持,假设您现在编写的是一个普通的.net程序(比如winform或者 console程序),您该怎么用HttpWebRequest 类来实现这样的客户端?

    一旦以上的问题解决了,其实您可以把同样的代码逻辑用windows商店应用中特定的 httpclient 类来实现。标准HTTP断点续传的协议以及相关代码您可以在网上搜索以下。

    现在我们再回到windows 商店应用编程中的 BackgroundTransfer组件。这个组件根据文档的描述是主要针对以下这样的场景和目的:

    * 我们的商店应用需要下载较大的文件,比如视频, 音频,压缩包等,同时下载时间可能较长。。。。
    * 我们的商店应用可能随时会被挂起(suspended),因此WinJS.xhr 或者HttpClient类的方法无法应付这种情形

    而是用backgroundTransfer可以使得下载的操作被系统在另一个环境(和我们调用BackgroundTransfer的商店应用不同)中被执行,这样即便应用被挂起,下载的代码仍然继续在执行,我们可以不断更新记录下载进度以便在下次应用再次被激活的时候更新界面信息。 但是BackgroundTransfer这种方式并不是专门用来解决我上述提到的传统意义上的“断点续传”功能的。这点从BackgroundTransfer并没有对目标资源做出具体特殊的要求就可以看出,任何HTTP资源他都能下载,因此这也决定了他无法用来保证断点续传。只是能一定程度的针对某些情况(比如程序挂起或者网络短暂断掉等)起到缓解的问题。 要实现传统意义上的断点续传,还是需要我们根据HTTP中断点续传相关的协议支持来自己用HttpClient等组件来实现。


    #Transferring data in the background (Windows Store apps using JavaScript and HTML) (Windows)
    http://msdn.microsoft.com/en-us/library/windows/apps/hh452979.aspx

    希望有所帮助。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 zengluyang 2013年1月30日 1:46
    2013年1月28日 10:05
  • 不客气,很高兴您已经找到了解决的方法。

    关于程序被挂起后的运行,其实是这样的。无论是否debug,windows 商店应用被挂起(比如当用户切换到新的应用)后,系统会根据当前的全局资源使用情况来决定何时把程序彻底移除(也就是终止)。在资源不紧张的情况下可能会慢一点,这个时间并不是人为可以控制或者指定的。因此对于我们开发人员来说,尽量用suspend相关的event来判断程序被挂起(左一些简单的状态记录工作),使得一些在运行模式下才执行的代码即使暂停保存状态,等待程序再次被激活/启动的时候再继续。 千万不要因为挂起后程序还可能继续执行就依赖于这样的行为,一个明显的例子就是有人会用javascript timer 去执行一些定期的代码,当程序被挂起后timer可能还会继续执行一会,但是一旦彻底终止就不会执行了,这种情况正确的做法是要么再挂起时候终止timer保存状态,下次启动时再执行;或者干脆改用background task 来做,这样即便挂起也会继续执行。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 zengluyang 2013年1月30日 2:23
    2013年1月30日 2:16

全部回复

  • Hi,

    请参考这两个文档:

    DownLoadOperation:

    http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.downloadoperation

    Background Transfer:

    http://msdn.microsoft.com/en-us/library/windows/apps/xaml/Hh452975(v=win.10)

    1)Background Tranfer有这样一段话:

    Use the Windows.Networking.BackgroundTransfer APIs provided in the Windows Runtime to enhance your Windows Store app with advanced file download and upload features that run in the background during app suspension, demonstrate per operation lifecycle management, and persist beyond app termination.

    虽然这里面没有说过这个运行在BackgroundTask中但实际上这句话就是说明了这一点,即使是应用挂起或者是终结也不会对下载造成影响。因此应用关闭或者是刮起等需要对Background Tranfer进行什么操作需要你自己来做。而DownloadOperation文档中也给出了到底应该怎么样做:

    After app termination, an app should enumerate all existing DownloadOperation instances at next start-up usingGetCurrentDownloadsAsync. When a Windows Store app using Background Transfer is terminated, incomplete downloads will persist in the background. If the app is restarted after termination and these incomplete operations are not enumerated and re-introduced to the current session, they will go stale and continue to occupy device resources.

    2)断点续传是支持的,不过也需要服务器支持:

    Note  Paused or incomplete download operations can only be resumed if the server accepts range-requests.

    也可以参考这个帖子(有时候资源会重定向这样断点续传就不行了):

    http://social.msdn.microsoft.com/forums/zh-cn/winstoreappzhcn/thread/09a1a4eb-2c6c-4beb-bd24-b56f8b0fd92d

    3)HttpClient 如果你用GetStreamAsync()不行,因为这个只有在全部读完之后返回不存储buffer。如果使用断点续传最好用Background transfer


    Aaron
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 zengluyang 2013年1月24日 11:01
    2013年1月23日 9:59
    版主
  • 谢谢你的回复,同时我还有问题:
    1.公司带宽10M,内网测试BackgroundDownloader下载很快,几秒种下完了,服务器支持断点续传,BackgroundDownloader发的请求头没有Range,它的实现原理能稍微讲讲吗? (BD是否会动态监测网络环境啊,如果确定很快能下载下来就不发Range啊?请求头无Range是否能解释我暂停后不能恢复只能重下?)
    2.我在应用起来时候会去调GetCurrentDownloadsAsync(),用法上跟官方Sample差不多,但以下几种情况都不行:暂停再恢复,断网再连上,关闭App再打开。。。
    请问BackgroundDownloader的需要一些特殊设置才能断点续传吗?比如BackgroundDownloader请求头设置有什么特殊要求吗?感觉它就是个黑箱,没有好的调试办法,请给些指点。
    2013年1月24日 11:21
  • Hi,

    抱歉,因为我也不太清楚BackgroundDownloader中内部实现原理,不过从公开的文档和实际效果来看,这个的确是支持断点续传。你说的几种情况你看一下是不是url变化了。

    关于实现原理的问题,我会让更多地微软专家帮助你。


    Aaron
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月28日 6:04
    版主

  • zengluyang 你好,

    关于您提到的用backgroundTransfer来实现断点续传功能的问题,以下是我的一些看法和建议。

    传统意义上的断点续传诸如“网络蚂蚁","flashget"等软件做的那种是需要服务端HTTP支持的,并不是光客户端就可以做到的。这种断点续传的目的是针对网络断开,或者认为终止HTTP下载后仍然可以在下次从指定的位置继续下载。具体实现应该是通过一些特定的http header 以及协议的规范来做的。如果您要实现的是这类功能,那么您不妨从以下的角度来考虑您目前需要处理的问题:

    * 您的windows 商店应用中要下载的服务端资源是否支持断点续传?
    * 如果支持,假设您现在编写的是一个普通的.net程序(比如winform或者 console程序),您该怎么用HttpWebRequest 类来实现这样的客户端?

    一旦以上的问题解决了,其实您可以把同样的代码逻辑用windows商店应用中特定的 httpclient 类来实现。标准HTTP断点续传的协议以及相关代码您可以在网上搜索以下。

    现在我们再回到windows 商店应用编程中的 BackgroundTransfer组件。这个组件根据文档的描述是主要针对以下这样的场景和目的:

    * 我们的商店应用需要下载较大的文件,比如视频, 音频,压缩包等,同时下载时间可能较长。。。。
    * 我们的商店应用可能随时会被挂起(suspended),因此WinJS.xhr 或者HttpClient类的方法无法应付这种情形

    而是用backgroundTransfer可以使得下载的操作被系统在另一个环境(和我们调用BackgroundTransfer的商店应用不同)中被执行,这样即便应用被挂起,下载的代码仍然继续在执行,我们可以不断更新记录下载进度以便在下次应用再次被激活的时候更新界面信息。 但是BackgroundTransfer这种方式并不是专门用来解决我上述提到的传统意义上的“断点续传”功能的。这点从BackgroundTransfer并没有对目标资源做出具体特殊的要求就可以看出,任何HTTP资源他都能下载,因此这也决定了他无法用来保证断点续传。只是能一定程度的针对某些情况(比如程序挂起或者网络短暂断掉等)起到缓解的问题。 要实现传统意义上的断点续传,还是需要我们根据HTTP中断点续传相关的协议支持来自己用HttpClient等组件来实现。


    #Transferring data in the background (Windows Store apps using JavaScript and HTML) (Windows)
    http://msdn.microsoft.com/en-us/library/windows/apps/hh452979.aspx

    希望有所帮助。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 zengluyang 2013年1月30日 1:46
    2013年1月28日 10:05
  • 感谢Steven Cheng的回复!已经用传统方法实现了,用BD下载抓到的包也正好印证了您的说法,现在不就结了。

    另外我发现在Debug状态下让程序挂起或者终止它,程序都会再继续运行一小段时间,这个时间可以自定义吗?这个时间是固定的还是不固定的?

    盼复!

    2013年1月30日 2:05
  • 不客气,很高兴您已经找到了解决的方法。

    关于程序被挂起后的运行,其实是这样的。无论是否debug,windows 商店应用被挂起(比如当用户切换到新的应用)后,系统会根据当前的全局资源使用情况来决定何时把程序彻底移除(也就是终止)。在资源不紧张的情况下可能会慢一点,这个时间并不是人为可以控制或者指定的。因此对于我们开发人员来说,尽量用suspend相关的event来判断程序被挂起(左一些简单的状态记录工作),使得一些在运行模式下才执行的代码即使暂停保存状态,等待程序再次被激活/启动的时候再继续。 千万不要因为挂起后程序还可能继续执行就依赖于这样的行为,一个明显的例子就是有人会用javascript timer 去执行一些定期的代码,当程序被挂起后timer可能还会继续执行一会,但是一旦彻底终止就不会执行了,这种情况正确的做法是要么再挂起时候终止timer保存状态,下次启动时再执行;或者干脆改用background task 来做,这样即便挂起也会继续执行。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 zengluyang 2013年1月30日 2:23
    2013年1月30日 2:16