UploadHubSample.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. #if !BESTHTTP_DISABLE_SIGNALR_CORE
  2. using BestHTTP;
  3. using BestHTTP.Examples.Helpers;
  4. using BestHTTP.SignalRCore;
  5. using BestHTTP.SignalRCore.Encoders;
  6. using System;
  7. using System.Collections;
  8. using UnityEngine;
  9. using UnityEngine.UI;
  10. namespace BestHTTP.Examples
  11. {
  12. /// <summary>
  13. /// This sample demonstrates redirection capabilities. The server will redirect a few times the client before
  14. /// routing it to the final endpoint.
  15. /// </summary>
  16. public sealed class UploadHubSample : BestHTTP.Examples.Helpers.SampleBase
  17. {
  18. #pragma warning disable 0649
  19. [SerializeField]
  20. private string _path = "/uploading";
  21. [SerializeField]
  22. private ScrollRect _scrollRect;
  23. [SerializeField]
  24. private RectTransform _contentRoot;
  25. [SerializeField]
  26. private TextListItem _listItemPrefab;
  27. [SerializeField]
  28. private int _maxListItemEntries = 100;
  29. [SerializeField]
  30. private Button _connectButton;
  31. [SerializeField]
  32. private Button _closeButton;
  33. [SerializeField]
  34. private float _yieldWaitTime = 0.1f;
  35. #pragma warning restore
  36. // Instance of the HubConnection
  37. private HubConnection hub;
  38. protected override void Start()
  39. {
  40. base.Start();
  41. SetButtons(true, false);
  42. }
  43. void OnDestroy()
  44. {
  45. if (hub != null)
  46. {
  47. hub.StartClose();
  48. }
  49. }
  50. public void OnConnectButton()
  51. {
  52. #if BESTHTTP_SIGNALR_CORE_ENABLE_MESSAGEPACK_CSHARP
  53. try
  54. {
  55. MessagePack.Resolvers.StaticCompositeResolver.Instance.Register(
  56. MessagePack.Resolvers.DynamicEnumAsStringResolver.Instance,
  57. MessagePack.Unity.UnityResolver.Instance,
  58. //MessagePack.Unity.Extension.UnityBlitWithPrimitiveArrayResolver.Instance,
  59. //MessagePack.Resolvers.StandardResolver.Instance,
  60. MessagePack.Resolvers.ContractlessStandardResolver.Instance
  61. );
  62. var options = MessagePack.MessagePackSerializerOptions.Standard.WithResolver(MessagePack.Resolvers.StaticCompositeResolver.Instance);
  63. MessagePack.MessagePackSerializer.DefaultOptions = options;
  64. }
  65. catch
  66. { }
  67. #endif
  68. IProtocol protocol = null;
  69. #if BESTHTTP_SIGNALR_CORE_ENABLE_MESSAGEPACK_CSHARP
  70. protocol = new MessagePackCSharpProtocol();
  71. #elif BESTHTTP_SIGNALR_CORE_ENABLE_GAMEDEVWARE_MESSAGEPACK
  72. protocol = new MessagePackProtocol();
  73. #else
  74. protocol = new JsonProtocol(new LitJsonEncoder());
  75. #endif
  76. // Crete the HubConnection
  77. hub = new HubConnection(new Uri(this.sampleSelector.BaseURL + this._path), protocol);
  78. // Subscribe to hub events
  79. hub.OnConnected += Hub_OnConnected;
  80. hub.OnError += Hub_OnError;
  81. hub.OnClosed += Hub_OnClosed;
  82. hub.OnRedirected += Hub_Redirected;
  83. hub.OnTransportEvent += (hub, transport, ev) => AddText(string.Format("Transport(<color=green>{0}</color>) event: <color=green>{1}</color>", transport.TransportType, ev));
  84. // And finally start to connect to the server
  85. hub.StartConnect();
  86. AddText("StartConnect called");
  87. SetButtons(false, false);
  88. }
  89. public void OnCloseButton()
  90. {
  91. if (this.hub != null)
  92. {
  93. this.hub.StartClose();
  94. AddText("StartClose called");
  95. SetButtons(false, false);
  96. }
  97. }
  98. private void Hub_Redirected(HubConnection hub, Uri oldUri, Uri newUri)
  99. {
  100. AddText(string.Format("Hub connection redirected to '<color=green>{0}</color>'!", hub.Uri));
  101. }
  102. /// <summary>
  103. /// This callback is called when the plugin is connected to the server successfully. Messages can be sent to the server after this point.
  104. /// </summary>
  105. private void Hub_OnConnected(HubConnection hub)
  106. {
  107. AddText(string.Format("Hub Connected with <color=green>{0}</color> transport using the <color=green>{1}</color> encoder.", hub.Transport.TransportType.ToString(), hub.Protocol.Name));
  108. StartCoroutine(UploadWord());
  109. SetButtons(false, true);
  110. }
  111. private IEnumerator UploadWord()
  112. {
  113. AddText("<color=green>UploadWord</color>:");
  114. var controller = hub.GetUpStreamController<string, string>("UploadWord");
  115. controller.OnSuccess(result =>
  116. {
  117. AddText(string.Format("UploadWord completed, result: '<color=yellow>{0}</color>'", result))
  118. .AddLeftPadding(20);
  119. AddText("");
  120. StartCoroutine(ScoreTracker());
  121. });
  122. yield return new WaitForSeconds(_yieldWaitTime);
  123. controller.UploadParam("Hello ");
  124. AddText("'<color=green>Hello </color>' uploaded!")
  125. .AddLeftPadding(20);
  126. yield return new WaitForSeconds(_yieldWaitTime);
  127. controller.UploadParam("World");
  128. AddText("'<color=green>World</color>' uploaded!")
  129. .AddLeftPadding(20);
  130. yield return new WaitForSeconds(_yieldWaitTime);
  131. controller.UploadParam("!!");
  132. AddText("'<color=green>!!</color>' uploaded!")
  133. .AddLeftPadding(20);
  134. yield return new WaitForSeconds(_yieldWaitTime);
  135. controller.Finish();
  136. AddText("Sent upload finished message.")
  137. .AddLeftPadding(20);
  138. yield return new WaitForSeconds(_yieldWaitTime);
  139. }
  140. private IEnumerator ScoreTracker()
  141. {
  142. AddText("<color=green>ScoreTracker</color>:");
  143. var controller = hub.GetUpStreamController<string, int, int>("ScoreTracker");
  144. controller.OnSuccess(result =>
  145. {
  146. AddText(string.Format("ScoreTracker completed, result: '<color=yellow>{0}</color>'", result))
  147. .AddLeftPadding(20);
  148. AddText("");
  149. StartCoroutine(ScoreTrackerWithParameterChannels());
  150. });
  151. const int numScores = 5;
  152. for (int i = 0; i < numScores; i++)
  153. {
  154. yield return new WaitForSeconds(_yieldWaitTime);
  155. int p1 = UnityEngine.Random.Range(0, 10);
  156. int p2 = UnityEngine.Random.Range(0, 10);
  157. controller.UploadParam(p1, p2);
  158. AddText(string.Format("Score({0}/{1}) uploaded! p1's score: <color=green>{2}</color> p2's score: <color=green>{3}</color>", i + 1, numScores, p1, p2))
  159. .AddLeftPadding(20);
  160. }
  161. yield return new WaitForSeconds(_yieldWaitTime);
  162. controller.Finish();
  163. AddText("Sent upload finished message.")
  164. .AddLeftPadding(20);
  165. yield return new WaitForSeconds(_yieldWaitTime);
  166. }
  167. private IEnumerator ScoreTrackerWithParameterChannels()
  168. {
  169. AddText("<color=green>ScoreTracker using upload channels</color>:");
  170. using (var controller = hub.GetUpStreamController<string, int, int>("ScoreTracker"))
  171. {
  172. controller.OnSuccess(result =>
  173. {
  174. AddText(string.Format("ScoreTracker completed, result: '<color=yellow>{0}</color>'", result))
  175. .AddLeftPadding(20);
  176. AddText("");
  177. StartCoroutine(StreamEcho());
  178. });
  179. const int numScores = 5;
  180. // While the server's ScoreTracker has two parameters, we can upload those parameters separately
  181. // So here we
  182. using (var player1param = controller.GetUploadChannel<int>(0))
  183. {
  184. for (int i = 0; i < numScores; i++)
  185. {
  186. yield return new WaitForSeconds(_yieldWaitTime);
  187. int score = UnityEngine.Random.Range(0, 10);
  188. player1param.Upload(score);
  189. AddText(string.Format("Player 1's score({0}/{1}) uploaded! Score: <color=green>{2}</color>", i + 1, numScores, score))
  190. .AddLeftPadding(20);
  191. }
  192. }
  193. AddText("");
  194. using (var player2param = controller.GetUploadChannel<int>(1))
  195. {
  196. for (int i = 0; i < numScores; i++)
  197. {
  198. yield return new WaitForSeconds(_yieldWaitTime);
  199. int score = UnityEngine.Random.Range(0, 10);
  200. player2param.Upload(score);
  201. AddText(string.Format("Player 2's score({0}/{1}) uploaded! Score: <color=green>{2}</color>", i + 1, numScores, score))
  202. .AddLeftPadding(20);
  203. }
  204. }
  205. AddText("All scores uploaded!")
  206. .AddLeftPadding(20);
  207. }
  208. yield return new WaitForSeconds(_yieldWaitTime);
  209. }
  210. private IEnumerator StreamEcho()
  211. {
  212. AddText("<color=green>StreamEcho</color>:");
  213. using (var controller = hub.GetUpAndDownStreamController<string, string>("StreamEcho"))
  214. {
  215. controller.OnSuccess(result =>
  216. {
  217. AddText("StreamEcho completed!")
  218. .AddLeftPadding(20);
  219. AddText("");
  220. StartCoroutine(PersonEcho());
  221. });
  222. controller.OnItem(item =>
  223. {
  224. AddText(string.Format("Received from server: '<color=yellow>{0}</color>'", item))
  225. .AddLeftPadding(20);
  226. });
  227. const int numMessages = 5;
  228. for (int i = 0; i < numMessages; i++)
  229. {
  230. yield return new WaitForSeconds(_yieldWaitTime);
  231. string message = string.Format("Message from client {0}/{1}", i + 1, numMessages);
  232. controller.UploadParam(message);
  233. AddText(string.Format("Sent message to the server: <color=green>{0}</color>", message))
  234. .AddLeftPadding(20);
  235. }
  236. yield return new WaitForSeconds(_yieldWaitTime);
  237. }
  238. AddText("Upload finished!")
  239. .AddLeftPadding(20);
  240. yield return new WaitForSeconds(_yieldWaitTime);
  241. }
  242. /// <summary>
  243. /// This is basically the same as the previous StreamEcho, but it's streaming a complex object (Person
  244. /// </summary>
  245. private IEnumerator PersonEcho()
  246. {
  247. AddText("<color=green>PersonEcho</color>:");
  248. using (var controller = hub.GetUpAndDownStreamController<Person, Person>("PersonEcho"))
  249. {
  250. controller.OnSuccess(result =>
  251. {
  252. AddText("PersonEcho completed!")
  253. .AddLeftPadding(20);
  254. AddText("");
  255. AddText("All Done!");
  256. });
  257. controller.OnItem(item =>
  258. {
  259. AddText(string.Format("Received from server: '<color=yellow>{0}</color>'", item))
  260. .AddLeftPadding(20);
  261. });
  262. const int numMessages = 5;
  263. for (int i = 0; i < numMessages; i++)
  264. {
  265. yield return new WaitForSeconds(_yieldWaitTime);
  266. Person person = new Person()
  267. {
  268. Name = "Mr. Smith",
  269. Age = 20 + i * 2
  270. };
  271. controller.UploadParam(person);
  272. AddText(string.Format("Sent person to the server: <color=green>{0}</color>", person))
  273. .AddLeftPadding(20);
  274. }
  275. yield return new WaitForSeconds(_yieldWaitTime);
  276. }
  277. AddText("Upload finished!")
  278. .AddLeftPadding(20);
  279. yield return new WaitForSeconds(_yieldWaitTime);
  280. }
  281. /// <summary>
  282. /// This is called when the hub is closed after a StartClose() call.
  283. /// </summary>
  284. private void Hub_OnClosed(HubConnection hub)
  285. {
  286. AddText("Hub Closed");
  287. SetButtons(true, false);
  288. }
  289. /// <summary>
  290. /// Called when an unrecoverable error happen. After this event the hub will not send or receive any messages.
  291. /// </summary>
  292. private void Hub_OnError(HubConnection hub, string error)
  293. {
  294. AddText(string.Format("Hub Error: <color=red>{0}</color>", error));
  295. SetButtons(true, false);
  296. }
  297. private void SetButtons(bool connect, bool close)
  298. {
  299. if (this._connectButton != null)
  300. this._connectButton.interactable = connect;
  301. if (this._closeButton != null)
  302. this._closeButton.interactable = close;
  303. }
  304. private TextListItem AddText(string text)
  305. {
  306. return GUIHelper.AddText(this._listItemPrefab, this._contentRoot, text, this._maxListItemEntries, this._scrollRect);
  307. }
  308. }
  309. }
  310. #endif