How to connect to an Azure SignalR Service
Here's a sample implementation to connect to an Azure SignalR Serverice:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BestHTTP.SignalRCore;
using System;
using BestHTTP;
public class SignalRService : MonoBehaviour {
// Use this for initialization
void Start () {
var conn = new HubConnection(new Uri("http://localhost:5000/chat"), new JsonProtocol(new BestHTTP.SignalRCore.Encoders.LitJsonEncoder()));
conn.AuthenticationProvider = new AzureSignalRServiceAuthenticator(conn);
conn.OnConnected += OnConnected;
conn.On<string, string>("BroadcastMessage", OnBroadcastMessage);
conn.StartConnect();
}
private void OnBroadcastMessage(string name, string message)
{
Debug.LogFormat("[{0}]: {1}", name, message);
}
private void OnConnected(HubConnection hub)
{
hub.Send("BroadcastMessage", "Best HTTP Client", "Hello World!");
}
}
public sealed class AzureSignalRServiceAuthenticator : IAuthenticationProvider
{
/// <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
private HubConnection _connection;
public AzureSignalRServiceAuthenticator(HubConnection connection)
{
this._connection = connection;
}
/// <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)
{
if (this._connection.NegotiationResult == null)
return;
// Add Authorization header to http requests, add access_token param to the uri otherwise
if (BestHTTP.Connections.HTTPProtocolFactory.GetProtocolFromUri(request.CurrentUri) == BestHTTP.Connections.SupportedProtocols.HTTP)
request.SetHeader("Authorization", "Bearer " + this._connection.NegotiationResult.AccessToken);
else
request.Uri = PrepareUriImpl(request.Uri);
}
public Uri PrepareUri(Uri uri)
{
if (uri.Query.StartsWith("??"))
{
UriBuilder builder = new UriBuilder(uri);
builder.Query = builder.Query.Substring(2);
return builder.Uri;
}
return uri;
}
private Uri PrepareUriImpl(Uri uri)
{
string query = string.IsNullOrEmpty(uri.Query) ? "" : uri.Query + "&";
UriBuilder uriBuilder = new UriBuilder(uri.Scheme, uri.Host, uri.Port, uri.AbsolutePath, query + "access_token=" + this._connection.NegotiationResult.AccessToken);
return uriBuilder.Uri;
}
}
Warning
When used with Azure Functions Invoke and other client to server messaging can be done through Azure Functions (HTTP requests). See https://docs.microsoft.com/en-us/azure/azure-signalr/signalr-concept-serverless-development-config#sending-messages-from-a-client-to-the-service