using System; namespace BestHTTP.Examples { /// <summary> /// The html code for all the samples. These are used only in the WebPlayer demo. /// </summary> public static class CodeBlocks { #region TextureDownloadSample public static string TextureDownloadSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> System.Collections.Generic; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP; <span style=""color:blue;"">public</span> <span style=""color:blue;"">sealed</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">TextureDownloadSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The URL of the server that will serve the image resources</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">const</span> <span style=""color:blue;"">string</span> BaseURL = <span style=""color:#a31515;"">"http://besthttp.azurewebsites.net/Content/"</span>; <span style=""color:blue;""> #region</span> Private Fields <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The downloadable images</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">string</span>[] Images = <span style=""color:blue;"">new</span> <span style=""color:blue;"">string</span>[9] { <span style=""color:#a31515;"">"One.png"</span>, <span style=""color:#a31515;"">"Two.png"</span>, <span style=""color:#a31515;"">"Three.png"</span>, <span style=""color:#a31515;"">"Four.png"</span>, <span style=""color:#a31515;"">"Five.png"</span>, <span style=""color:#a31515;"">"Six.png"</span>, <span style=""color:#a31515;"">"Seven.png"</span>, <span style=""color:#a31515;"">"Eight.png"</span>, <span style=""color:#a31515;"">"Nine.png"</span> }; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The downloaded images will be stored as textures in this array</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Texture2D</span>[] Textures = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Texture2D</span>[9]; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> True if all images are loaded from the local cache instead of the server</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">bool</span> allDownloadedFromLocalCache; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> How many sent requests are finished</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">int</span> finishedCount; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> GUI scroll position</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Vector2</span> scrollPos; <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> Awake() { <span style=""color:green;"">// SaveLocal a well observable value</span> <span style=""color:green;"">// This is how many concurrent requests can be made to a server</span> <span style=""color:#2b91af;"">HTTPManager</span>.MaxConnectionPerServer = 1; <span style=""color:green;"">// Create placeholder textures</span> <span style=""color:blue;"">for</span> (<span style=""color:blue;"">int</span> i = 0; i < Images.Length; ++i) Textures[i] = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Texture2D</span>(100, 150); } <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:green;"">// SaveLocal back to its defualt value.</span> <span style=""color:#2b91af;"">HTTPManager</span>.MaxConnectionPerServer = 4; } <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { scrollPos = <span style=""color:#2b91af;"">GUILayout</span>.BeginScrollView(scrollPos); <span style=""color:green;"">// Draw out the textures</span> <span style=""color:#2b91af;"">GUILayout</span>.SelectionGrid(0, Textures, 3); <span style=""color:blue;"">if</span> (finishedCount == Images.Length && allDownloadedFromLocalCache) <span style=""color:#2b91af;"">GUIHelper</span>.DrawCenteredText(<span style=""color:#a31515;"">"All images loaded from the local cache!"</span>); <span style=""color:#2b91af;"">GUILayout</span>.FlexibleSpace(); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Max Connection/Server: "</span>, <span style=""color:#2b91af;"">GUILayout</span>.Width(150)); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#2b91af;"">HTTPManager</span>.MaxConnectionPerServer.ToString(), <span style=""color:#2b91af;"">GUILayout</span>.Width(20)); <span style=""color:#2b91af;"">HTTPManager</span>.MaxConnectionPerServer = (<span style=""color:blue;"">byte</span>)<span style=""color:#2b91af;"">GUILayout</span>.HorizontalSlider(<span style=""color:#2b91af;"">HTTPManager</span>.MaxConnectionPerServer, 1, 10); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Start Download"</span>)) DownloadImages(); <span style=""color:#2b91af;"">GUILayout</span>.EndScrollView(); }); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Private Helper Functions <span style=""color:blue;"">void</span> DownloadImages() { <span style=""color:green;"">// SaveLocal these metadatas to its initial values</span> allDownloadedFromLocalCache = <span style=""color:blue;"">true</span>; finishedCount = 0; <span style=""color:blue;"">for</span> (<span style=""color:blue;"">int</span> i = 0; i < Images.Length; ++i) { <span style=""color:green;"">// SaveLocal a blank placeholder texture, overriding previously downloaded texture</span> Textures[i] = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Texture2D</span>(100, 150); <span style=""color:green;"">// Construct the request</span> <span style=""color:blue;"">var</span> request = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">HTTPRequest</span>(<span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(BaseURL + Images[i]), ImageDownloaded); <span style=""color:green;"">// SaveLocal the Tag property, we can use it as a general storage bound to the request</span> request.Tag = Textures[i]; <span style=""color:green;"">// Send out the request</span> request.Send(); } } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Callback function of the image download http requests</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> ImageDownloaded(<span style=""color:#2b91af;"">HTTPRequest</span> req, <span style=""color:#2b91af;"">HTTPResponse</span> resp) { <span style=""color:green;"">// Increase the finished count regardless of the state of our request</span> finishedCount++; <span style=""color:blue;"">switch</span> (req.State) { <span style=""color:green;"">// The request finished without any problem.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Finished: <span style=""color:blue;"">if</span> (resp.IsSuccess) { <span style=""color:green;"">// Get the Texture from the Tag property</span> <span style=""color:#2b91af;"">Texture2D</span> tex = req.Tag <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">Texture2D</span>; <span style=""color:green;"">// Load the texture</span> tex.LoadImage(resp.Data); <span style=""color:green;"">// Update the cache-info variable</span> allDownloadedFromLocalCache = allDownloadedFromLocalCache && resp.IsFromCache; } <span style=""color:blue;"">else</span> { <span style=""color:#2b91af;"">Debug</span>.LogWarning(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}"</span>, resp.StatusCode, resp.Message, resp.DataAsText)); } <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request finished with an unexpected error. The request's Exception property may contain more info about the error.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Error: <span style=""color:#2b91af;"">Debug</span>.LogError(<span style=""color:#a31515;"">"Request Finished with Error! "</span> + (req.Exception != <span style=""color:blue;"">null</span> ? (req.Exception.Message + <span style=""color:#a31515;"">"\n"</span> + req.Exception.StackTrace) : <span style=""color:#a31515;"">"No Exception"</span>)); <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request aborted, initiated by the user.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Aborted: <span style=""color:#2b91af;"">Debug</span>.LogWarning(<span style=""color:#a31515;"">"Request Aborted!"</span>); <span style=""color:blue;"">break</span>; <span style=""color:green;"">// Ceonnecting to the server is timed out.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.ConnectionTimedOut: <span style=""color:#2b91af;"">Debug</span>.LogError(<span style=""color:#a31515;"">"Connection Timed Out!"</span>); <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request didn't finished in the given time.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.TimedOut: <span style=""color:#2b91af;"">Debug</span>.LogError(<span style=""color:#a31515;"">"Processing the request Timed Out!"</span>); <span style=""color:blue;"">break</span>; } } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region WebSocketSample public static string WebSocketSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP; <span style=""color:blue;"">using</span> BestHTTP.WebSocket; <span style=""color:blue;"">public</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">WebSocketSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:blue;""> #region</span> Private Fields <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The WebSocket address to connect</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">string</span> address = <span style=""color:#a31515;"">"ws://echo.websocket.org"</span>; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Default text to send</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">string</span> msgToSend = <span style=""color:#a31515;"">"Hello World!"</span>; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Debug text to draw on the gui</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">string</span> Text = <span style=""color:blue;"">string</span>.Empty; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Saved WebSocket instance</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">WebSocket</span> webSocket; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> GUI scroll position</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Vector2</span> scrollPos; <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:blue;"">if</span> (webSocket != <span style=""color:blue;"">null</span>) webSocket.Close(); } <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { scrollPos = <span style=""color:#2b91af;"">GUILayout</span>.BeginScrollView(scrollPos); <span style=""color:#2b91af;"">GUILayout</span>.Label(Text); <span style=""color:#2b91af;"">GUILayout</span>.EndScrollView(); <span style=""color:#2b91af;"">GUILayout</span>.Space(5); <span style=""color:#2b91af;"">GUILayout</span>.FlexibleSpace(); address = <span style=""color:#2b91af;"">GUILayout</span>.TextField(address); <span style=""color:blue;"">if</span> (webSocket == <span style=""color:blue;"">null</span> && <span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Open Web Socket"</span>)) { <span style=""color:green;"">// Create the WebSocket instance</span> webSocket = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">WebSocket</span>(<span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(address)); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">HTTPManager</span>.Proxy != <span style=""color:blue;"">null</span>) webSocket.InternalRequest.Proxy = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">HTTPProxy</span>(<span style=""color:#2b91af;"">HTTPManager</span>.Proxy.Address, <span style=""color:#2b91af;"">HTTPManager</span>.Proxy.Credentials, <span style=""color:blue;"">false</span>); <span style=""color:green;"">// Subscribe to the WS events</span> webSocket.OnOpen += OnOpen; webSocket.OnMessage += OnMessageReceived; webSocket.OnClosed += OnClosed; webSocket.OnError += OnError; <span style=""color:green;"">// Start connecting to the server</span> webSocket.Open(); Text += <span style=""color:#a31515;"">"Opening Web Socket...\n"</span>; } <span style=""color:blue;"">if</span> (webSocket != <span style=""color:blue;"">null</span> && webSocket.IsOpen) { <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); msgToSend = <span style=""color:#2b91af;"">GUILayout</span>.TextField(msgToSend); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Send"</span>, <span style=""color:#2b91af;"">GUILayout</span>.MaxWidth(70))) { Text += <span style=""color:#a31515;"">"Sending message...\n"</span>; <span style=""color:green;"">// Send message to the server</span> webSocket.Send(msgToSend); } <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Close"</span>)) { <span style=""color:green;"">// Close the connection</span> webSocket.Close(1000, <span style=""color:#a31515;"">"Bye!"</span>); } } }); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> WebSocket Event Handlers <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called when the web socket is open, and we are ready to send and receive data</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> OnOpen(<span style=""color:#2b91af;"">WebSocket</span> ws) { Text += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"-WebSocket Open!\n"</span>); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called when we received a text message from the server</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> OnMessageReceived(<span style=""color:#2b91af;"">WebSocket</span> ws, <span style=""color:blue;"">string</span> message) { Text += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"-Message received: {0}\n"</span>, message); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called when the web socket closed</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> OnClosed(<span style=""color:#2b91af;"">WebSocket</span> ws, <span style=""color:#2b91af;"">UInt16</span> code, <span style=""color:blue;"">string</span> message) { Text += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"-WebSocket closed! Code: {0} Message: {1}\n"</span>, code, message); webSocket = <span style=""color:blue;"">null</span>; } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called when an error occured on client side</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> OnError(<span style=""color:#2b91af;"">WebSocket</span> ws, <span style=""color:#2b91af;"">Exception</span> ex) { <span style=""color:blue;"">string</span> errorMsg = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">if</span> (ws.InternalRequest.Response != <span style=""color:blue;"">null</span>) errorMsg = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Status Code from Server: {0} and Message: {1}"</span>, ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message); Text += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"-An error occured: {0}\n"</span>, (ex != <span style=""color:blue;"">null</span> ? ex.Message : <span style=""color:#a31515;"">"Unknown Error "</span> + errorMsg)); webSocket = <span style=""color:blue;"">null</span>; } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region AssetBundleSample public static string AssetBundleSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> System.Collections; <span style=""color:blue;"">using</span> System.Collections.Generic; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP; <span style=""color:blue;"">public</span> <span style=""color:blue;"">sealed</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">AssetBundleSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The url of the resource to download</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">const</span> <span style=""color:blue;"">string</span> URL = <span style=""color:#a31515;"">"http://besthttp.azurewebsites.net/Content/AssetBundle.html"</span>; <span style=""color:blue;""> #region</span> Private Fields <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Debug status text</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">string</span> status = <span style=""color:#a31515;"">"Waiting for user interaction"</span>; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The downloaded and cached AssetBundle</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">AssetBundle</span> cachedBundle; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The loaded texture from the AssetBundle</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Texture2D</span> texture; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> A flag that indicates that we are processing the request/bundle to hide the "Start Download" button.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">bool</span> downloading; <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Status: "</span> + status); <span style=""color:green;"">// Draw the texture from the downloaded bundle</span> <span style=""color:blue;"">if</span> (texture != <span style=""color:blue;"">null</span>) <span style=""color:#2b91af;"">GUILayout</span>.Box(texture, <span style=""color:#2b91af;"">GUILayout</span>.MaxHeight(256)); <span style=""color:blue;"">if</span> (!downloading && <span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Start Download"</span>)) { UnloadBundle(); StartCoroutine(DownloadAssetBundle()); } }); } <span style=""color:blue;"">void</span> OnDestroy() { UnloadBundle(); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Private Helper Functions <span style=""color:#2b91af;"">IEnumerator</span> DownloadAssetBundle() { downloading = <span style=""color:blue;"">true</span>; <span style=""color:green;"">// Create and send our request</span> <span style=""color:blue;"">var</span> request = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">HTTPRequest</span>(<span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(URL)).Send(); status = <span style=""color:#a31515;"">"Download started"</span>; <span style=""color:green;"">// Wait while it's finishes and add some fancy dots to display something while the user waits for it.</span> <span style=""color:green;"">// A simple "yield return StartCoroutine(request);" would do the job too.</span> <span style=""color:blue;"">while</span>(request.State < <span style=""color:#2b91af;"">HTTPRequestStates</span>.Finished) { <span style=""color:blue;"">yield</span> <span style=""color:blue;"">return</span> <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">WaitForSeconds</span>(0.1f); status += <span style=""color:#a31515;"">"."</span>; } <span style=""color:green;"">// Check the outcome of our request.</span> <span style=""color:blue;"">switch</span> (request.State) { <span style=""color:green;"">// The request finished without any problem.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Finished: <span style=""color:blue;"">if</span> (request.Response.IsSuccess) { status = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"AssetBundle downloaded! Loaded from local cache: {0}"</span>, request.Response.IsFromCache.ToString()); <span style=""color:green;"">// Start creating the downloaded asset bundle</span> <span style=""color:#2b91af;"">AssetBundleCreateRequest</span> async = <span style=""color:#2b91af;"">AssetBundle</span>.CreateFromMemory(request.Response.Data); <span style=""color:green;"">// wait for it</span> <span style=""color:blue;"">yield</span> <span style=""color:blue;"">return</span> async; <span style=""color:green;"">// And process the bundle</span> <span style=""color:blue;"">yield</span> <span style=""color:blue;"">return</span> StartCoroutine(ProcessAssetBundle(async.assetBundle)); } <span style=""color:blue;"">else</span> { status = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}"</span>, request.Response.StatusCode, request.Response.Message, request.Response.DataAsText); <span style=""color:#2b91af;"">Debug</span>.LogWarning(status); } <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request finished with an unexpected error. The request's Exception property may contain more info about the error.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Error: status = <span style=""color:#a31515;"">"Request Finished with Error! "</span> + (request.Exception != <span style=""color:blue;"">null</span> ? (request.Exception.Message + <span style=""color:#a31515;"">"\n"</span> + request.Exception.StackTrace) : <span style=""color:#a31515;"">"No Exception"</span>); <span style=""color:#2b91af;"">Debug</span>.LogError(status); <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request aborted, initiated by the user.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Aborted: status = <span style=""color:#a31515;"">"Request Aborted!"</span>; <span style=""color:#2b91af;"">Debug</span>.LogWarning(status); <span style=""color:blue;"">break</span>; <span style=""color:green;"">// Ceonnecting to the server is timed out.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.ConnectionTimedOut: status = <span style=""color:#a31515;"">"Connection Timed Out!"</span>; <span style=""color:#2b91af;"">Debug</span>.LogError(status); <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request didn't finished in the given time.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.TimedOut: status = <span style=""color:#a31515;"">"Processing the request Timed Out!"</span>; <span style=""color:#2b91af;"">Debug</span>.LogError(status); <span style=""color:blue;"">break</span>; } downloading = <span style=""color:blue;"">false</span>; } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> In this function we can do whatever we want with the freshly downloaded bundle.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> In this example we will cache it for later use, and we will load a texture from it.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">IEnumerator</span> ProcessAssetBundle(<span style=""color:#2b91af;"">AssetBundle</span> bundle) { <span style=""color:blue;"">if</span> (bundle == <span style=""color:blue;"">null</span>) <span style=""color:blue;"">yield</span> <span style=""color:blue;"">break</span>; <span style=""color:green;"">// Save the bundle for future use</span> cachedBundle = bundle; <span style=""color:green;"">// Start loading the asset from the bundle</span> <span style=""color:blue;"">var</span> asyncAsset = cachedBundle.LoadAsync(<span style=""color:#a31515;"">"9443182_orig"</span>, <span style=""color:blue;"">typeof</span>(<span style=""color:#2b91af;"">Texture2D</span>)); <span style=""color:green;"">// wait til load</span> <span style=""color:blue;"">yield</span> <span style=""color:blue;"">return</span> asyncAsset; <span style=""color:green;"">// get the texture</span> texture = asyncAsset.asset <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">Texture2D</span>; } <span style=""color:blue;"">void</span> UnloadBundle() { <span style=""color:blue;"">if</span> (cachedBundle != <span style=""color:blue;"">null</span>) { cachedBundle.Unload(<span style=""color:blue;"">true</span>); cachedBundle = <span style=""color:blue;"">null</span>; } } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region LargeFileDownloadSample public static string LargeFileDownloadSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> System.Collections.Generic; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP; <span style=""color:blue;"">public</span> <span style=""color:blue;"">sealed</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">LargeFileDownloadSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The url of the resource to download</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">const</span> <span style=""color:blue;"">string</span> URL = <span style=""color:#a31515;"">"http://ipv4.download.thinkbroadband.com/100MB.zip"</span>; <span style=""color:blue;""> #region</span> Private Fields <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Cached request to be able to abort it</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">HTTPRequest</span> request; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Debug status of the request</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">string</span> status = <span style=""color:blue;"">string</span>.Empty; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Download(processing) progress. Its range is between [0..1]</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">float</span> progress; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The fragment size that we will set to the request</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">int</span> fragmentSize = <span style=""color:#2b91af;"">HTTPResponse</span>.MinBufferSize; <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> Awake() { <span style=""color:green;"">// If we have a non-finished download, set the progress to the value where we left it</span> <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">PlayerPrefs</span>.HasKey(<span style=""color:#a31515;"">"DownloadLength"</span>)) progress = <span style=""color:#2b91af;"">PlayerPrefs</span>.GetInt(<span style=""color:#a31515;"">"DownloadProgress"</span>) / (<span style=""color:blue;"">float</span>)<span style=""color:#2b91af;"">PlayerPrefs</span>.GetInt(<span style=""color:#a31515;"">"DownloadLength"</span>); } <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:green;"">// Stop the download if we are leaving this example</span> <span style=""color:blue;"">if</span> (request != <span style=""color:blue;"">null</span> && request.State < <span style=""color:#2b91af;"">HTTPRequestStates</span>.Finished) { request.OnProgress = <span style=""color:blue;"">null</span>; request.Callback = <span style=""color:blue;"">null</span>; request.Abort(); } } <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:green;"">// Draw the current status</span> <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Request status: "</span> + status); <span style=""color:#2b91af;"">GUILayout</span>.Space(5); <span style=""color:green;"">// Draw the current progress</span> <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Progress: {0:P2} of {1:N0}Mb"</span>, progress, <span style=""color:#2b91af;"">PlayerPrefs</span>.GetInt(<span style=""color:#a31515;"">"DownloadLength"</span>) / 1048576 <span style=""color:green;"">/*1 Mb*/</span>)); <span style=""color:#2b91af;"">GUILayout</span>.HorizontalSlider(progress, 0, 1); <span style=""color:#2b91af;"">GUILayout</span>.Space(50); <span style=""color:blue;"">if</span> (request == <span style=""color:blue;"">null</span>) { <span style=""color:green;"">// Draw a slider to be able to change the fragment size</span> <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Desired Fragment Size: {0:N} KBytes"</span>, fragmentSize / 1024f)); fragmentSize = (<span style=""color:blue;"">int</span>)<span style=""color:#2b91af;"">GUILayout</span>.HorizontalSlider(fragmentSize, <span style=""color:#2b91af;"">HTTPResponse</span>.MinBufferSize, 10 * 1024 * 1024); <span style=""color:#2b91af;"">GUILayout</span>.Space(5); <span style=""color:blue;"">string</span> buttonStr = <span style=""color:#2b91af;"">PlayerPrefs</span>.HasKey(<span style=""color:#a31515;"">"DownloadProgress"</span>) ? <span style=""color:#a31515;"">"Continue Download"</span> : <span style=""color:#a31515;"">"Start Download"</span>; <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(buttonStr)) StreamLargeFileTest(); } <span style=""color:blue;"">else</span> <span style=""color:blue;"">if</span> (request.State == <span style=""color:#2b91af;"">HTTPRequestStates</span>.Processing && <span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Abort Download"</span>)) { <span style=""color:green;"">// Simulate a connection lost</span> request.Abort(); } }); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Private Helper Functions <span style=""color:green;"">// Calling this function again when the "DownloadProgress" key in the PlayerPrefs present will </span> <span style=""color:green;"">// continue the download</span> <span style=""color:blue;"">void</span> StreamLargeFileTest() { request = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">HTTPRequest</span>(<span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(URL), (req, resp) => { <span style=""color:blue;"">switch</span> (req.State) { <span style=""color:green;"">// The request is currently processed. With UseStreaming == true, we can get the streamed fragments here</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Processing: <span style=""color:green;"">// SaveLocal the DownloadLength, so we can display the progress</span> <span style=""color:blue;"">if</span> (!<span style=""color:#2b91af;"">PlayerPrefs</span>.HasKey(<span style=""color:#a31515;"">"DownloadLength"</span>)) { <span style=""color:blue;"">string</span> value = resp.GetFirstHeaderValue(<span style=""color:#a31515;"">"content-length"</span>); <span style=""color:blue;"">if</span> (!<span style=""color:blue;"">string</span>.IsNullOrEmpty(value)) <span style=""color:#2b91af;"">PlayerPrefs</span>.SetInt(<span style=""color:#a31515;"">"DownloadLength"</span>, <span style=""color:blue;"">int</span>.Parse(value)); } <span style=""color:green;"">// Get the fragments, and save them</span> ProcessFragments(resp.GetStreamedFragments()); status = <span style=""color:#a31515;"">"Processing"</span>; <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request finished without any problem.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Finished: <span style=""color:blue;"">if</span> (resp.IsSuccess) { <span style=""color:green;"">// Save any remaining fragments</span> ProcessFragments(resp.GetStreamedFragments()); <span style=""color:green;"">// Completly finished</span> <span style=""color:blue;"">if</span> (resp.IsStreamingFinished) { status = <span style=""color:#a31515;"">"Streaming finished!"</span>; <span style=""color:green;"">// We are done, delete the progress key</span> <span style=""color:#2b91af;"">PlayerPrefs</span>.DeleteKey(<span style=""color:#a31515;"">"DownloadProgress"</span>); <span style=""color:#2b91af;"">PlayerPrefs</span>.Save(); request = <span style=""color:blue;"">null</span>; } <span style=""color:blue;"">else</span> status = <span style=""color:#a31515;"">"Processing"</span>; } <span style=""color:blue;"">else</span> { status = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}"</span>, resp.StatusCode, resp.Message, resp.DataAsText); <span style=""color:#2b91af;"">Debug</span>.LogWarning(status); request = <span style=""color:blue;"">null</span>; } <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request finished with an unexpected error. The request's Exception property may contain more info about the error.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Error: status = <span style=""color:#a31515;"">"Request Finished with Error! "</span> + (req.Exception != <span style=""color:blue;"">null</span> ? (req.Exception.Message + <span style=""color:#a31515;"">"\n"</span> + req.Exception.StackTrace) : <span style=""color:#a31515;"">"No Exception"</span>); <span style=""color:#2b91af;"">Debug</span>.LogError(status); request = <span style=""color:blue;"">null</span>; <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request aborted, initiated by the user.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.Aborted: status = <span style=""color:#a31515;"">"Request Aborted!"</span>; <span style=""color:#2b91af;"">Debug</span>.LogWarning(status); request = <span style=""color:blue;"">null</span>; <span style=""color:blue;"">break</span>; <span style=""color:green;"">// Ceonnecting to the server is timed out.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.ConnectionTimedOut: status = <span style=""color:#a31515;"">"Connection Timed Out!"</span>; <span style=""color:#2b91af;"">Debug</span>.LogError(status); request = <span style=""color:blue;"">null</span>; <span style=""color:blue;"">break</span>; <span style=""color:green;"">// The request didn't finished in the given time.</span> <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">HTTPRequestStates</span>.TimedOut: status = <span style=""color:#a31515;"">"Processing the request Timed Out!"</span>; <span style=""color:#2b91af;"">Debug</span>.LogError(status); request = <span style=""color:blue;"">null</span>; <span style=""color:blue;"">break</span>; } }); <span style=""color:green;"">// Are there any progress, that we can continue?</span> <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">PlayerPrefs</span>.HasKey(<span style=""color:#a31515;"">"DownloadProgress"</span>)) <span style=""color:green;"">// SaveLocal the range header</span> request.SetRangeHeader(<span style=""color:#2b91af;"">PlayerPrefs</span>.GetInt(<span style=""color:#a31515;"">"DownloadProgress"</span>)); <span style=""color:blue;"">else</span> <span style=""color:green;"">// This is a new request</span> <span style=""color:#2b91af;"">PlayerPrefs</span>.SetInt(<span style=""color:#a31515;"">"DownloadProgress"</span>, 0); <span style=""color:green;"">// If we are writing our own file set it true(disable), so don't duplicate it on the filesystem</span> request.DisableCache = <span style=""color:blue;"">true</span>; <span style=""color:green;"">// We want to access the downloaded bytes while we are still downloading</span> request.UseStreaming = <span style=""color:blue;"">true</span>; <span style=""color:green;"">// SaveLocal a reasonable high fragment size. Here it is 5 megabytes.</span> request.StreamFragmentSize = fragmentSize; <span style=""color:green;"">// Start Processing the request</span> request.Send(); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> In this function we can do whatever we want with the downloaded bytes. In this sample we will do nothing, just set the metadata to display progress.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> ProcessFragments(<span style=""color:#2b91af;"">List</span><<span style=""color:blue;"">byte</span>[]> fragments) { <span style=""color:blue;"">if</span> (fragments != <span style=""color:blue;"">null</span> && fragments.Count > 0) { <span style=""color:green;"">/*string dir = "TODO!";</span> <span style=""color:green;""> string filename = "TODO!";</span> <span style=""color:green;""> using (System.IO.FileStream fs = new System.IO.FileStream(System.IO.Path.Combine(dir, filename), System.IO.FileMode.Append))</span> <span style=""color:green;""> for (int i = 0; i < fragments.Count; ++i)</span> <span style=""color:green;""> fs.Write(fragments[i], 0, fragments[i].Length);*/</span> <span style=""color:blue;"">for</span> (<span style=""color:blue;"">int</span> i = 0; i < fragments.Count; ++i) { <span style=""color:green;"">// Save how many bytes we wrote successfully</span> <span style=""color:blue;"">int</span> downloaded = <span style=""color:#2b91af;"">PlayerPrefs</span>.GetInt(<span style=""color:#a31515;"">"DownloadProgress"</span>) + fragments[i].Length; <span style=""color:#2b91af;"">PlayerPrefs</span>.SetInt(<span style=""color:#a31515;"">"DownloadProgress"</span>, downloaded); } <span style=""color:#2b91af;"">PlayerPrefs</span>.Save(); <span style=""color:green;"">// SaveLocal the progress to the actually processed bytes</span> progress = <span style=""color:#2b91af;"">PlayerPrefs</span>.GetInt(<span style=""color:#a31515;"">"DownloadProgress"</span>) / (<span style=""color:blue;"">float</span>)<span style=""color:#2b91af;"">PlayerPrefs</span>.GetInt(<span style=""color:#a31515;"">"DownloadLength"</span>); } } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region SocketIOChatSample public static string SocketIOChatSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> System.Collections.Generic; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP; <span style=""color:blue;"">using</span> BestHTTP.SocketIO; <span style=""color:blue;"">using</span> BestHTTP.JSON; <span style=""color:blue;"">using</span> BestHTTP.SocketIO.Events; <span style=""color:blue;"">public</span> <span style=""color:blue;"">sealed</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">SocketIOChatSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:blue;"">private</span> <span style=""color:blue;"">readonly</span> <span style=""color:#2b91af;"">TimeSpan</span> TYPING_TIMER_LENGTH = <span style=""color:#2b91af;"">TimeSpan</span>.FromMilliseconds(700); <span style=""color:blue;"">private</span> <span style=""color:blue;"">enum</span> <span style=""color:#2b91af;"">ChatStates</span> { Login, Chat } <span style=""color:blue;""> #region</span> Fields <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The Socket.IO manager instance.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">SocketManager</span> Manager; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Current state of the chat demo.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">ChatStates</span> State; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The selected nickname</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">string</span> userName = <span style=""color:blue;"">string</span>.Empty; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Currently typing message</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">string</span> message = <span style=""color:blue;"">string</span>.Empty; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Sent and received messages.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">string</span> chatLog = <span style=""color:blue;"">string</span>.Empty; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Position of the scroller</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">Vector2</span> scrollPos; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> True if the user is currently typing</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">bool</span> typing; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> When the message changed.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">DateTime</span> lastTypingTime = <span style=""color:#2b91af;"">DateTime</span>.MinValue; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Users that typing.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">List</span><<span style=""color:blue;"">string</span>> typingUsers = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">List</span><<span style=""color:blue;"">string</span>>(); <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> Start() { <span style=""color:green;"">// The current state is Login</span> State = <span style=""color:#2b91af;"">ChatStates</span>.Login; <span style=""color:green;"">// Change an option to show how it should be done</span> <span style=""color:#2b91af;"">SocketOptions</span> options = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">SocketOptions</span>(); options.AutoConnect = <span style=""color:blue;"">false</span>; <span style=""color:green;"">// Create the Socket.IO manager</span> Manager = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">SocketManager</span>(<span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(<span style=""color:#a31515;"">"http://chat.socket.io/socket.io/"</span>), options); <span style=""color:green;"">// SaveLocal up custom chat events</span> Manager.Socket.On(<span style=""color:#a31515;"">"login"</span>, OnLogin); Manager.Socket.On(<span style=""color:#a31515;"">"new message"</span>, OnNewMessage); Manager.Socket.On(<span style=""color:#a31515;"">"user joined"</span>, OnUserJoined); Manager.Socket.On(<span style=""color:#a31515;"">"user left"</span>, OnUserLeft); Manager.Socket.On(<span style=""color:#a31515;"">"typing"</span>, OnTyping); Manager.Socket.On(<span style=""color:#a31515;"">"stop typing"</span>, OnStopTyping); <span style=""color:green;"">// The argument will be an Error object.</span> Manager.Socket.On(<span style=""color:#2b91af;"">SocketIOEventTypes</span>.Error, (socket, packet, args) => <span style=""color:#2b91af;"">Debug</span>.LogError(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Error: {0}"</span>, args[0].ToString()))); <span style=""color:green;"">// We set SocketOptions' AutoConnect to false, so we have to call it manually.</span> Manager.Open(); } <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:green;"">// Leaving this sample, close the socket</span> Manager.Close(); } <span style=""color:blue;"">void</span> Update() { <span style=""color:green;"">// Go back to the demo selector</span> <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">Input</span>.GetKeyDown(<span style=""color:#2b91af;"">KeyCode</span>.Escape)) <span style=""color:#2b91af;"">SampleSelector</span>.SelectedSample.DestroyUnityObject(); <span style=""color:green;"">// Stop typing if some time passed without typing</span> <span style=""color:blue;"">if</span> (typing) { <span style=""color:blue;"">var</span> typingTimer = <span style=""color:#2b91af;"">DateTime</span>.UtcNow; <span style=""color:blue;"">var</span> timeDiff = typingTimer - lastTypingTime; <span style=""color:blue;"">if</span> (timeDiff >= TYPING_TIMER_LENGTH) { Manager.Socket.Emit(<span style=""color:#a31515;"">"stop typing"</span>); typing = <span style=""color:blue;"">false</span>; } } } <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:blue;"">switch</span>(State) { <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">ChatStates</span>.Login: DrawLoginScreen(); <span style=""color:blue;"">break</span>; <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">ChatStates</span>.Chat: DrawChatScreen(); <span style=""color:blue;"">break</span>; } } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Chat Logic <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called from an OnGUI event to draw the Login Screen.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> DrawLoginScreen() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); <span style=""color:#2b91af;"">GUILayout</span>.FlexibleSpace(); <span style=""color:#2b91af;"">GUIHelper</span>.DrawCenteredText(<span style=""color:#a31515;"">"What's your nickname?"</span>); userName = <span style=""color:#2b91af;"">GUILayout</span>.TextField(userName); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Join"</span>)) SetUserName(); <span style=""color:#2b91af;"">GUILayout</span>.FlexibleSpace(); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); }); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called from an OnGUI event to draw the Chat Screen.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> DrawChatScreen() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); scrollPos = <span style=""color:#2b91af;"">GUILayout</span>.BeginScrollView(scrollPos); <span style=""color:#2b91af;"">GUILayout</span>.Label(chatLog, <span style=""color:#2b91af;"">GUILayout</span>.ExpandWidth(<span style=""color:blue;"">true</span>), <span style=""color:#2b91af;"">GUILayout</span>.ExpandHeight(<span style=""color:blue;"">true</span>)); <span style=""color:#2b91af;"">GUILayout</span>.EndScrollView(); <span style=""color:blue;"">string</span> typing = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">if</span> (typingUsers.Count > 0) { typing += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0}"</span>, typingUsers[0]); <span style=""color:blue;"">for</span> (<span style=""color:blue;"">int</span> i = 1; i < typingUsers.Count; ++i) typing += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">", {0}"</span>, typingUsers[i]); <span style=""color:blue;"">if</span> (typingUsers.Count == 1) typing += <span style=""color:#a31515;"">" is typing!"</span>; <span style=""color:blue;"">else</span> typing += <span style=""color:#a31515;"">" are typing!"</span>; } <span style=""color:#2b91af;"">GUILayout</span>.Label(typing); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Type here:"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); message = <span style=""color:#2b91af;"">GUILayout</span>.TextField(message); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Send"</span>, <span style=""color:#2b91af;"">GUILayout</span>.MaxWidth(100))) SendMessage(); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUI</span>.changed) UpdateTyping(); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); }); } <span style=""color:blue;"">void</span> SetUserName() { <span style=""color:blue;"">if</span> (<span style=""color:blue;"">string</span>.IsNullOrEmpty(userName)) <span style=""color:blue;"">return</span>; State = <span style=""color:#2b91af;"">ChatStates</span>.Chat; Manager.Socket.Emit(<span style=""color:#a31515;"">"add user"</span>, userName); } <span style=""color:blue;"">void</span> SendMessage() { <span style=""color:blue;"">if</span> (<span style=""color:blue;"">string</span>.IsNullOrEmpty(message)) <span style=""color:blue;"">return</span>; Manager.Socket.Emit(<span style=""color:#a31515;"">"new message"</span>, message); chatLog += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0}: {1}\n"</span>, userName, message); message = <span style=""color:blue;"">string</span>.Empty; } <span style=""color:blue;"">void</span> UpdateTyping() { <span style=""color:blue;"">if</span> (!typing) { typing = <span style=""color:blue;"">true</span>; Manager.Socket.Emit(<span style=""color:#a31515;"">"typing"</span>); } lastTypingTime = <span style=""color:#2b91af;"">DateTime</span>.UtcNow; } <span style=""color:blue;"">void</span> addParticipantsMessage(<span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>> data) { <span style=""color:blue;"">int</span> numUsers = <span style=""color:#2b91af;"">Convert</span>.ToInt32(data[<span style=""color:#a31515;"">"numUsers"</span>]); <span style=""color:blue;"">if</span> (numUsers == 1) chatLog += <span style=""color:#a31515;"">"there's 1 participant\n"</span>; <span style=""color:blue;"">else</span> chatLog += <span style=""color:#a31515;"">"there are "</span> + numUsers + <span style=""color:#a31515;"">" participants\n"</span>; } <span style=""color:blue;"">void</span> addChatMessage(<span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>> data) { <span style=""color:blue;"">var</span> username = data[<span style=""color:#a31515;"">"username"</span>] <span style=""color:blue;"">as</span> <span style=""color:blue;"">string</span>; <span style=""color:blue;"">var</span> msg = data[<span style=""color:#a31515;"">"message"</span>] <span style=""color:blue;"">as</span> <span style=""color:blue;"">string</span>; chatLog += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0}: {1}\n"</span>, username, msg); } <span style=""color:blue;"">void</span> AddChatTyping(<span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>> data) { <span style=""color:blue;"">var</span> username = data[<span style=""color:#a31515;"">"username"</span>] <span style=""color:blue;"">as</span> <span style=""color:blue;"">string</span>; typingUsers.Add(username); } <span style=""color:blue;"">void</span> RemoveChatTyping(<span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>> data) { <span style=""color:blue;"">var</span> username = data[<span style=""color:#a31515;"">"username"</span>] <span style=""color:blue;"">as</span> <span style=""color:blue;"">string</span>; <span style=""color:blue;"">int</span> idx = typingUsers.FindIndex((name) => name.Equals(username)); <span style=""color:blue;"">if</span> (idx != -1) typingUsers.RemoveAt(idx); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Custom SocketIO Events <span style=""color:blue;"">void</span> OnLogin(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { chatLog = <span style=""color:#a31515;"">"Welcome to Socket.IO Chat — \n"</span>; addParticipantsMessage(args[0] <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>>); } <span style=""color:blue;"">void</span> OnNewMessage(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { addChatMessage(args[0] <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>>); } <span style=""color:blue;"">void</span> OnUserJoined(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { <span style=""color:blue;"">var</span> data = args[0] <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>>; <span style=""color:blue;"">var</span> username = data[<span style=""color:#a31515;"">"username"</span>] <span style=""color:blue;"">as</span> <span style=""color:blue;"">string</span>; chatLog += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} joined\n"</span>, username); addParticipantsMessage(data); } <span style=""color:blue;"">void</span> OnUserLeft(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { <span style=""color:blue;"">var</span> data = args[0] <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>>; <span style=""color:blue;"">var</span> username = data[<span style=""color:#a31515;"">"username"</span>] <span style=""color:blue;"">as</span> <span style=""color:blue;"">string</span>; chatLog += <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} left\n"</span>, username); addParticipantsMessage(data); } <span style=""color:blue;"">void</span> OnTyping(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { AddChatTyping(args[0] <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>>); } <span style=""color:blue;"">void</span> OnStopTyping(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { RemoveChatTyping(args[0] <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>>); } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region SocketIOWePlaySample public static string SocketIOWePlaySample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> System.Collections.Generic; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP.SocketIO; <span style=""color:blue;"">using</span> BestHTTP.SocketIO.Events; <span style=""color:blue;"">public</span> <span style=""color:blue;"">sealed</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">SocketIOWePlaySample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Possible states of the game.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">enum</span> <span style=""color:#2b91af;"">States</span> { Connecting, WaitForNick, Joined } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Controls that the server understands as a parameter in the move event.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">string</span>[] controls = <span style=""color:blue;"">new</span> <span style=""color:blue;"">string</span>[] { <span style=""color:#a31515;"">"left"</span>, <span style=""color:#a31515;"">"right"</span>, <span style=""color:#a31515;"">"a"</span>, <span style=""color:#a31515;"">"b"</span>, <span style=""color:#a31515;"">"up"</span>, <span style=""color:#a31515;"">"down"</span>, <span style=""color:#a31515;"">"select"</span>, <span style=""color:#a31515;"">"start"</span> }; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Ratio of the drawn GUI texture from the screen</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">const</span> <span style=""color:blue;"">float</span> ratio = 1.5f; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> How many messages to keep.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">int</span> MaxMessages = 50; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Current state of the game.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">States</span> State; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The root("/") Socket instance.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">Socket</span> Socket; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The user-selected nickname.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">string</span> Nick = <span style=""color:blue;"">string</span>.Empty; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The message that the user want to send to the chat.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">string</span> messageToSend = <span style=""color:blue;"">string</span>.Empty; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> How many user connected to the server.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">int</span> connections; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Local and server sent messages.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">List</span><<span style=""color:blue;"">string</span>> messages = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">List</span><<span style=""color:blue;"">string</span>>(); <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The chat scroll position.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">Vector2</span> scrollPos; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The decoded texture from the server sent binary data</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">Texture2D</span> FrameTexture; <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> Start() { <span style=""color:green;"">// Change an option to show how it should be done</span> <span style=""color:#2b91af;"">SocketOptions</span> options = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">SocketOptions</span>(); options.AutoConnect = <span style=""color:blue;"">false</span>; <span style=""color:green;"">// Create the SocketManager instance</span> <span style=""color:blue;"">var</span> manager = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">SocketManager</span>(<span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(<span style=""color:#a31515;"">"http://io.weplay.io/socket.io/"</span>), options); <span style=""color:green;"">// Keep a reference to the root namespace</span> Socket = manager.Socket; <span style=""color:green;"">// SaveLocal up our event handlers.</span> Socket.On(<span style=""color:#2b91af;"">SocketIOEventTypes</span>.Connect, OnConnected); Socket.On(<span style=""color:#a31515;"">"joined"</span>, OnJoined); Socket.On(<span style=""color:#a31515;"">"connections"</span>, OnConnections); Socket.On(<span style=""color:#a31515;"">"join"</span>, OnJoin); Socket.On(<span style=""color:#a31515;"">"move"</span>, OnMove); Socket.On(<span style=""color:#a31515;"">"message"</span>, OnMessage); Socket.On(<span style=""color:#a31515;"">"reload"</span>, OnReload); <span style=""color:green;"">// Don't waste cpu cycles on decoding the payload, we are expecting only binary data with this event,</span> <span style=""color:green;"">// and we can access it through the packet's Attachments property.</span> Socket.On(<span style=""color:#a31515;"">"frame"</span>, OnFrame, <span style=""color:green;"">/*autoDecodePayload:*/</span> <span style=""color:blue;"">false</span>); <span style=""color:green;"">// Add error handler, so we can display it</span> Socket.On(<span style=""color:#2b91af;"">SocketIOEventTypes</span>.Error, OnError); <span style=""color:green;"">// We set SocketOptions' AutoConnect to false, so we have to call it manually.</span> manager.Open(); <span style=""color:green;"">// We are connecting to the server.</span> State = <span style=""color:#2b91af;"">States</span>.Connecting; } <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:green;"">// Leaving this sample, close the socket</span> Socket.Manager.Close(); } <span style=""color:blue;"">void</span> Update() { <span style=""color:green;"">// Go back to the demo selector</span> <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">Input</span>.GetKeyDown(<span style=""color:#2b91af;"">KeyCode</span>.Escape)) <span style=""color:#2b91af;"">SampleSelector</span>.SelectedSample.DestroyUnityObject(); } <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:blue;"">switch</span>(State) { <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">States</span>.Connecting: <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); <span style=""color:#2b91af;"">GUILayout</span>.FlexibleSpace(); <span style=""color:#2b91af;"">GUIHelper</span>.DrawCenteredText(<span style=""color:#a31515;"">"Connecting to the server..."</span>); <span style=""color:#2b91af;"">GUILayout</span>.FlexibleSpace(); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); }); <span style=""color:blue;"">break</span>; <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">States</span>.WaitForNick: <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { DrawLoginScreen(); }); <span style=""color:blue;"">break</span>; <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">States</span>.Joined: <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:green;"">// Draw Texture</span> <span style=""color:blue;"">if</span> (FrameTexture != <span style=""color:blue;"">null</span>) <span style=""color:#2b91af;"">GUILayout</span>.Box(FrameTexture); DrawControls(); DrawChat(); }); <span style=""color:blue;"">break</span>; } } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Helper Functions <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called from an OnGUI event to draw the Login Screen.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> DrawLoginScreen() { <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); <span style=""color:#2b91af;"">GUILayout</span>.FlexibleSpace(); <span style=""color:#2b91af;"">GUIHelper</span>.DrawCenteredText(<span style=""color:#a31515;"">"What's your nickname?"</span>); Nick = <span style=""color:#2b91af;"">GUILayout</span>.TextField(Nick); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Join"</span>)) Join(); <span style=""color:#2b91af;"">GUILayout</span>.FlexibleSpace(); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); } <span style=""color:blue;"">void</span> DrawControls() { <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Controls:"</span>); <span style=""color:blue;"">for</span> (<span style=""color:blue;"">int</span> i = 0; i < controls.Length; ++i) <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(controls[i])) Socket.Emit(<span style=""color:#a31515;"">"move"</span>, controls[i]); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">" Connections: "</span> + connections); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); } <span style=""color:blue;"">void</span> DrawChat(<span style=""color:blue;"">bool</span> withInput = <span style=""color:blue;"">true</span>) { <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); <span style=""color:green;"">// Draw the messages</span> scrollPos = <span style=""color:#2b91af;"">GUILayout</span>.BeginScrollView(scrollPos, <span style=""color:blue;"">false</span>, <span style=""color:blue;"">false</span>); <span style=""color:blue;"">for</span> (<span style=""color:blue;"">int</span> i = 0; i < messages.Count; ++i) <span style=""color:#2b91af;"">GUILayout</span>.Label(messages[i], <span style=""color:#2b91af;"">GUILayout</span>.MinWidth(<span style=""color:#2b91af;"">Screen</span>.width)); <span style=""color:#2b91af;"">GUILayout</span>.EndScrollView(); <span style=""color:blue;"">if</span> (withInput) { <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Your message: "</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); messageToSend = <span style=""color:#2b91af;"">GUILayout</span>.TextField(messageToSend); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Send"</span>, <span style=""color:#2b91af;"">GUILayout</span>.MaxWidth(100))) SendMessage(); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); } <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Add a message to the message log</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><param name=</span><span style=""color:gray;"">"msg"</span><span style=""color:gray;"">></param></span> <span style=""color:blue;"">void</span> AddMessage(<span style=""color:blue;"">string</span> msg) { messages.Insert(0, msg); <span style=""color:blue;"">if</span> (messages.Count > MaxMessages) messages.RemoveRange(MaxMessages, messages.Count - MaxMessages); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Send a chat message. The message must be in the messageToSend field.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> SendMessage() { <span style=""color:blue;"">if</span> (<span style=""color:blue;"">string</span>.IsNullOrEmpty(messageToSend)) <span style=""color:blue;"">return</span>; Socket.Emit(<span style=""color:#a31515;"">"message"</span>, messageToSend); AddMessage(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0}: {1}"</span>, Nick, messageToSend)); messageToSend = <span style=""color:blue;"">string</span>.Empty; } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Join to the game with the nickname stored in the Nick field.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> Join() { <span style=""color:#2b91af;"">PlayerPrefs</span>.SetString(<span style=""color:#a31515;"">"Nick"</span>, Nick); Socket.Emit(<span style=""color:#a31515;"">"join"</span>, Nick); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Reload the game.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> Reload() { FrameTexture = <span style=""color:blue;"">null</span>; <span style=""color:blue;"">if</span> (Socket != <span style=""color:blue;"">null</span>) { Socket.Manager.Close(); Socket = <span style=""color:blue;"">null</span>; Start(); } } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> SocketIO Events <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Socket connected event.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnConnected(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">PlayerPrefs</span>.HasKey(<span style=""color:#a31515;"">"Nick"</span>)) { Nick = <span style=""color:#2b91af;"">PlayerPrefs</span>.GetString(<span style=""color:#a31515;"">"Nick"</span>, <span style=""color:#a31515;"">"NickName"</span>); Join(); } <span style=""color:blue;"">else</span> State = <span style=""color:#2b91af;"">States</span>.WaitForNick; AddMessage(<span style=""color:#a31515;"">"connected"</span>); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Local player joined after sending a 'join' event</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnJoined(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { State = <span style=""color:#2b91af;"">States</span>.Joined; } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Server sent us a 'reload' event.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnReload(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { Reload(); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Someone wrote a message to the chat.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnMessage(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { <span style=""color:blue;"">if</span> (args.Length == 1) AddMessage(args[0] <span style=""color:blue;"">as</span> <span style=""color:blue;"">string</span>); <span style=""color:blue;"">else</span> AddMessage(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0}: {1}"</span>, args[1], args[0])); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Someone (including us) pressed a button.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnMove(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { AddMessage(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} pressed {1}"</span>, args[1], args[0])); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Someone joined to the game</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnJoin(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { <span style=""color:blue;"">string</span> loc = args.Length > 1 ? <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"({0})"</span>, args[1]) : <span style=""color:blue;"">string</span>.Empty; AddMessage(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} joined {1}"</span>, args[0], loc)); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> How many players are connected to the game.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnConnections(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { connections = <span style=""color:#2b91af;"">Convert</span>.ToInt32(args[0]); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The server sent us a new picture to draw the game.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnFrame(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { <span style=""color:blue;"">if</span> (State != <span style=""color:#2b91af;"">States</span>.Joined) <span style=""color:blue;"">return</span>; <span style=""color:blue;"">if</span> (FrameTexture == <span style=""color:blue;"">null</span>) { FrameTexture = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Texture2D</span>(0, 0, <span style=""color:#2b91af;"">TextureFormat</span>.RGBA32, <span style=""color:blue;"">false</span>); FrameTexture.filterMode = <span style=""color:#2b91af;"">FilterMode</span>.Point; } <span style=""color:green;"">// Binary data usage case 1 - using directly the Attachments property:</span> <span style=""color:blue;"">byte</span>[] data = packet.Attachments[0]; <span style=""color:green;"">// Binary data usage case 2 - using the packet's ReconstructAttachmentAsIndex() function</span> <span style=""color:green;"">/*packet.ReconstructAttachmentAsIndex();</span> <span style=""color:green;""> args = packet.Decode(socket.Manager.Encoder);</span> <span style=""color:green;""> data = packet.Attachments[Convert.ToInt32(args[0])];*/</span> <span style=""color:green;"">// Binary data usage case 3 - using the packet's ReconstructAttachmentAsBase64() function</span> <span style=""color:green;"">/*packet.ReconstructAttachmentAsBase64();</span> <span style=""color:green;""> args = packet.Decode(socket.Manager.Encoder);</span> <span style=""color:green;""> data = Convert.FromBase64String(args[0] as string);*/</span> <span style=""color:green;"">// Load the server sent picture</span> FrameTexture.LoadImage(data); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called on local or remote error.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnError(<span style=""color:#2b91af;"">Socket</span> socket, <span style=""color:#2b91af;"">Packet</span> packet, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { AddMessage(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"--ERROR - {0}"</span>, args[0].ToString())); } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region SignalR SimpleStreamingSample public static string SignalR_SimpleStreamingSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP.SignalR; <span style=""color:blue;"">sealed</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">SimpleStreamingSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:blue;"">readonly</span> <span style=""color:#2b91af;"">Uri</span> URI = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(<span style=""color:#a31515;"">"http://besthttpsignalr.azurewebsites.net/streaming-connection"</span>); <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Reference to the SignalR Connection</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Connection</span> signalRConnection; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Helper GUI class to handle and display a string-list</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">GUIMessageList</span> messages = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">GUIMessageList</span>(); <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> Start() { <span style=""color:green;"">// Create the SignalR connection</span> signalRConnection = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Connection</span>(URI); <span style=""color:green;"">// set event handlers</span> signalRConnection.OnNonHubMessage += signalRConnection_OnNonHubMessage; signalRConnection.OnStateChanged += signalRConnection_OnStateChanged; signalRConnection.OnError += signalRConnection_OnError; <span style=""color:green;"">// Start connecting to the server</span> signalRConnection.Open(); } <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:green;"">// Close the connection when the sample is closed</span> signalRConnection.Close(); } <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Messages"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); messages.Draw(<span style=""color:#2b91af;"">Screen</span>.width - 20, 0); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); }); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> SignalR Events <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Handle Server-sent messages</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> signalRConnection_OnNonHubMessage(<span style=""color:#2b91af;"">Connection</span> connection, <span style=""color:blue;"">object</span> data) { messages.Add(<span style=""color:#a31515;"">"[Server Message] "</span> + data.ToString()); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Display state changes</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> signalRConnection_OnStateChanged(<span style=""color:#2b91af;"">Connection</span> connection, <span style=""color:#2b91af;"">ConnectionStates</span> oldState, <span style=""color:#2b91af;"">ConnectionStates</span> newState) { messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"[State Change] {0} => {1}"</span>, oldState, newState)); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Display errors.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> signalRConnection_OnError(<span style=""color:#2b91af;"">Connection</span> connection, <span style=""color:blue;"">string</span> error) { messages.Add(<span style=""color:#a31515;"">"[Error] "</span> + error); } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region SignalR ConnectionAPISample public static string SignalR_ConnectionAPISample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> System.Collections.Generic; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP.SignalR; <span style=""color:blue;"">using</span> BestHTTP.Cookies; <span style=""color:blue;"">public</span> <span style=""color:blue;"">sealed</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">ConnectionAPISample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:blue;"">readonly</span> <span style=""color:#2b91af;"">Uri</span> URI = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(<span style=""color:#a31515;"">"http://besthttpsignalr.azurewebsites.net/raw-connection/"</span>); <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Possible message types that the client can send to the server</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">enum</span> <span style=""color:#2b91af;"">MessageTypes</span> { Send, <span style=""color:green;"">// 0</span> Broadcast, <span style=""color:green;"">// 1</span> Join, <span style=""color:green;"">// 2</span> PrivateMessage, <span style=""color:green;"">// 3</span> AddToGroup, <span style=""color:green;"">// 4</span> RemoveFromGroup, <span style=""color:green;"">// 5</span> SendToGroup, <span style=""color:green;"">// 6</span> BroadcastExceptMe, <span style=""color:green;"">// 7</span> } <span style=""color:blue;""> #region</span> Private Fields <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Reference to the SignalR Connection</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Connection</span> signalRConnection; <span style=""color:green;"">// Input strings</span> <span style=""color:blue;"">string</span> ToEveryBodyText = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> ToMeText = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> PrivateMessageText = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> PrivateMessageUserOrGroupName = <span style=""color:blue;"">string</span>.Empty; <span style=""color:#2b91af;"">GUIMessageList</span> messages = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">GUIMessageList</span>(); <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> Start() { <span style=""color:green;"">// SaveLocal a "user" cookie if we previously used the 'Enter Name' button.</span> <span style=""color:green;"">// The server will set this username to the new connection.</span> <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">PlayerPrefs</span>.HasKey(<span style=""color:#a31515;"">"userName"</span>)) <span style=""color:#2b91af;"">CookieJar</span>.SaveLocal(URI, <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Cookie</span>(<span style=""color:#a31515;"">"user"</span>, <span style=""color:#2b91af;"">PlayerPrefs</span>.GetString(<span style=""color:#a31515;"">"userName"</span>))); signalRConnection = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Connection</span>(URI); <span style=""color:green;"">// to serialize the Message class, set a more advanced json encoder</span> signalRConnection.JsonEncoder = <span style=""color:blue;"">new</span> BestHTTP.SignalR.JsonEncoders.<span style=""color:#2b91af;"">LitJsonEncoder</span>(); <span style=""color:green;"">// set up event handlers</span> signalRConnection.OnStateChanged += signalRConnection_OnStateChanged; signalRConnection.OnNonHubMessage += signalRConnection_OnGeneralMessage; <span style=""color:green;"">// Start to connect to the server.</span> signalRConnection.Open(); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Draw the gui.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> Get input strings.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> Handle function calls.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); <span style=""color:blue;""> #region</span> To Everybody <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"To Everybody"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); ToEveryBodyText = <span style=""color:#2b91af;"">GUILayout</span>.TextField(ToEveryBodyText, <span style=""color:#2b91af;"">GUILayout</span>.MinWidth(100)); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Broadcast"</span>)) Broadcast(ToEveryBodyText); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Broadcast (All Except Me)"</span>)) BroadcastExceptMe(ToEveryBodyText); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Enter Name"</span>)) EnterName(ToEveryBodyText); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Join Group"</span>)) JoinGroup(ToEveryBodyText); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Leave Group"</span>)) LeaveGroup(ToEveryBodyText); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> To Me <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"To Me"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); ToMeText = <span style=""color:#2b91af;"">GUILayout</span>.TextField(ToMeText, <span style=""color:#2b91af;"">GUILayout</span>.MinWidth(100)); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Send to me"</span>)) SendToMe(ToMeText); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Private Message <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Private Message"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Message:"</span>); PrivateMessageText = <span style=""color:#2b91af;"">GUILayout</span>.TextField(PrivateMessageText, <span style=""color:#2b91af;"">GUILayout</span>.MinWidth(100)); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"User or Group name:"</span>); PrivateMessageUserOrGroupName = <span style=""color:#2b91af;"">GUILayout</span>.TextField(PrivateMessageUserOrGroupName, <span style=""color:#2b91af;"">GUILayout</span>.MinWidth(100)); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Send to user"</span>)) SendToUser(PrivateMessageUserOrGroupName, PrivateMessageText); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Send to group"</span>)) SendToGroup(PrivateMessageUserOrGroupName, PrivateMessageText); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:blue;""> #endregion</span> <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:blue;"">if</span> (signalRConnection.State == <span style=""color:#2b91af;"">ConnectionStates</span>.Closed) { <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Start Connection"</span>)) signalRConnection.Open(); } <span style=""color:blue;"">else</span> <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Stop Connection"</span>)) signalRConnection.Close(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:green;"">// Draw the messages</span> <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Messages"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); messages.Draw(<span style=""color:#2b91af;"">Screen</span>.width - 20, 0); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); }); } <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:green;"">// Close the connection when the sample is closed</span> signalRConnection.Close(); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> SignalR Events <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Handle non-hub messages</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> signalRConnection_OnGeneralMessage(<span style=""color:#2b91af;"">Connection</span> manager, <span style=""color:blue;"">object</span> data) { <span style=""color:green;"">// For now, just create a Json string from the sent data again</span> <span style=""color:blue;"">string</span> reencoded = BestHTTP.JSON.<span style=""color:#2b91af;"">Json</span>.Encode(data); <span style=""color:green;"">// and display it</span> messages.Add(<span style=""color:#a31515;"">"[Server Message] "</span> + reencoded); } <span style=""color:blue;"">void</span> signalRConnection_OnStateChanged(<span style=""color:#2b91af;"">Connection</span> manager, <span style=""color:#2b91af;"">ConnectionStates</span> oldState, <span style=""color:#2b91af;"">ConnectionStates</span> newState) { <span style=""color:green;"">// display state changes</span> messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"[State Change] {0} => {1}"</span>, oldState.ToString(), newState.ToString())); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> To EveryBody Functions <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Broadcast a message to all connected clients</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> Broadcast(<span style=""color:blue;"">string</span> text) { signalRConnection.Send(<span style=""color:blue;"">new</span> { Type = <span style=""color:#2b91af;"">MessageTypes</span>.Broadcast, Value = text }); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Broadcast a message to all connected clients, except this client</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> BroadcastExceptMe(<span style=""color:blue;"">string</span> text) { signalRConnection.Send(<span style=""color:blue;"">new</span> { Type = <span style=""color:#2b91af;"">MessageTypes</span>.BroadcastExceptMe, Value = text }); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> SaveLocal a name for this connection.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> EnterName(<span style=""color:blue;"">string</span> name) { signalRConnection.Send(<span style=""color:blue;"">new</span> { Type = <span style=""color:#2b91af;"">MessageTypes</span>.Join, Value = name }); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Join to a group</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> JoinGroup(<span style=""color:blue;"">string</span> groupName) { signalRConnection.Send(<span style=""color:blue;"">new</span> { Type = <span style=""color:#2b91af;"">MessageTypes</span>.AddToGroup, Value = groupName }); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Leave a group</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> LeaveGroup(<span style=""color:blue;"">string</span> groupName) { signalRConnection.Send(<span style=""color:blue;"">new</span> { Type = <span style=""color:#2b91af;"">MessageTypes</span>.RemoveFromGroup, Value = groupName }); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> To Me Functions <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Send a message to the very same client through the server</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> SendToMe(<span style=""color:blue;"">string</span> text) { signalRConnection.Send(<span style=""color:blue;"">new</span> { Type = <span style=""color:#2b91af;"">MessageTypes</span>.Send, Value = text }); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Private Message Functions <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Send a private message to a user</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> SendToUser(<span style=""color:blue;"">string</span> userOrGroupName, <span style=""color:blue;"">string</span> text) { signalRConnection.Send(<span style=""color:blue;"">new</span> { Type = <span style=""color:#2b91af;"">MessageTypes</span>.PrivateMessage, Value = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0}|{1}"</span>, userOrGroupName, text) }); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Send a message to a group</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> SendToGroup(<span style=""color:blue;"">string</span> userOrGroupName, <span style=""color:blue;"">string</span> text) { signalRConnection.Send(<span style=""color:blue;"">new</span> { Type = <span style=""color:#2b91af;"">MessageTypes</span>.SendToGroup, Value = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0}|{1}"</span>, userOrGroupName, text) }); } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region SignalR ConnectionStatusSample public static string SignalR_ConnectionStatusSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> System.Collections.Generic; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP.SignalR; <span style=""color:blue;"">using</span> BestHTTP.SignalR.Hubs; <span style=""color:blue;"">sealed</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">ConnectionStatusSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:blue;"">readonly</span> <span style=""color:#2b91af;"">Uri</span> URI = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(<span style=""color:#a31515;"">"http://besthttpsignalr.azurewebsites.net/signalr"</span>); <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Reference to the SignalR Connection</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Connection</span> signalRConnection; <span style=""color:#2b91af;"">GUIMessageList</span> messages = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">GUIMessageList</span>(); <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> Start() { <span style=""color:green;"">// Connect to the StatusHub hub</span> signalRConnection = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Connection</span>(URI, <span style=""color:#a31515;"">"StatusHub"</span>); <span style=""color:green;"">// General events</span> signalRConnection.OnNonHubMessage += signalRConnection_OnNonHubMessage; signalRConnection.OnError += signalRConnection_OnError; signalRConnection.OnStateChanged += signalRConnection_OnStateChanged; <span style=""color:green;"">// SaveLocal up a Callback for Hub events</span> signalRConnection[<span style=""color:#a31515;"">"StatusHub"</span>].OnMethodCall += statusHub_OnMethodCall; <span style=""color:green;"">// Connect to the server</span> signalRConnection.Open(); } <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:green;"">// Close the connection when we are closing the sample</span> signalRConnection.Close(); } <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"START"</span>) && signalRConnection.State != <span style=""color:#2b91af;"">ConnectionStates</span>.Connected) signalRConnection.Open(); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"STOP"</span>) && signalRConnection.State == <span style=""color:#2b91af;"">ConnectionStates</span>.Connected) { signalRConnection.Close(); messages.Clear(); } <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"PING"</span>) && signalRConnection.State == <span style=""color:#2b91af;"">ConnectionStates</span>.Connected) { <span style=""color:green;"">// Call a Hub-method on the server.</span> signalRConnection[<span style=""color:#a31515;"">"StatusHub"</span>].Call(<span style=""color:#a31515;"">"Ping"</span>); } <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Connection Status Messages"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); messages.Draw(<span style=""color:#2b91af;"">Screen</span>.width - 20, 0); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); }); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> SignalR Events <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called on server-sent non-hub messages.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> signalRConnection_OnNonHubMessage(<span style=""color:#2b91af;"">Connection</span> manager, <span style=""color:blue;"">object</span> data) { messages.Add(<span style=""color:#a31515;"">"[Server Message] "</span> + data.ToString()); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called when the SignalR Connection's state changes.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> signalRConnection_OnStateChanged(<span style=""color:#2b91af;"">Connection</span> manager, <span style=""color:#2b91af;"">ConnectionStates</span> oldState, <span style=""color:#2b91af;"">ConnectionStates</span> newState) { messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"[State Change] {0} => {1}"</span>, oldState, newState)); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called when an error occures. The plugin may close the connection after this event.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> signalRConnection_OnError(<span style=""color:#2b91af;"">Connection</span> manager, <span style=""color:blue;"">string</span> error) { messages.Add(<span style=""color:#a31515;"">"[Error] "</span> + error); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called when the "StatusHub" hub wants to call a method on this client.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> statusHub_OnMethodCall(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:blue;"">string</span> method, <span style=""color:blue;"">params</span> <span style=""color:blue;"">object</span>[] args) { <span style=""color:blue;"">string</span> id = args.Length > 0 ? args[0] <span style=""color:blue;"">as</span> <span style=""color:blue;"">string</span> : <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> when = args.Length > 1 ? args[1].ToString() : <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">switch</span> (method) { <span style=""color:blue;"">case</span> <span style=""color:#a31515;"">"joined"</span>: messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"[{0}] {1} joined at {2}"</span>, hub.Name, id, when)); <span style=""color:blue;"">break</span>; <span style=""color:blue;"">case</span> <span style=""color:#a31515;"">"rejoined"</span>: messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"[{0}] {1} reconnected at {2}"</span>, hub.Name, id, when)); <span style=""color:blue;"">break</span>; <span style=""color:blue;"">case</span> <span style=""color:#a31515;"">"leave"</span>: messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"[{0}] {1} leaved at {2}"</span>, hub.Name, id, when)); <span style=""color:blue;"">break</span>; <span style=""color:blue;"">default</span>: <span style=""color:green;"">// pong</span> messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"[{0}] {1}"</span>, hub.Name, method)); <span style=""color:blue;"">break</span>; } } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region SignalR DemoHubSample public static string SignalR_DemoHubSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP.SignalR; <span style=""color:blue;"">using</span> BestHTTP.SignalR.Hubs; <span style=""color:blue;"">using</span> BestHTTP.SignalR.Messages; <span style=""color:blue;"">using</span> BestHTTP.SignalR.JsonEncoders; <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">DemoHubSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:blue;"">readonly</span> <span style=""color:#2b91af;"">Uri</span> URI = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(<span style=""color:#a31515;"">"http://besthttpsignalr.azurewebsites.net/signalr"</span>); <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The SignalR connection instance</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Connection</span> signalRConnection; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> DemoHub client side implementation</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">DemoHub</span> demoHub; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> TypedDemoHub client side implementation</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">TypedDemoHub</span> typedDemoHub; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> VB .NET Hub</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Hub</span> vbDemoHub; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Result of the VB demo's ReadStateValue call</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">string</span> vbReadStateResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:#2b91af;"">Vector2</span> scrollPos; <span style=""color:blue;"">void</span> Start() { <span style=""color:green;"">// Create the hubs</span> demoHub = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">DemoHub</span>(); typedDemoHub = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">TypedDemoHub</span>(); vbDemoHub = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Hub</span>(<span style=""color:#a31515;"">"vbdemo"</span>); <span style=""color:green;"">// Create the SignalR connection, passing all the three hubs to it</span> signalRConnection = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Connection</span>(URI, demoHub, typedDemoHub, vbDemoHub); <span style=""color:green;"">// Switch from the default encoder to the LitJson Encoder becouse it can handle the complex types too.</span> signalRConnection.JsonEncoder = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">LitJsonEncoder</span>(); <span style=""color:green;"">// Call the demo functions when we successfully connect to the server</span> signalRConnection.OnConnected += (connection) => { <span style=""color:blue;"">var</span> person = <span style=""color:blue;"">new</span> { Name = <span style=""color:#a31515;"">"Foo"</span>, Age = 20, Address = <span style=""color:blue;"">new</span> { Street = <span style=""color:#a31515;"">"One Microsoft Way"</span>, Zip = <span style=""color:#a31515;"">"98052"</span> } }; <span style=""color:green;"">// Call the demo functions</span> demoHub.ReportProgress(<span style=""color:#a31515;"">"Long running job!"</span>); demoHub.AddToGroups(); demoHub.GetValue(); demoHub.TaskWithException(); demoHub.GenericTaskWithException(); demoHub.SynchronousException(); demoHub.DynamicTask(); demoHub.PassingDynamicComplex(person); demoHub.SimpleArray(<span style=""color:blue;"">new</span> <span style=""color:blue;"">int</span>[] { 5, 5, 6 }); demoHub.ComplexType(person); demoHub.ComplexArray(<span style=""color:blue;"">new</span> <span style=""color:blue;"">object</span>[] { person, person, person }); demoHub.Overload(); <span style=""color:green;"">// set some state</span> demoHub.State[<span style=""color:#a31515;"">"name"</span>] = <span style=""color:#a31515;"">"Testing state!"</span>; demoHub.ReadStateValue(); demoHub.PlainTask(); demoHub.GenericTaskWithContinueWith(); typedDemoHub.Echo(<span style=""color:#a31515;"">"Typed echo Callback"</span>); <span style=""color:green;"">// vbDemo is not wrapped in a hub class, it would contain only one function</span> vbDemoHub.Call(<span style=""color:#a31515;"">"readStateValue"</span>, (hub, msg, result) => vbReadStateResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Read some state from VB.NET! => {0}"</span>, result.ReturnValue == <span style=""color:blue;"">null</span> ? <span style=""color:#a31515;"">"undefined"</span> : result.ReturnValue.ToString())); }; <span style=""color:green;"">// Start opening the signalR connection</span> signalRConnection.Open(); } <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:green;"">// Close the connection when we are closing this sample</span> signalRConnection.Close(); } <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { scrollPos = <span style=""color:#2b91af;"">GUILayout</span>.BeginScrollView(scrollPos, <span style=""color:blue;"">false</span>, <span style=""color:blue;"">false</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); demoHub.Draw(); typedDemoHub.Draw(); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Read State Value"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(vbReadStateResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); <span style=""color:#2b91af;"">GUILayout</span>.EndScrollView(); }); } } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Wrapper class of the 'TypedDemoHub' hub</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">TypedDemoHub</span> : <span style=""color:#2b91af;"">Hub</span> { <span style=""color:blue;"">string</span> typedEchoResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> typedEchoClientResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">public</span> TypedDemoHub() :<span style=""color:blue;"">base</span>(<span style=""color:#a31515;"">"typeddemohub"</span>) { } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called by the Connection class to be able to set up mappings.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">override</span> <span style=""color:blue;"">void</span> Setup() { <span style=""color:green;"">// Setup server-called functions</span> <span style=""color:blue;"">base</span>.On(<span style=""color:#a31515;"">"Echo"</span>, Echo); } <span style=""color:blue;""> #region</span> Server Called Functions <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Server-called, client side implementation of the Echo function</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> Echo(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">MethodCallMessage</span> methodCall) { typedEchoClientResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} #{1} triggered!"</span>, methodCall.Arguments[0], methodCall.Arguments[1]); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Client Called Function(s) <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Client-called, server side implementation of the Echo function.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> When the function successfully executed on the server the OnEcho_Done Callback function will be called.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> Echo(<span style=""color:blue;"">string</span> msg) { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"echo"</span>, OnEcho_Done, msg); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> When the function successfully executed on the server this Callback function will be called.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnEcho_Done(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">ClientMessage</span> originalMessage, <span style=""color:#2b91af;"">ResultMessage</span> result) { typedEchoResult = <span style=""color:#a31515;"">"TypedDemoHub.Echo(string message) invoked!"</span>; } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> Draw() { <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Typed Callback"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); <span style=""color:#2b91af;"">GUILayout</span>.Label(typedEchoResult); <span style=""color:#2b91af;"">GUILayout</span>.Label(typedEchoClientResult); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); } } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> A wrapper class for the 'DemoHub' hub.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">DemoHub</span> : <span style=""color:#2b91af;"">Hub</span> { <span style=""color:blue;""> #region</span> Private fields <span style=""color:green;"">// These fields are here to store results of the function calls</span> <span style=""color:blue;"">float</span> longRunningJobProgress = 0f; <span style=""color:blue;"">string</span> longRunningJobStatus = <span style=""color:#a31515;"">"Not Started!"</span>; <span style=""color:blue;"">string</span> fromArbitraryCodeResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> groupAddedResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> dynamicTaskResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> genericTaskResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> taskWithExceptionResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> genericTaskWithExceptionResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> synchronousExceptionResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> invokingHubMethodWithDynamicResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> simpleArrayResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> complexTypeResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> complexArrayResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> voidOverloadResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> intOverloadResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> readStateResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> plainTaskResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> genericTaskWithContinueWithResult = <span style=""color:blue;"">string</span>.Empty; <span style=""color:#2b91af;"">GUIMessageList</span> invokeResults = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">GUIMessageList</span>(); <span style=""color:blue;""> #endregion</span> <span style=""color:blue;"">public</span> DemoHub() : <span style=""color:blue;"">base</span>(<span style=""color:#a31515;"">"demo"</span>) { } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called by the Connection class to be able to set up mappings.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">override</span> <span style=""color:blue;"">void</span> Setup() { <span style=""color:green;"">// Setup server-called functions</span> <span style=""color:blue;"">base</span>.On(<span style=""color:#a31515;"">"invoke"</span>, Invoke); <span style=""color:blue;"">base</span>.On(<span style=""color:#a31515;"">"signal"</span>, Signal); <span style=""color:blue;"">base</span>.On(<span style=""color:#a31515;"">"groupAdded"</span>, GroupAdded); <span style=""color:blue;"">base</span>.On(<span style=""color:#a31515;"">"fromArbitraryCode"</span>, FromArbitraryCode); } <span style=""color:blue;""> #region</span> Client Called Functions <span style=""color:blue;""> #region</span> ReportProgress <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> ReportProgress(<span style=""color:blue;"">string</span> arg) { Call(<span style=""color:#a31515;"">"reportProgress"</span>, OnLongRunningJob_Done, <span style=""color:blue;"">null</span>, OnLongRunningJob_Progress, arg); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> OnLongRunningJob_Progress(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">ClientMessage</span> originialMessage, <span style=""color:#2b91af;"">ProgressMessage</span> progress) { longRunningJobProgress = (<span style=""color:blue;"">float</span>)progress.Progress; longRunningJobStatus = progress.Progress.ToString() + <span style=""color:#a31515;"">"%"</span>; } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> OnLongRunningJob_Done(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">ClientMessage</span> originalMessage, <span style=""color:#2b91af;"">ResultMessage</span> result) { longRunningJobStatus = result.ReturnValue.ToString(); MultipleCalls(); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> MultipleCalls() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"multipleCalls"</span>); } <span style=""color:blue;""> #region</span> DynamicTask <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> DynamicTask() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"dynamicTask"</span>, OnDynamicTask_Done, OnDynamicTask_Failed); } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnDynamicTask_Failed(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">ClientMessage</span> originalMessage, <span style=""color:#2b91af;"">ResultMessage</span> result) { dynamicTaskResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"The dynamic task failed :( {0}"</span>, result.ErrorMessage); } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnDynamicTask_Done(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">ClientMessage</span> originalMessage, <span style=""color:#2b91af;"">ResultMessage</span> result) { dynamicTaskResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"The dynamic task! {0}"</span>, result.ReturnValue); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> AddToGroups() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"addToGroups"</span>); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> GetValue() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"getValue"</span>, (hub, msg, result) => genericTaskResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"The value is {0} after 5 seconds"</span>, result.ReturnValue)); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> TaskWithException() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"taskWithException"</span>, <span style=""color:blue;"">null</span>, (hub, msg, result) => taskWithExceptionResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Error: {0}"</span>, result.ErrorMessage)); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> GenericTaskWithException() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"genericTaskWithException"</span>, <span style=""color:blue;"">null</span>, (hub, msg, result) => genericTaskWithExceptionResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Error: {0}"</span>, result.ErrorMessage)); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> SynchronousException() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"synchronousException"</span>, <span style=""color:blue;"">null</span>, (hub, msg, result) => synchronousExceptionResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Error: {0}"</span>, result.ErrorMessage)); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> PassingDynamicComplex(<span style=""color:blue;"">object</span> person) { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"passingDynamicComplex"</span>, (hub, msg, result) => invokingHubMethodWithDynamicResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"The person's age is {0}"</span>, result.ReturnValue), person); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> SimpleArray(<span style=""color:blue;"">int</span>[] array) { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"simpleArray"</span>, (hub, msg, result) => simpleArrayResult = <span style=""color:#a31515;"">"Simple array works!"</span>, array); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> ComplexType(<span style=""color:blue;"">object</span> person) { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"complexType"</span>, (hub, msg, result) => complexTypeResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Complex Type -> {0}"</span>, (<span style=""color:blue;"">this</span> <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">IHub</span>).Connection.JsonEncoder.Encode(<span style=""color:blue;"">this</span>.State[<span style=""color:#a31515;"">"person"</span>])), person); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> ComplexArray(<span style=""color:blue;"">object</span>[] complexArray) { <span style=""color:green;"">// We need to cast the object array to object to keep it as an array</span> <span style=""color:green;"">// http://stackoverflow.com/questions/36350/how-to-pass-a-single-object-to-a-params-object</span> <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"ComplexArray"</span>, (hub, msg, result) => complexArrayResult = <span style=""color:#a31515;"">"Complex Array Works!"</span>, (<span style=""color:blue;"">object</span>)complexArray); } <span style=""color:blue;""> #region</span> Overloads <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> Overload() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"Overload"</span>, OnVoidOverload_Done); } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnVoidOverload_Done(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">ClientMessage</span> originalMessage, <span style=""color:#2b91af;"">ResultMessage</span> result) { voidOverloadResult = <span style=""color:#a31515;"">"Void Overload called"</span>; Overload(101); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> Overload(<span style=""color:blue;"">int</span> number) { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"Overload"</span>, OnIntOverload_Done, number); } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnIntOverload_Done(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">ClientMessage</span> originalMessage, <span style=""color:#2b91af;"">ResultMessage</span> result) { intOverloadResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Overload with return value called => {0}"</span>, result.ReturnValue.ToString()); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> ReadStateValue() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"readStateValue"</span>, (hub, msg, result) => readStateResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Read some state! => {0}"</span>, result.ReturnValue)); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> PlainTask() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"plainTask"</span>, (hub, msg, result) => plainTaskResult = <span style=""color:#a31515;"">"Plain Task Result"</span>); } <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> GenericTaskWithContinueWith() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"genericTaskWithContinueWith"</span>, (hub, msg, result) => genericTaskWithContinueWithResult = result.ReturnValue.ToString()); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Server Called Functions <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> FromArbitraryCode(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">MethodCallMessage</span> methodCall) { fromArbitraryCodeResult = methodCall.Arguments[0] <span style=""color:blue;"">as</span> <span style=""color:blue;"">string</span>; } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> GroupAdded(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">MethodCallMessage</span> methodCall) { <span style=""color:blue;"">if</span> (!<span style=""color:blue;"">string</span>.IsNullOrEmpty(groupAddedResult)) groupAddedResult = <span style=""color:#a31515;"">"Group Already Added!"</span>; <span style=""color:blue;"">else</span> groupAddedResult = <span style=""color:#a31515;"">"Group Added!"</span>; } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> Signal(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">MethodCallMessage</span> methodCall) { dynamicTaskResult = <span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"The dynamic task! {0}"</span>, methodCall.Arguments[0]); } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> Invoke(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">MethodCallMessage</span> methodCall) { invokeResults.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} client state index -> {1}"</span>, methodCall.Arguments[0], <span style=""color:blue;"">this</span>.State[<span style=""color:#a31515;"">"index"</span>])); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Draw <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Display the result's of the function calls.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> Draw() { <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Arbitrary Code"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"Sending {0} from arbitrary code without the hub itself!"</span>, fromArbitraryCodeResult)); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Group Added"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(groupAddedResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Dynamic Task"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(dynamicTaskResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Report Progress"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); <span style=""color:#2b91af;"">GUILayout</span>.Label(longRunningJobStatus); <span style=""color:#2b91af;"">GUILayout</span>.HorizontalSlider(longRunningJobProgress, 0, 100); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Generic Task"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(genericTaskResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Task With Exception"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(taskWithExceptionResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Generic Task With Exception"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(genericTaskWithExceptionResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Synchronous Exception"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(synchronousExceptionResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Invoking hub method with dynamic"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(invokingHubMethodWithDynamicResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Simple Array"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(simpleArrayResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Complex Type"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(complexTypeResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Complex Array"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(complexArrayResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Overloads"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); <span style=""color:#2b91af;"">GUILayout</span>.Label(voidOverloadResult); <span style=""color:#2b91af;"">GUILayout</span>.Label(intOverloadResult); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Read State Value"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(readStateResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Plain Task"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(plainTaskResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Generic Task With ContinueWith"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); <span style=""color:#2b91af;"">GUILayout</span>.Label(genericTaskWithContinueWithResult); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Message Pump"</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); invokeResults.Draw(<span style=""color:#2b91af;"">Screen</span>.width - 40, 270); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion #region SignalR AuthenticationSample public static string SignalR_AuthenticationSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> System.Collections.Generic; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP.SignalR; <span style=""color:blue;"">using</span> BestHTTP.SignalR.Hubs; <span style=""color:blue;"">using</span> BestHTTP.SignalR.Messages; <span style=""color:blue;"">using</span> BestHTTP.SignalR.Authentication; <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">AuthenticationSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:blue;"">readonly</span> <span style=""color:#2b91af;"">Uri</span> URI = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Uri</span>(<span style=""color:#a31515;"">"https://besthttpsignalr.azurewebsites.net/signalr"</span>); <span style=""color:blue;""> #region</span> Private Fields <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Reference to the SignalR Connection</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">Connection</span> signalRConnection; <span style=""color:blue;"">string</span> userName = <span style=""color:blue;"">string</span>.Empty; <span style=""color:blue;"">string</span> role = <span style=""color:blue;"">string</span>.Empty; <span style=""color:#2b91af;"">Vector2</span> scrollPos; <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> Start() { <span style=""color:green;"">// Create the SignalR connection, and pass the hubs that we want to connect to</span> signalRConnection = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">Connection</span>(URI, <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">BaseHub</span>(<span style=""color:#a31515;"">"noauthhub"</span>, <span style=""color:#a31515;"">"Messages"</span>), <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">BaseHub</span>(<span style=""color:#a31515;"">"invokeauthhub"</span>, <span style=""color:#a31515;"">"Messages Invoked By Admin or Invoker"</span>), <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">BaseHub</span>(<span style=""color:#a31515;"">"authhub"</span>, <span style=""color:#a31515;"">"Messages Requiring Authentication to Send or Receive"</span>), <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">BaseHub</span>(<span style=""color:#a31515;"">"inheritauthhub"</span>, <span style=""color:#a31515;"">"Messages Requiring Authentication to Send or Receive Because of Inheritance"</span>), <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">BaseHub</span>(<span style=""color:#a31515;"">"incomingauthhub"</span>, <span style=""color:#a31515;"">"Messages Requiring Authentication to Send"</span>), <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">BaseHub</span>(<span style=""color:#a31515;"">"adminauthhub"</span>, <span style=""color:#a31515;"">"Messages Requiring Admin Membership to Send or Receive"</span>), <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">BaseHub</span>(<span style=""color:#a31515;"">"userandroleauthhub"</span>, <span style=""color:#a31515;"">"Messages Requiring Name to be \"User\" and Role to be \"Admin\" to Send or Receive"</span>)); <span style=""color:green;"">// SaveLocal the authenticator if we have valid fields</span> <span style=""color:blue;"">if</span> (!<span style=""color:blue;"">string</span>.IsNullOrEmpty(userName) && !<span style=""color:blue;"">string</span>.IsNullOrEmpty(role)) signalRConnection.AuthenticationProvider = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">HeaderAuthenticator</span>(userName, role); <span style=""color:green;"">// SaveLocal up event handler</span> signalRConnection.OnConnected += signalRConnection_OnConnected; <span style=""color:green;"">// Start to connect to the server.</span> signalRConnection.Open(); } <span style=""color:blue;"">void</span> OnDestroy() { <span style=""color:green;"">// Close the connection when we are closing the sample</span> signalRConnection.Close(); } <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { scrollPos = <span style=""color:#2b91af;"">GUILayout</span>.BeginScrollView(scrollPos, <span style=""color:blue;"">false</span>, <span style=""color:blue;"">false</span>); <span style=""color:#2b91af;"">GUILayout</span>.BeginVertical(); <span style=""color:blue;"">if</span> (signalRConnection.AuthenticationProvider == <span style=""color:blue;"">null</span>) { <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Username (Enter 'User'):"</span>); userName = <span style=""color:#2b91af;"">GUILayout</span>.TextField(userName, <span style=""color:#2b91af;"">GUILayout</span>.MinWidth(100)); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Roles (Enter 'Invoker' or 'Admin'):"</span>); role = <span style=""color:#2b91af;"">GUILayout</span>.TextField(role, <span style=""color:#2b91af;"">GUILayout</span>.MinWidth(100)); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Log in"</span>)) Restart(); } <span style=""color:blue;"">for</span> (<span style=""color:blue;"">int</span> i = 0; i < signalRConnection.Hubs.Length; ++i) (signalRConnection.Hubs[i] <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">BaseHub</span>).Draw(); <span style=""color:#2b91af;"">GUILayout</span>.EndVertical(); <span style=""color:#2b91af;"">GUILayout</span>.EndScrollView(); }); } <span style=""color:blue;""> #endregion</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called when we successfully connected to the server.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> signalRConnection_OnConnected(<span style=""color:#2b91af;"">Connection</span> manager) { <span style=""color:green;"">// call 'InvokedFromClient' on all hubs</span> <span style=""color:blue;"">for</span> (<span style=""color:blue;"">int</span> i = 0; i < signalRConnection.Hubs.Length; ++i) (signalRConnection.Hubs[i] <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">BaseHub</span>).InvokedFromClient(); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Helper function to do a hard-restart to the server.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">void</span> Restart() { <span style=""color:green;"">// Clean up</span> signalRConnection.OnConnected -= signalRConnection_OnConnected; <span style=""color:green;"">// Close current connection</span> signalRConnection.Close(); signalRConnection = <span style=""color:blue;"">null</span>; <span style=""color:green;"">// start again, with authentication if we filled in all input fields</span> Start(); } } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Hub implementation for the authentication demo. All hubs that we connect to has the same server and client side functions.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">BaseHub</span> : <span style=""color:#2b91af;"">Hub</span> { <span style=""color:blue;""> #region</span> Private Fields <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Hub specific title</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">string</span> Title; <span style=""color:blue;"">private</span> <span style=""color:#2b91af;"">GUIMessageList</span> messages = <span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">GUIMessageList</span>(); <span style=""color:blue;""> #endregion</span> <span style=""color:blue;"">public</span> BaseHub(<span style=""color:blue;"">string</span> name, <span style=""color:blue;"">string</span> title) : <span style=""color:blue;"">base</span>(name) { <span style=""color:blue;"">this</span>.Title = title; } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> Called by the Connection class to be able to set up mappings.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">override</span> <span style=""color:blue;"">void</span> Setup() { <span style=""color:green;"">// Map the server-callable method names to the real functions.</span> On(<span style=""color:#a31515;"">"joined"</span>, Joined); On(<span style=""color:#a31515;"">"rejoined"</span>, Rejoined); On(<span style=""color:#a31515;"">"left"</span>, Left); On(<span style=""color:#a31515;"">"invoked"</span>, Invoked); } <span style=""color:blue;""> #region</span> Server Called Functions <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> Joined(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">MethodCallMessage</span> methodCall) { <span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>> AuthInfo = methodCall.Arguments[2] <span style=""color:blue;"">as</span> <span style=""color:#2b91af;"">Dictionary</span><<span style=""color:blue;"">string</span>, <span style=""color:blue;"">object</span>>; messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} joined at {1}\n\tIsAuthenticated: {2} IsAdmin: {3} UserName: {4}"</span>, methodCall.Arguments[0], methodCall.Arguments[1], AuthInfo[<span style=""color:#a31515;"">"IsAuthenticated"</span>], AuthInfo[<span style=""color:#a31515;"">"IsAdmin"</span>], AuthInfo[<span style=""color:#a31515;"">"UserName"</span>])); } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> Rejoined(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">MethodCallMessage</span> methodCall) { messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} reconnected at {1}"</span>, methodCall.Arguments[0], methodCall.Arguments[1])); } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> Left(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">MethodCallMessage</span> methodCall) { messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} left at {1}"</span>, methodCall.Arguments[0], methodCall.Arguments[1])); } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> Invoked(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">MethodCallMessage</span> methodCall) { messages.Add(<span style=""color:blue;"">string</span>.Format(<span style=""color:#a31515;"">"{0} invoked hub method at {1}"</span>, methodCall.Arguments[0], methodCall.Arguments[1])); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Client callable function implementation <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> InvokedFromClient() { <span style=""color:blue;"">base</span>.Call(<span style=""color:#a31515;"">"invokedFromClient"</span>, OnInvoked, OnInvokeFailed); } <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnInvoked(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">ClientMessage</span> originalMessage, <span style=""color:#2b91af;"">ResultMessage</span> result) { <span style=""color:#2b91af;"">Debug</span>.Log(hub.Name + <span style=""color:#a31515;"">" invokedFromClient success!"</span>); } <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> This Callback function will be called every time we try to access a protected API while we are using an non-authenticated connection.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">private</span> <span style=""color:blue;"">void</span> OnInvokeFailed(<span style=""color:#2b91af;"">Hub</span> hub, <span style=""color:#2b91af;"">ClientMessage</span> originalMessage, <span style=""color:#2b91af;"">ResultMessage</span> result) { <span style=""color:#2b91af;"">Debug</span>.LogWarning(hub.Name + <span style=""color:#a31515;"">" "</span> + result.ErrorMessage); } <span style=""color:blue;""> #endregion</span> <span style=""color:blue;"">public</span> <span style=""color:blue;"">void</span> Draw() { <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:blue;"">this</span>.Title); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(20); messages.Draw(<span style=""color:#2b91af;"">Screen</span>.width - 20, 100); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); } }</pre>"; #endregion #region CacheMaintenanceSample public static string CacheMaintenanceSample = @"<pre style=""font-family:Consolas;font-size:13;color:black;background:silver;""><span style=""color:blue;"">using</span> System; <span style=""color:blue;"">using</span> System.Collections.Generic; <span style=""color:blue;"">using</span> UnityEngine; <span style=""color:blue;"">using</span> BestHTTP; <span style=""color:blue;"">using</span> BestHTTP.Caching; <span style=""color:blue;"">public</span> <span style=""color:blue;"">sealed</span> <span style=""color:blue;"">class</span> <span style=""color:#2b91af;"">CacheMaintenanceSample</span> : <span style=""color:#2b91af;"">MonoBehaviour</span> { <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> An enum for better readability</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">enum</span> <span style=""color:#2b91af;"">DeleteOlderTypes</span> { Days, Hours, Mins, Secs }; <span style=""color:blue;""> #region</span> Private Fields <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> What methode to call on the TimeSpan</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:#2b91af;"">DeleteOlderTypes</span> deleteOlderType = <span style=""color:#2b91af;"">DeleteOlderTypes</span>.Secs; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> The value for the TimeSpan.</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">int</span> value = 10; <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""><summary></span> <span style=""color:gray;"">///</span><span style=""color:green;""> What's our maximum cache size</span> <span style=""color:gray;"">///</span><span style=""color:green;""> </span><span style=""color:gray;""></summary></span> <span style=""color:blue;"">int</span> maxCacheSize = 5 * 1024 * 1024; <span style=""color:blue;""> #endregion</span> <span style=""color:blue;""> #region</span> Unity Events <span style=""color:blue;"">void</span> OnGUI() { <span style=""color:#2b91af;"">GUIHelper</span>.DrawArea(<span style=""color:#2b91af;"">GUIHelper</span>.ClientArea, <span style=""color:blue;"">true</span>, () => { <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Delete cached entities older then"</span>); <span style=""color:#2b91af;"">GUILayout</span>.Label(value.ToString(), <span style=""color:#2b91af;"">GUILayout</span>.MinWidth(50)); value = (<span style=""color:blue;"">int</span>)<span style=""color:#2b91af;"">GUILayout</span>.HorizontalSlider(value, 1, 60, <span style=""color:#2b91af;"">GUILayout</span>.MinWidth(100)); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); deleteOlderType = (<span style=""color:#2b91af;"">DeleteOlderTypes</span>)(<span style=""color:blue;"">int</span>)<span style=""color:#2b91af;"">GUILayout</span>.SelectionGrid((<span style=""color:blue;"">int</span>)deleteOlderType, <span style=""color:blue;"">new</span> <span style=""color:blue;"">string</span>[] { <span style=""color:#a31515;"">"Days"</span>, <span style=""color:#a31515;"">"Hours"</span>, <span style=""color:#a31515;"">"Mins"</span>, <span style=""color:#a31515;"">"Secs"</span> }, 4); <span style=""color:#2b91af;"">GUILayout</span>.FlexibleSpace(); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:#2b91af;"">GUILayout</span>.BeginHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Label(<span style=""color:#a31515;"">"Max Cache Size (bytes): "</span>, <span style=""color:#2b91af;"">GUILayout</span>.Width(150)); <span style=""color:#2b91af;"">GUILayout</span>.Label(maxCacheSize.ToString(<span style=""color:#a31515;"">"N0"</span>), <span style=""color:#2b91af;"">GUILayout</span>.Width(70)); maxCacheSize = (<span style=""color:blue;"">int</span>)<span style=""color:#2b91af;"">GUILayout</span>.HorizontalSlider(maxCacheSize, 1024, 10 * 1024 * 1024); <span style=""color:#2b91af;"">GUILayout</span>.EndHorizontal(); <span style=""color:#2b91af;"">GUILayout</span>.Space(10); <span style=""color:blue;"">if</span> (<span style=""color:#2b91af;"">GUILayout</span>.Button(<span style=""color:#a31515;"">"Maintenance"</span>)) { <span style=""color:#2b91af;"">TimeSpan</span> deleteOlder = <span style=""color:#2b91af;"">TimeSpan</span>.FromDays(14); <span style=""color:blue;"">switch</span> (deleteOlderType) { <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">DeleteOlderTypes</span>.Days: deleteOlder = <span style=""color:#2b91af;"">TimeSpan</span>.FromDays(value); <span style=""color:blue;"">break</span>; <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">DeleteOlderTypes</span>.Hours: deleteOlder = <span style=""color:#2b91af;"">TimeSpan</span>.FromHours(value); <span style=""color:blue;"">break</span>; <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">DeleteOlderTypes</span>.Mins: deleteOlder = <span style=""color:#2b91af;"">TimeSpan</span>.FromMinutes(value); <span style=""color:blue;"">break</span>; <span style=""color:blue;"">case</span> <span style=""color:#2b91af;"">DeleteOlderTypes</span>.Secs: deleteOlder = <span style=""color:#2b91af;"">TimeSpan</span>.FromSeconds(value); <span style=""color:blue;"">break</span>; } <span style=""color:green;"">// Call the BeginMaintainence function. It will run on a thread to do not block the main thread.</span> <span style=""color:#2b91af;"">HTTPCacheService</span>.BeginMaintainence(<span style=""color:blue;"">new</span> <span style=""color:#2b91af;"">HTTPCacheMaintananceParams</span>(deleteOlder, (<span style=""color:blue;"">ulong</span>)maxCacheSize)); } }); } <span style=""color:blue;""> #endregion</span> }</pre>"; #endregion } }