提交帧同步案例

This commit is contained in:
PC-20230316NUNE\Administrator
2024-01-26 19:15:07 +08:00
parent 3a345ab966
commit 68c4d5e811
3928 changed files with 463020 additions and 1 deletions

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9286baa677f488b4bb493dd5436147c6
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,135 @@
#if !BESTHTTP_DISABLE_SIGNALR
#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using BestHTTP.Cookies;
using BestHTTP.SignalR.Transports;
namespace BestHTTP.SignalR.Authentication
{
public sealed class SampleCookieAuthentication : IAuthenticationProvider
{
#region Public Properties
public Uri AuthUri { get; private set; }
public string UserName { get; private set; }
public string Password { get; private set; }
public string UserRoles { get; private set; }
#endregion
#region IAuthenticationProvider properties
public bool IsPreAuthRequired { get; private set; }
public event OnAuthenticationSuccededDelegate OnAuthenticationSucceded;
public event OnAuthenticationFailedDelegate OnAuthenticationFailed;
#endregion
#region Privates
private HTTPRequest AuthRequest;
private Cookie Cookie;
#endregion
public SampleCookieAuthentication(Uri authUri, string user, string passwd, string roles)
{
this.AuthUri = authUri;
this.UserName = user;
this.Password = passwd;
this.UserRoles = roles;
this.IsPreAuthRequired = true;
}
#region IAuthenticationProvider Implementation
public void StartAuthentication()
{
AuthRequest = new HTTPRequest(AuthUri, HTTPMethods.Post, OnAuthRequestFinished);
// Setup the form
AuthRequest.AddField("userName", UserName);
AuthRequest.AddField("Password", Password); // not used in the sample
AuthRequest.AddField("roles", UserRoles);
AuthRequest.Send();
}
public void PrepareRequest(HTTPRequest request, RequestTypes type)
{
// Adding the cookie to the request is not required, as it's managed by the plugin automatically,
// but for now, we want to be really sure that it's added
request.Cookies.Add(Cookie);
}
#endregion
#region Request Handler
void OnAuthRequestFinished(HTTPRequest req, HTTPResponse resp)
{
AuthRequest = null;
string failReason = string.Empty;
switch (req.State)
{
// The request finished without any problem.
case HTTPRequestStates.Finished:
if (resp.IsSuccess)
{
Cookie = resp.Cookies != null ? resp.Cookies.Find(c => c.Name.Equals(".ASPXAUTH")) : null;
if (Cookie != null)
{
HTTPManager.Logger.Information("CookieAuthentication", "Auth. Cookie found!");
if (OnAuthenticationSucceded != null)
OnAuthenticationSucceded(this);
// return now, all other paths are authentication failures
return;
}
else
HTTPManager.Logger.Warning("CookieAuthentication", failReason = "Auth. Cookie NOT found!");
}
else
HTTPManager.Logger.Warning("CookieAuthentication", failReason = string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
resp.StatusCode,
resp.Message,
resp.DataAsText));
break;
// The request finished with an unexpected error. The request's Exception property may contain more info about the error.
case HTTPRequestStates.Error:
HTTPManager.Logger.Warning("CookieAuthentication", failReason = "Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
break;
// The request aborted, initiated by the user.
case HTTPRequestStates.Aborted:
HTTPManager.Logger.Warning("CookieAuthentication", failReason = "Request Aborted!");
break;
// Connecting to the server is timed out.
case HTTPRequestStates.ConnectionTimedOut:
HTTPManager.Logger.Error("CookieAuthentication", failReason = "Connection Timed Out!");
break;
// The request didn't finished in the given time.
case HTTPRequestStates.TimedOut:
HTTPManager.Logger.Error("CookieAuthentication", failReason = "Processing the request Timed Out!");
break;
}
if (OnAuthenticationFailed != null)
OnAuthenticationFailed(this, failReason);
}
#endregion
}
}
#endif
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 48a74a50eeb07bb4ea649a902e9d487a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,97 @@
#if !BESTHTTP_DISABLE_SIGNALR
namespace BestHTTP.SignalR.Authentication
{
/// <summary>
/// Custom http-header based authenticator.
/// <example>
/// <code>
/// // Server side implementation of the Header-based authenticator
/// // Use it by adding the app.Use(typeof(HeaderBasedAuthenticationMiddleware)); line to the Startup class' Configuration function.
/// private class HeaderBasedAuthenticationMiddleware : OwinMiddleware
/// {
/// public HeaderBasedAuthenticationMiddleware(OwinMiddleware next)
/// : base(next)
/// {
/// }
///
/// public override Task Invoke(IOwinContext context)
/// {
/// string username = context.Request.Headers.Get("username");
/// string roles = context.Request.Headers.Get("roles");
///
/// if (!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(roles))
/// {
/// var identity = new System.Security.Principal.GenericIdentity(username);
///
/// var principal = new System.Security.Principal.GenericPrincipal(identity, SplitString(roles));
///
/// context.Request.User = principal;
/// }
///
/// return Next.Invoke(context);
/// }
///
/// private static string[] SplitString(string original)
/// {
/// if (String.IsNullOrEmpty(original))
/// return new string[0];
///
/// var split = from piece in original.Split(',') let trimmed = piece.Trim() where !String.IsNullOrEmpty(trimmed) select trimmed;
///
/// return split.ToArray();
/// }
/// }
/// </code>
/// </example>
/// </summary>
class HeaderAuthenticator : IAuthenticationProvider
{
public string User { get; private set; }
public string Roles { get; private set; }
/// <summary>
/// No pre-auth step required for this type of authentication
/// </summary>
public bool IsPreAuthRequired { get { return false; } }
#pragma warning disable 0067
/// <summary>
/// Not used event as IsPreAuthRequired is false
/// </summary>
public event OnAuthenticationSuccededDelegate OnAuthenticationSucceded;
/// <summary>
/// Not used event as IsPreAuthRequired is false
/// </summary>
public event OnAuthenticationFailedDelegate OnAuthenticationFailed;
#pragma warning restore 0067
/// <summary>
/// Constructor to initialise the authenticator with username and roles.
/// </summary>
public HeaderAuthenticator(string user, string roles)
{
this.User = user;
this.Roles = roles;
}
/// <summary>
/// Not used as IsPreAuthRequired is false
/// </summary>
public void StartAuthentication()
{ }
/// <summary>
/// Prepares the request by adding two headers to it
/// </summary>
public void PrepareRequest(BestHTTP.HTTPRequest request, RequestTypes type)
{
request.SetHeader("username", this.User);
request.SetHeader("roles", this.Roles);
}
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 5ebd4ce02d369a6498f9be6bb7141ac3
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,210 @@
#if !BESTHTTP_DISABLE_SIGNALR
using System;
using System.Collections.Generic;
using UnityEngine;
using BestHTTP.SignalR;
using BestHTTP.SignalR.Hubs;
using BestHTTP.SignalR.Messages;
using BestHTTP.SignalR.Authentication;
namespace BestHTTP.Examples
{
public class AuthenticationSample : MonoBehaviour
{
readonly Uri URI = new Uri(GUIHelper.BaseURL + "/signalr");
#region Private Fields
/// <summary>
/// Reference to the SignalR Connection
/// </summary>
Connection signalRConnection;
string userName = string.Empty;
string role = string.Empty;
Vector2 scrollPos;
#endregion
#region Unity Events
void Start()
{
// Create the SignalR connection, and pass the hubs that we want to connect to
signalRConnection = new Connection(URI, new BaseHub("noauthhub", "Messages"),
new BaseHub("invokeauthhub", "Messages Invoked By Admin or Invoker"),
new BaseHub("authhub", "Messages Requiring Authentication to Send or Receive"),
new BaseHub("inheritauthhub", "Messages Requiring Authentication to Send or Receive Because of Inheritance"),
new BaseHub("incomingauthhub", "Messages Requiring Authentication to Send"),
new BaseHub("adminauthhub", "Messages Requiring Admin Membership to Send or Receive"),
new BaseHub("userandroleauthhub", "Messages Requiring Name to be \"User\" and Role to be \"Admin\" to Send or Receive"));
// Set the authenticator if we have valid fields
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(role))
signalRConnection.AuthenticationProvider = new HeaderAuthenticator(userName, role);
// Set up event handler
signalRConnection.OnConnected += signalRConnection_OnConnected;
// Start to connect to the server.
signalRConnection.Open();
}
void OnDestroy()
{
// Close the connection when we are closing the sample
signalRConnection.Close();
}
void OnGUI()
{
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
scrollPos = GUILayout.BeginScrollView(scrollPos, false, false);
GUILayout.BeginVertical();
if (signalRConnection.AuthenticationProvider == null)
{
GUILayout.BeginHorizontal();
GUILayout.Label("Username (Enter 'User'):");
userName = GUILayout.TextField(userName, GUILayout.MinWidth(100));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Roles (Enter 'Invoker' or 'Admin'):");
role = GUILayout.TextField(role, GUILayout.MinWidth(100));
GUILayout.EndHorizontal();
if (GUILayout.Button("Log in"))
Restart();
}
for (int i = 0; i < signalRConnection.Hubs.Length; ++i)
(signalRConnection.Hubs[i] as BaseHub).Draw();
GUILayout.EndVertical();
GUILayout.EndScrollView();
});
}
#endregion
/// <summary>
/// Called when we successfully connected to the server.
/// </summary>
void signalRConnection_OnConnected(Connection manager)
{
// call 'InvokedFromClient' on all hubs
for (int i = 0; i < signalRConnection.Hubs.Length; ++i)
(signalRConnection.Hubs[i] as BaseHub).InvokedFromClient();
}
/// <summary>
/// Helper function to do a hard-restart to the server.
/// </summary>
void Restart()
{
// Clean up
signalRConnection.OnConnected -= signalRConnection_OnConnected;
// Close current connection
signalRConnection.Close();
signalRConnection = null;
// start again, with authentication if we filled in all input fields
Start();
}
}
/// <summary>
/// Hub implementation for the authentication demo. All hubs that we connect to has the same server and client side functions.
/// </summary>
class BaseHub : Hub
{
#region Private Fields
/// <summary>
/// Hub specific title
/// </summary>
private string Title;
private GUIMessageList messages = new GUIMessageList();
#endregion
public BaseHub(string name, string title)
: base(name)
{
this.Title = title;
// Map the server-callable method names to the real functions.
On("joined", Joined);
On("rejoined", Rejoined);
On("left", Left);
On("invoked", Invoked);
}
#region Server Called Functions
private void Joined(Hub hub, MethodCallMessage methodCall)
{
Dictionary<string, object> AuthInfo = methodCall.Arguments[2] as Dictionary<string, object>;
messages.Add(string.Format("{0} joined at {1}\n\tIsAuthenticated: {2} IsAdmin: {3} UserName: {4}", methodCall.Arguments[0], methodCall.Arguments[1], AuthInfo["IsAuthenticated"], AuthInfo["IsAdmin"], AuthInfo["UserName"]));
}
private void Rejoined(Hub hub, MethodCallMessage methodCall)
{
messages.Add(string.Format("{0} reconnected at {1}", methodCall.Arguments[0], methodCall.Arguments[1]));
}
private void Left(Hub hub, MethodCallMessage methodCall)
{
messages.Add(string.Format("{0} left at {1}", methodCall.Arguments[0], methodCall.Arguments[1]));
}
private void Invoked(Hub hub, MethodCallMessage methodCall)
{
messages.Add(string.Format("{0} invoked hub method at {1}", methodCall.Arguments[0], methodCall.Arguments[1]));
}
#endregion
#region Client callable function implementation
public void InvokedFromClient()
{
base.Call("invokedFromClient", OnInvoked, OnInvokeFailed);
}
private void OnInvoked(Hub hub, ClientMessage originalMessage, ResultMessage result)
{
Debug.Log(hub.Name + " invokedFromClient success!");
}
/// <summary>
/// This callback function will be called every time we try to access a protected API while we are using an non-authenticated connection.
/// </summary>
private void OnInvokeFailed(Hub hub, ClientMessage originalMessage, FailureMessage result)
{
Debug.LogWarning(hub.Name + " " + result.ErrorMessage);
}
#endregion
public void Draw()
{
GUILayout.Label(this.Title);
GUILayout.BeginHorizontal();
GUILayout.Space(20);
messages.Draw(Screen.width - 20, 100);
GUILayout.EndHorizontal();
}
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 02921d1602244e44cbd5103f972bf1fb
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,275 @@
#if !BESTHTTP_DISABLE_SIGNALR
using System;
using UnityEngine;
using BestHTTP.SignalR;
#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR)
using BestHTTP.Cookies;
#endif
namespace BestHTTP.Examples
{
public sealed class ConnectionAPISample : MonoBehaviour
{
readonly Uri URI = new Uri(GUIHelper.BaseURL + "/raw-connection/");
/// <summary>
/// Possible message types that the client can send to the server
/// </summary>
enum MessageTypes
{
Send, // 0
Broadcast, // 1
Join, // 2
PrivateMessage, // 3
AddToGroup, // 4
RemoveFromGroup, // 5
SendToGroup, // 6
BroadcastExceptMe, // 7
}
#region Private Fields
/// <summary>
/// Reference to the SignalR Connection
/// </summary>
Connection signalRConnection;
// Input strings
string ToEveryBodyText = string.Empty;
string ToMeText = string.Empty;
string PrivateMessageText = string.Empty;
string PrivateMessageUserOrGroupName = string.Empty;
GUIMessageList messages = new GUIMessageList();
#endregion
#region Unity Events
void Start()
{
#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR)
// Set a "user" cookie if we previously used the 'Enter Name' button.
// The server will set this username to the new connection.
if (PlayerPrefs.HasKey("userName"))
CookieJar.Set(URI, new Cookie("user", PlayerPrefs.GetString("userName")));
#endif
signalRConnection = new Connection(URI);
// to serialize the Message class, set a more advanced json encoder
signalRConnection.JsonEncoder = new BestHTTP.SignalR.JsonEncoders.LitJsonEncoder();
// set up event handlers
signalRConnection.OnStateChanged += signalRConnection_OnStateChanged;
signalRConnection.OnNonHubMessage += signalRConnection_OnGeneralMessage;
// Start to connect to the server.
signalRConnection.Open();
}
/// <summary>
/// Draw the gui.
/// Get input strings.
/// Handle function calls.
/// </summary>
void OnGUI()
{
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
GUILayout.BeginVertical();
#region To Everybody
GUILayout.Label("To Everybody");
GUILayout.BeginHorizontal();
ToEveryBodyText = GUILayout.TextField(ToEveryBodyText, GUILayout.MinWidth(100));
if (GUILayout.Button("Broadcast"))
Broadcast(ToEveryBodyText);
if (GUILayout.Button("Broadcast (All Except Me)"))
BroadcastExceptMe(ToEveryBodyText);
if (GUILayout.Button("Enter Name"))
EnterName(ToEveryBodyText);
if (GUILayout.Button("Join Group"))
JoinGroup(ToEveryBodyText);
if (GUILayout.Button("Leave Group"))
LeaveGroup(ToEveryBodyText);
GUILayout.EndHorizontal();
#endregion
#region To Me
GUILayout.Label("To Me");
GUILayout.BeginHorizontal();
ToMeText = GUILayout.TextField(ToMeText, GUILayout.MinWidth(100));
if (GUILayout.Button("Send to me"))
SendToMe(ToMeText);
GUILayout.EndHorizontal();
#endregion
#region Private Message
GUILayout.Label("Private Message");
GUILayout.BeginHorizontal();
GUILayout.Label("Message:");
PrivateMessageText = GUILayout.TextField(PrivateMessageText, GUILayout.MinWidth(100));
GUILayout.Label("User or Group name:");
PrivateMessageUserOrGroupName = GUILayout.TextField(PrivateMessageUserOrGroupName, GUILayout.MinWidth(100));
if (GUILayout.Button("Send to user"))
SendToUser(PrivateMessageUserOrGroupName, PrivateMessageText);
if (GUILayout.Button("Send to group"))
SendToGroup(PrivateMessageUserOrGroupName, PrivateMessageText);
GUILayout.EndHorizontal();
#endregion
GUILayout.Space(20);
if (signalRConnection.State == ConnectionStates.Closed)
{
if (GUILayout.Button("Start Connection"))
signalRConnection.Open();
}
else if (GUILayout.Button("Stop Connection"))
signalRConnection.Close();
GUILayout.Space(20);
// Draw the messages
GUILayout.Label("Messages");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
messages.Draw(Screen.width - 20, 0);
GUILayout.EndHorizontal();
GUILayout.EndVertical();
});
}
void OnDestroy()
{
// Close the connection when the sample is closed
signalRConnection.Close();
}
#endregion
#region SignalR Events
/// <summary>
/// Handle non-hub messages
/// </summary>
void signalRConnection_OnGeneralMessage(Connection manager, object data)
{
// For now, just create a Json string from the sent data again
string reencoded = BestHTTP.JSON.Json.Encode(data);
// and display it
messages.Add("[Server Message] " + reencoded);
}
void signalRConnection_OnStateChanged(Connection manager, ConnectionStates oldState, ConnectionStates newState)
{
// display state changes
messages.Add(string.Format("[State Change] {0} => {1}", oldState.ToString(), newState.ToString()));
}
#endregion
#region To EveryBody Functions
/// <summary>
/// Broadcast a message to all connected clients
/// </summary>
private void Broadcast(string text)
{
signalRConnection.Send(new { Type = MessageTypes.Broadcast, Value = text });
}
/// <summary>
/// Broadcast a message to all connected clients, except this client
/// </summary>
private void BroadcastExceptMe(string text)
{
signalRConnection.Send(new { Type = MessageTypes.BroadcastExceptMe, Value = text });
}
/// <summary>
/// Set a name for this connection.
/// </summary>
private void EnterName(string name)
{
signalRConnection.Send(new { Type = MessageTypes.Join, Value = name });
}
/// <summary>
/// Join to a group
/// </summary>
private void JoinGroup(string groupName)
{
signalRConnection.Send(new { Type = MessageTypes.AddToGroup, Value = groupName });
}
/// <summary>
/// Leave a group
/// </summary>
private void LeaveGroup(string groupName)
{
signalRConnection.Send(new { Type = MessageTypes.RemoveFromGroup, Value = groupName });
}
#endregion
#region To Me Functions
/// <summary>
/// Send a message to the very same client through the server
/// </summary>
void SendToMe(string text)
{
signalRConnection.Send(new { Type = MessageTypes.Send, Value = text });
}
#endregion
#region Private Message Functions
/// <summary>
/// Send a private message to a user
/// </summary>
void SendToUser(string userOrGroupName, string text)
{
signalRConnection.Send(new { Type = MessageTypes.PrivateMessage, Value = string.Format("{0}|{1}", userOrGroupName, text) });
}
/// <summary>
/// Send a message to a group
/// </summary>
void SendToGroup(string userOrGroupName, string text)
{
signalRConnection.Send(new { Type = MessageTypes.SendToGroup, Value = string.Format("{0}|{1}", userOrGroupName, text) });
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 872d6dfdac0e67f4d910376205532bc0
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,141 @@
#if !BESTHTTP_DISABLE_SIGNALR
using System;
using UnityEngine;
using BestHTTP.SignalR;
using BestHTTP.SignalR.Hubs;
namespace BestHTTP.Examples
{
public sealed class ConnectionStatusSample : MonoBehaviour
{
readonly Uri URI = new Uri(GUIHelper.BaseURL + "/signalr");
/// <summary>
/// Reference to the SignalR Connection
/// </summary>
Connection signalRConnection;
GUIMessageList messages = new GUIMessageList();
#region Unity Events
void Start()
{
// Connect to the StatusHub hub
signalRConnection = new Connection(URI, "StatusHub");
// General events
signalRConnection.OnNonHubMessage += signalRConnection_OnNonHubMessage;
signalRConnection.OnError += signalRConnection_OnError;
signalRConnection.OnStateChanged += signalRConnection_OnStateChanged;
// Set up a callback for Hub events
signalRConnection["StatusHub"].OnMethodCall += statusHub_OnMethodCall;
// Connect to the server
signalRConnection.Open();
}
void OnDestroy()
{
// Close the connection when we are closing the sample
signalRConnection.Close();
}
void OnGUI()
{
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
GUILayout.BeginHorizontal();
if (GUILayout.Button("START") && signalRConnection.State != ConnectionStates.Connected)
signalRConnection.Open();
if (GUILayout.Button("STOP") && signalRConnection.State == ConnectionStates.Connected)
{
signalRConnection.Close();
messages.Clear();
}
if (GUILayout.Button("PING") && signalRConnection.State == ConnectionStates.Connected)
{
// Call a Hub-method on the server.
signalRConnection["StatusHub"].Call("Ping");
}
GUILayout.EndHorizontal();
GUILayout.Space(20);
GUILayout.Label("Connection Status Messages");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
messages.Draw(Screen.width - 20, 0);
GUILayout.EndHorizontal();
});
}
#endregion
#region SignalR Events
/// <summary>
/// Called on server-sent non-hub messages.
/// </summary>
void signalRConnection_OnNonHubMessage(Connection manager, object data)
{
messages.Add("[Server Message] " + data.ToString());
}
/// <summary>
/// Called when the SignalR Connection's state changes.
/// </summary>
void signalRConnection_OnStateChanged(Connection manager, ConnectionStates oldState, ConnectionStates newState)
{
messages.Add(string.Format("[State Change] {0} => {1}", oldState, newState));
}
/// <summary>
/// Called when an error occures. The plugin may close the connection after this event.
/// </summary>
void signalRConnection_OnError(Connection manager, string error)
{
messages.Add("[Error] " + error);
}
/// <summary>
/// Called when the "StatusHub" hub wants to call a method on this client.
/// </summary>
void statusHub_OnMethodCall(Hub hub, string method, params object[] args)
{
string id = args.Length > 0 ? args[0] as string : string.Empty;
string when = args.Length > 1 ? args[1].ToString() : string.Empty;
switch (method)
{
case "joined":
messages.Add(string.Format("[{0}] {1} joined at {2}", hub.Name, id, when));
break;
case "rejoined":
messages.Add(string.Format("[{0}] {1} reconnected at {2}", hub.Name, id, when));
break;
case "leave":
messages.Add(string.Format("[{0}] {1} leaved at {2}", hub.Name, id, when));
break;
default: // pong
messages.Add(string.Format("[{0}] {1}", hub.Name, method));
break;
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 0d5b759afc726754fb1e1d49d529bae5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,557 @@
#if !BESTHTTP_DISABLE_SIGNALR
using System;
using UnityEngine;
using BestHTTP.SignalR;
using BestHTTP.SignalR.Hubs;
using BestHTTP.SignalR.Messages;
using BestHTTP.SignalR.JsonEncoders;
namespace BestHTTP.Examples
{
public sealed class DemoHubSample : MonoBehaviour
{
readonly Uri URI = new Uri(GUIHelper.BaseURL + "/signalr");
/// <summary>
/// The SignalR connection instance
/// </summary>
Connection signalRConnection;
/// <summary>
/// DemoHub client side implementation
/// </summary>
DemoHub demoHub;
/// <summary>
/// TypedDemoHub client side implementation
/// </summary>
TypedDemoHub typedDemoHub;
/// <summary>
/// VB .NET Hub
/// </summary>
Hub vbDemoHub;
/// <summary>
/// Result of the VB demo's ReadStateValue call
/// </summary>
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();
});
}
}
/// <summary>
/// Wrapper class of the 'TypedDemoHub' hub
/// </summary>
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
/// <summary>
/// Server-called, client side implementation of the Echo function
/// </summary>
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)
/// <summary>
/// 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.
/// </summary>
public void Echo(string msg)
{
base.Call("echo", OnEcho_Done, msg);
}
/// <summary>
/// When the function successfully executed on the server this callback function will be called.
/// </summary>
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);
}
}
/// <summary>
/// A wrapper class for the 'DemoHub' hub.
/// </summary>
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
/// <summary>
/// Display the result's of the function calls.
/// </summary>
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

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 55779d2699b42c34ab1549c70402d294
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1c996438e0be72649b8abf5fbdee3f41
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
#if !BESTHTTP_DISABLE_SIGNALR && BESTHTTP_SIGNALR_WITH_JSONDOTNET
using System.Collections.Generic;
using Newtonsoft.Json;
namespace BestHTTP.SignalR.JsonEncoders
{
public sealed class JSonDotnetEncoder : IJsonEncoder
{
public string Encode(object obj)
{
return JsonConvert.SerializeObject(obj);
}
public IDictionary<string, object> DecodeMessage(string json)
{
return JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
}
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 653a0f163689052438748b7beda14886
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
#if !BESTHTTP_DISABLE_SIGNALR
using System.Collections.Generic;
using LitJson;
namespace BestHTTP.SignalR.JsonEncoders
{
public sealed class LitJsonEncoder : IJsonEncoder
{
public string Encode(object obj)
{
JsonWriter writer = new JsonWriter();
JsonMapper.ToJson(obj, writer);
return writer.ToString();
}
public IDictionary<string, object> DecodeMessage(string json)
{
JsonReader reader = new JsonReader(json);
return JsonMapper.ToObject<Dictionary<string, object>>(reader);
}
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 2870a746a601b8b439c495ff39474385
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,91 @@
#if !BESTHTTP_DISABLE_SIGNALR
using System;
using UnityEngine;
using BestHTTP.SignalR;
namespace BestHTTP.Examples
{
public sealed class SimpleStreamingSample : MonoBehaviour
{
readonly Uri URI = new Uri(GUIHelper.BaseURL + "/streaming-connection");
/// <summary>
/// Reference to the SignalR Connection
/// </summary>
Connection signalRConnection;
/// <summary>
/// Helper GUI class to handle and display a string-list
/// </summary>
GUIMessageList messages = new GUIMessageList();
#region Unity Events
void Start()
{
// Create the SignalR connection
signalRConnection = new Connection(URI);
// set event handlers
signalRConnection.OnNonHubMessage += signalRConnection_OnNonHubMessage;
signalRConnection.OnStateChanged += signalRConnection_OnStateChanged;
signalRConnection.OnError += signalRConnection_OnError;
// Start connecting to the server
signalRConnection.Open();
}
void OnDestroy()
{
// Close the connection when the sample is closed
signalRConnection.Close();
}
void OnGUI()
{
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
GUILayout.Label("Messages");
GUILayout.BeginHorizontal();
GUILayout.Space(20);
messages.Draw(Screen.width - 20, 0);
GUILayout.EndHorizontal();
});
}
#endregion
#region SignalR Events
/// <summary>
/// Handle Server-sent messages
/// </summary>
void signalRConnection_OnNonHubMessage(Connection connection, object data)
{
messages.Add("[Server Message] " + data.ToString());
}
/// <summary>
/// Display state changes
/// </summary>
void signalRConnection_OnStateChanged(Connection connection, ConnectionStates oldState, ConnectionStates newState)
{
messages.Add(string.Format("[State Change] {0} => {1}", oldState, newState));
}
/// <summary>
/// Display errors.
/// </summary>
void signalRConnection_OnError(Connection connection, string error)
{
messages.Add("[Error] " + error);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 0eb1f1efe4749fc489977765e40a04e4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: