UploadOnDemandSample.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using System.Collections;
  2. using Best.HTTP.Examples.Helpers;
  3. using Best.HTTP.Request.Upload;
  4. using UnityEngine;
  5. namespace Best.HTTP.Examples
  6. {
  7. /// <summary>
  8. /// On-demand upload
  9. /// </summary>
  10. class UploadOnDemand : SampleBase
  11. {
  12. #pragma warning disable 0649, 0169
  13. [Header("Sample Fields")]
  14. /// <summary>
  15. /// GameObject that will be used as a root for new UI objects.
  16. /// </summary>
  17. [SerializeField]
  18. private RectTransform _contentRoot;
  19. /// <summary>
  20. /// Prefab of a UI object with two Text fields.
  21. /// </summary>
  22. [SerializeField]
  23. private MultiTextListItem _listItemPrefab;
  24. #pragma warning restore
  25. /// <summary>
  26. /// Address of the used end point.
  27. /// </summary>
  28. private string _baseAddress = "https://httpbin.org/post";
  29. protected override void Start()
  30. {
  31. base.Start();
  32. // create request
  33. var request = HTTPRequest.CreatePost(_baseAddress, OnUploadFinished);
  34. // setup
  35. request.UploadSettings.UploadStream = new DynamicUploadStream();
  36. request.UploadSettings.OnHeadersSent += UploadSettings_OnBeforeHeaderSend;
  37. // send
  38. request.Send();
  39. CreateUIText("Connecting...");
  40. }
  41. /// <summary>
  42. /// This callback fired before the request's headers are sent. It's a good opportunity to start generating our (fake) data.
  43. /// </summary>
  44. private void UploadSettings_OnBeforeHeaderSend(HTTPRequest req)
  45. => StartCoroutine(GenerateData(req));
  46. /// <summary>
  47. /// This is our main logic to generate fake data and feed it to the upload stream to send it to the server.
  48. /// </summary>
  49. private IEnumerator GenerateData(HTTPRequest req)
  50. {
  51. const int MAX_CHUNKS = 10;
  52. const int CHUNK_SIZE = 16 * 1024;
  53. CreateUIText("Connected, upload can start");
  54. // get the upload stream
  55. DynamicUploadStream uploadStream = req.UploadSettings.UploadStream as DynamicUploadStream;
  56. try
  57. {
  58. int uploadedChunks = 0;
  59. do
  60. {
  61. yield return new WaitForSeconds(2f);
  62. // check whether the request is finished, it can be in an errored state
  63. if (req.State >= HTTPRequestStates.Finished)
  64. break;
  65. // write the data to the stream and let the connection know about it
  66. uploadStream.Write(new byte[CHUNK_SIZE], 0, CHUNK_SIZE);
  67. CreateUIText($"Added new chunk to upload ({uploadedChunks + 1} / {MAX_CHUNKS})");
  68. } while (++uploadedChunks < MAX_CHUNKS);
  69. }
  70. finally
  71. {
  72. // complete upload
  73. uploadStream.Complete();
  74. }
  75. }
  76. /// <summary>
  77. /// Callback of the request when finished.
  78. /// </summary>
  79. private void OnUploadFinished(HTTPRequest req, HTTPResponse resp)
  80. {
  81. if (resp != null)
  82. {
  83. if (resp.IsSuccess)
  84. CreateUIText("Response recceived, finished succesfully!");
  85. else
  86. CreateUIText($"Finished with error: {resp.StatusCode} - {resp.Message}!");
  87. }
  88. else
  89. CreateUIText(req.State.ToString());
  90. }
  91. /// <summary>
  92. /// UI helper function to create a list item from a prefab and set its text to display.
  93. /// </summary>
  94. TextListItem CreateUIText(string text)
  95. => Instantiate<MultiTextListItem>(this._listItemPrefab, this._contentRoot)
  96. .SetText(text);
  97. }
  98. }