#if !BESTHTTP_DISABLE_SIGNALR
using System;
using UnityEngine;
using BestHTTP.SignalR;
using BestHTTP.SignalR.Hubs;
using BestHTTP.SignalR.Messages;
using BestHTTP.SignalR.JsonEncoders;
using BestHTTP.Examples;
class DemoHubSample : MonoBehaviour
{
readonly Uri URI = new Uri("https://besthttpsignalr.azurewebsites.net/signalr");
///
/// The SignalR connection instance
///
Connection signalRConnection;
///
/// DemoHub client side implementation
///
DemoHub demoHub;
///
/// TypedDemoHub client side implementation
///
TypedDemoHub typedDemoHub;
///
/// VB .NET Hub
///
Hub vbDemoHub;
///
/// Result of the VB demo's ReadStateValue call
///
string vbReadStateResult = string.Empty;
Vector2 scrollPos;
void Start()
{
// Create the hubs
demoHub = new DemoHub();
typedDemoHub = new TypedDemoHub();
vbDemoHub = new Hub("vbdemo");
// Create the SignalR connection, passing all the three hubs to it
signalRConnection = new Connection(URI, demoHub, typedDemoHub, vbDemoHub);
// Switch from the default encoder to the LitJson Encoder because it can handle the complex types too.
signalRConnection.JsonEncoder = new LitJsonEncoder();
// Call the demo functions when we successfully connect to the server
signalRConnection.OnConnected += (connection) =>
{
var person = new { Name = "Foo", Age = 20, Address = new { Street = "One Microsoft Way", Zip = "98052" } };
// Call the demo functions
demoHub.AddToGroups();
demoHub.GetValue();
demoHub.TaskWithException();
demoHub.GenericTaskWithException();
demoHub.SynchronousException();
demoHub.DynamicTask();
demoHub.PassingDynamicComplex(person);
demoHub.SimpleArray(new int[] { 5, 5, 6 });
demoHub.ComplexType(person);
demoHub.ComplexArray(new object[] { person, person, person });
demoHub.ReportProgress("Long running job!");
demoHub.Overload();
// set some state
demoHub.State["name"] = "Testing state!";
demoHub.ReadStateValue();
demoHub.PlainTask();
demoHub.GenericTaskWithContinueWith();
typedDemoHub.Echo("Typed echo callback");
// vbDemo is not wrapped in a hub class, it would contain only one function
vbDemoHub.Call("readStateValue", (hub, msg, result) => vbReadStateResult = string.Format("Read some state from VB.NET! => {0}", result.ReturnValue == null ? "undefined" : result.ReturnValue.ToString()));
};
// Start opening the signalR connection
signalRConnection.Open();
}
void OnDestroy()
{
// Close the connection when we are closing this sample
signalRConnection.Close();
}
void OnGUI()
{
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
scrollPos = GUILayout.BeginScrollView(scrollPos, false, false);
GUILayout.BeginVertical();
demoHub.Draw();
typedDemoHub.Draw();
GUILayout.Label("Read State Value");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(vbReadStateResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.EndVertical();
GUILayout.EndScrollView();
});
}
}
///
/// Wrapper class of the 'TypedDemoHub' hub
///
class TypedDemoHub : Hub
{
string typedEchoResult = string.Empty;
string typedEchoClientResult = string.Empty;
public TypedDemoHub()
:base("typeddemohub")
{
// Setup server-called functions
base.On("Echo", Echo);
}
#region Server Called Functions
///
/// Server-called, client side implementation of the Echo function
///
private void Echo(Hub hub, MethodCallMessage methodCall)
{
typedEchoClientResult = string.Format("{0} #{1} triggered!", methodCall.Arguments[0], methodCall.Arguments[1]);
}
#endregion
#region Client Called Function(s)
///
/// Client-called, server side implementation of the Echo function.
/// When the function successfully executed on the server the OnEcho_Done callback function will be called.
///
public void Echo(string msg)
{
base.Call("echo", OnEcho_Done, msg);
}
///
/// When the function successfully executed on the server this callback function will be called.
///
private void OnEcho_Done(Hub hub, ClientMessage originalMessage, ResultMessage result)
{
typedEchoResult = "TypedDemoHub.Echo(string message) invoked!";
}
#endregion
public void Draw()
{
GUILayout.Label("Typed callback");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.BeginVertical();
GUILayout.Label(typedEchoResult);
GUILayout.Label(typedEchoClientResult);
GUILayout.EndVertical();
GUILayout.EndHorizontal();
GUILayout.Space(10);
}
}
///
/// A wrapper class for the 'DemoHub' hub.
///
class DemoHub : Hub
{
#region Private fields
// These fields are here to store results of the function calls
float longRunningJobProgress = 0f;
string longRunningJobStatus = "Not Started!";
string fromArbitraryCodeResult = string.Empty;
string groupAddedResult = string.Empty;
string dynamicTaskResult = string.Empty;
string genericTaskResult = string.Empty;
string taskWithExceptionResult = string.Empty;
string genericTaskWithExceptionResult = string.Empty;
string synchronousExceptionResult = string.Empty;
string invokingHubMethodWithDynamicResult = string.Empty;
string simpleArrayResult = string.Empty;
string complexTypeResult = string.Empty;
string complexArrayResult = string.Empty;
string voidOverloadResult = string.Empty;
string intOverloadResult = string.Empty;
string readStateResult = string.Empty;
string plainTaskResult = string.Empty;
string genericTaskWithContinueWithResult = string.Empty;
GUIMessageList invokeResults = new GUIMessageList();
#endregion
public DemoHub()
: base("demo")
{
// Setup server-called functions
base.On("invoke", Invoke);
base.On("signal", Signal);
base.On("groupAdded", GroupAdded);
base.On("fromArbitraryCode", FromArbitraryCode);
}
#region Client Called Functions
#region ReportProgress
public void ReportProgress(string arg)
{
Call("reportProgress", OnLongRunningJob_Done, null, OnLongRunningJob_Progress, arg);
}
public void OnLongRunningJob_Progress(Hub hub, ClientMessage originialMessage, ProgressMessage progress)
{
longRunningJobProgress = (float)progress.Progress;
longRunningJobStatus = progress.Progress.ToString() + "%";
}
public void OnLongRunningJob_Done(Hub hub, ClientMessage originalMessage, ResultMessage result)
{
longRunningJobStatus = result.ReturnValue.ToString();
MultipleCalls();
}
#endregion
public void MultipleCalls()
{
base.Call("multipleCalls");
}
#region DynamicTask
public void DynamicTask()
{
base.Call("dynamicTask", OnDynamicTask_Done, OnDynamicTask_Failed);
}
private void OnDynamicTask_Failed(Hub hub, ClientMessage originalMessage, FailureMessage result)
{
dynamicTaskResult = string.Format("The dynamic task failed :( {0}", result.ErrorMessage);
}
private void OnDynamicTask_Done(Hub hub, ClientMessage originalMessage, ResultMessage result)
{
dynamicTaskResult = string.Format("The dynamic task! {0}", result.ReturnValue);
}
#endregion
public void AddToGroups()
{
base.Call("addToGroups");
}
public void GetValue()
{
base.Call("getValue", (hub, msg, result) => genericTaskResult = string.Format("The value is {0} after 5 seconds", result.ReturnValue));
}
public void TaskWithException()
{
// This method call must fail, so only error handler added
base.Call("taskWithException", null, (Hub hub, ClientMessage msg, FailureMessage error) => taskWithExceptionResult = string.Format("Error: {0}", error.ErrorMessage));
}
public void GenericTaskWithException()
{
// This method call must fail, so only error handler added
base.Call("genericTaskWithException", null, (Hub hub, ClientMessage msg, FailureMessage error) => genericTaskWithExceptionResult = string.Format("Error: {0}", error.ErrorMessage));
}
public void SynchronousException()
{
// This method call must fail, so only error handler added
base.Call("synchronousException", null, (Hub hub, ClientMessage msg, FailureMessage error) => synchronousExceptionResult = string.Format("Error: {0}", error.ErrorMessage));
}
public void PassingDynamicComplex(object person)
{
base.Call("passingDynamicComplex", (hub, msg, result) => invokingHubMethodWithDynamicResult = string.Format("The person's age is {0}", result.ReturnValue), person);
}
public void SimpleArray(int[] array)
{
base.Call("simpleArray", (hub, msg, result) => simpleArrayResult = "Simple array works!", array);
}
public void ComplexType(object person)
{
base.Call("complexType", (hub, msg, result) => complexTypeResult = string.Format("Complex Type -> {0}", (this as IHub).Connection.JsonEncoder.Encode(this.State["person"])), person);
}
public void ComplexArray(object[] complexArray)
{
// We need to cast the object array to object to keep it as an array
// http://stackoverflow.com/questions/36350/how-to-pass-a-single-object-to-a-params-object
base.Call("ComplexArray", (hub, msg, result) => complexArrayResult = "Complex Array Works!", (object)complexArray);
}
#region Overloads
public void Overload()
{
base.Call("Overload", OnVoidOverload_Done);
}
private void OnVoidOverload_Done(Hub hub, ClientMessage originalMessage, ResultMessage result)
{
voidOverloadResult = "Void Overload called";
Overload(101);
}
public void Overload(int number)
{
base.Call("Overload", OnIntOverload_Done, number);
}
private void OnIntOverload_Done(Hub hub, ClientMessage originalMessage, ResultMessage result)
{
intOverloadResult = string.Format("Overload with return value called => {0}", result.ReturnValue.ToString());
}
#endregion
public void ReadStateValue()
{
base.Call("readStateValue", (hub, msg, result) => readStateResult = string.Format("Read some state! => {0}", result.ReturnValue));
}
public void PlainTask()
{
base.Call("plainTask", (hub, msg, result) => plainTaskResult = "Plain Task Result");
}
public void GenericTaskWithContinueWith()
{
base.Call("genericTaskWithContinueWith", (hub, msg, result) => genericTaskWithContinueWithResult = result.ReturnValue.ToString());
}
#endregion
#region Server Called Functions
private void FromArbitraryCode(Hub hub, MethodCallMessage methodCall)
{
fromArbitraryCodeResult = methodCall.Arguments[0] as string;
}
private void GroupAdded(Hub hub, MethodCallMessage methodCall)
{
if (!string.IsNullOrEmpty(groupAddedResult))
groupAddedResult = "Group Already Added!";
else
groupAddedResult = "Group Added!";
}
private void Signal(Hub hub, MethodCallMessage methodCall)
{
dynamicTaskResult = string.Format("The dynamic task! {0}", methodCall.Arguments[0]);
}
private void Invoke(Hub hub, MethodCallMessage methodCall)
{
invokeResults.Add(string.Format("{0} client state index -> {1}", methodCall.Arguments[0], this.State["index"]));
}
#endregion
#region Draw
///
/// Display the result's of the function calls.
///
public void Draw()
{
GUILayout.Label("Arbitrary Code");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(string.Format("Sending {0} from arbitrary code without the hub itself!", fromArbitraryCodeResult));
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Group Added");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(groupAddedResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Dynamic Task");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(dynamicTaskResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Report Progress");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.BeginVertical();
GUILayout.Label(longRunningJobStatus);
GUILayout.HorizontalSlider(longRunningJobProgress, 0, 100);
GUILayout.EndVertical();
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Generic Task");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(genericTaskResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Task With Exception");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(taskWithExceptionResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Generic Task With Exception");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(genericTaskWithExceptionResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Synchronous Exception");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(synchronousExceptionResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Invoking hub method with dynamic");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(invokingHubMethodWithDynamicResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Simple Array");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(simpleArrayResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Complex Type");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(complexTypeResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Complex Array");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(complexArrayResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Overloads");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.BeginVertical();
GUILayout.Label(voidOverloadResult);
GUILayout.Label(intOverloadResult);
GUILayout.EndVertical();
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Read State Value");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(readStateResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Plain Task");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(plainTaskResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Generic Task With ContinueWith");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.Label(genericTaskWithContinueWithResult);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("Message Pump");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
invokeResults.Draw(Screen.width - 40, 270);
GUILayout.EndHorizontal();
GUILayout.Space(10);
}
#endregion
}
#endif