An example of the implementation for the ADAL library for Windows Phone 8.1 can be found on GitHub
To display the Azure Login page for the user you call the AuthenticationContext.AcquireTokenAndContinue method. After the login process it should do a callback to the AuthenticationContextDelegate.
AuthenticationContext _authenticationContext = AuthenticationContext.CreateAsync(authority).GetResults();
_authenticationContext.AcquireTokenAndContinue(resource, clientId, redirectUri, authenticationContextDelegate);
AuthenticationContextDelegate authenticationContextDelegate= new AuthenticationContextDelegate(AuthContextDelegateMethod);
public static void AuthContextDelegateMethod(AuthenticationResult result)
{
// Never called
}
The AuthContextDelegateMethod is not getting called even after a successful login.
Is there any reason why the AuthenticationContextDelegate is not called, and any way to fix that?
I had this same issue with the ADAL library not working and not calling the AuthContextDelegateMethod
The firts thing was to understand how the AndContinue methods work, once you understand this the rest make a lot of sense.
App.xaml.cs
In your App.xaml.cs you need to add the OnActivate method which works with the ContinuationManager; this is where the app enters after the Azure login returns.
ContinuationManager _continuationManager;
protected override void OnActivated(IActivatedEventArgs e)
{
base.OnActivated(e);
_continuationManager = new ContinuationManager();
var continuationEventArgs = e as IContinuationActivatedEventArgs;
if (continuationEventArgs != null)
{
IWebAuthenticationContinuable azure = GetIWebAuthenticationContinuableInstance();
_continuationManager.Continue(continuationEventArgs, azure);
}
}
The GetIWebAuthenticationContinuableInstance should return the same instance of the IWebAuthenticationContinuable that called AuthenticationContext.AcquireTokenAndContinue; I had some issues when you try to give it a new instance (didn't work), in this answer it is called AzureLoginClass below.
ContinuationManager
Then in the ContinuationManager I added the following function (which is an adaptation of Continue(IContinuationActivatedEventArgs args, Frame rootFrame)):
internal void Continue(IContinuationActivatedEventArgs args, IWebAuthenticationContinuable wabPage)
{
if (args == null)
throw new ArgumentNullException("args");
if (this.args != null && !handled)
throw new InvalidOperationException("Can't set args more than once");
this.args = args;
this.handled = false;
this.id = Guid.NewGuid();
if (wabPage == null)
return;
switch (args.Kind)
{
case ActivationKind.PickFileContinuation:
break;
case ActivationKind.PickSaveFileContinuation:
break;
case ActivationKind.PickFolderContinuation:
break;
case ActivationKind.WebAuthenticationBrokerContinuation:
if (wabPage != null)
{
wabPage.ContinueWebAuthentication(args as WebAuthenticationBrokerContinuationEventArgs);
}
break;
}
}
I needed to do this because I implemented my IWebAuthenticationContinuable as part of a class and the given implementations give preference to an AppicationPage.
AzureLoginClass
Then in your implementation of IWebAuthenticationContinuable's ContinueWebAuthentication you need to call the ContinueAcquireTokenAsync
public class AzureLoginClass : IWebAuthenticationContinuable
{
public void CallAzureLogin
{
_authenticationContext.AcquireTokenAndContinue(resource, clientId, redirectUri, AuthContextDelegateMethod);
}
private void AuthContextDelegateMethod(AuthenticationResult result)
{
// Is now called when ContinueAcquireTokenAsync is called
}
public async void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args)
{
AuthenticationResult result = await _authenticationContext .ContinueAcquireTokenAsync(args);
}
}
When ContinueAcquireTokenAsync is called it gives a callback to AuthContextDelegateMethod. This is however not called if result.ErrorDescription is "User canceled authentication", so if you need this you should cater extra for it.
Related
I work on a Unity C# app with Firebase Auth and Firebase Functions SDK installed.
I have three callable functions I developed and tested thanks to the Firebase emulators and they seem to work correctly.
I deployed my functions, launched the game in Unity Editor and I get an error whenever I call a function. The error is always INTERNAL.
I checked the logs on Google Cloud dashboard and it seems my function doesn't even run.
I put a breakpoint and decide to inspect the exception to gather some information.
However, there isn't any useful information other than "One or more errors occurred" and "INTERNAL".
After numerous searches on Google/SO I've found two possible culprits :
Outdated SDK -> I redownload latest SDK and re-import Firebase Auth and Firebase Functions into my Unity project --> same error.
Need to specify region when getting the Functions instance if different than us-central1. According to the Google dashboard my functions are located in the us-central1 region but just in case I specify it anyway --> same error.
Then I notice that my actual Firebase project is in europe-west3 so I specify this in my code when getting the instance of Firebase Functions or App --> still the same error.
Now I'm starting to doubt everything so I comment out UseFunctionsEmulator() and test again with the emulators -> it works fine.
What could be the problem?
Here is my FirebaseManager.cs that run before anything else:
public class FirebaseManager : MonoBehaviour
{
private static bool gameQuitting = false;
private static readonly object Lock = new object();
private static FirebaseManager _instance;
public static FirebaseManager Instance
{
get
{
// [check if instance exists etc..]
}
}
private FirebaseApp _app;
private FirebaseAuth _auth;
public FirebaseAuth Auth
{
get
{
if (_auth == null)
{
_auth = FirebaseAuth.GetAuth(_app);
}
return _auth;
}
}
private FirebaseUser _user;
public FirebaseUser User
{
get
{
return _user;
}
set
{
_user = value;
}
}
private FirebaseFunctions _func;
public FirebaseFunctions Func
{
get
{
if (_func == null)
{
_func = FirebaseFunctions.DefaultInstance;
}
return _func;
}
}
// Events to subscribe to for this service
public delegate void FirebaseInitialized();
public static event FirebaseInitialized OnFirebaseInitialized;
public static bool IsInitialized = false;
private void Awake()
{
if (_instance == null)
{
DontDestroyOnLoad(this.gameObject);
_instance = this;
}
else { Destroy(this.gameObject); }
}
private void Start()
{
InitializeFirebase();
}
private void InitializeFirebase()
{
Debug.Log($"FirebaseManager.cs > INITIALIZING FIREBASE");
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
{
var dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
// Create and hold a reference to your FirebaseApp,
// where app is a Firebase.FirebaseApp property of your application class.
_app = FirebaseApp.DefaultInstance;
// _app = FirebaseApp.GetInstance("europe-west3");
// Create and hold a reference to FirebaseAuth
_auth = FirebaseAuth.DefaultInstance;
// Create and hold a reference to already logged in user (if any)
_user = _auth.CurrentUser;
// Create and hold a reference to Functions
_func = FirebaseFunctions.DefaultInstance;
// _func = FirebaseFunctions.GetInstance(FirebaseApp.DefaultInstance, "europe-west3");
// _func = FirebaseFunctions.GetInstance("europe-west3");
// #if UNITY_EDITOR
// _func.UseFunctionsEmulator("http://localhost:5001"); // LOCAL FUNCS
// #endif
// Subscribing to AuthStateChanged
FirebaseManager.Instance.Auth.StateChanged += AuthService.AuthStateChanged;
Debug.Log($"FirebaseManager.cs > INITIALIZED");
IsInitialized = true;
if (OnFirebaseInitialized != null) OnFirebaseInitialized.Invoke();
}
else
{
UnityEngine.Debug.LogError(System.String.Format(
"FirebaseManager.cs > Could not resolve all Firebase dependencies: {0}", dependencyStatus));
// Firebase Unity SDK is not safe to use here.
}
});
}
private void OnDestroy()
{
if (_auth != null) _auth = null;
}
private void OnApplicationQuit()
{
FirebaseManager.Instance.Auth.StateChanged -= AuthService.AuthStateChanged;
gameQuitting = true;
}
}
I call my function from Unity like this :
HttpsCallableReference function = FirebaseManager.Instance.Func.GetHttpsCallable("GetAllCharacters");
// Call the function and extract the operation from the result.
function.CallAsync().ContinueWithOnMainThread((task) =>
{
if (task.IsFaulted)
{
// this foreach is a debug attempt
foreach (var e in task.Exception.Flatten().InnerExceptions)
{
Debug.LogWarning($"Received Exception: {e.Message}");
}
foreach (var inner in task.Exception.InnerExceptions)
{
if (inner is FunctionsException)
{
var e = (FunctionsException)inner;
// Function error code, will be INTERNAL if the failure
// was not handled properly in the function call.
var code = e.ErrorCode;
var message = e.Message;
Debug.LogError($"Code: {code} // Message: {message}");
// [Handle error]
}
}
}
else
{
// [Handle data returned by the function]
}
});
Finally, my Firebase Functions look like this: (index.ts)
import * as Characters from "./Characters/Characters";
// CHARACTERS
export const CreateNewCharacter = Characters.CreateNewCharacter;
export const GetAllCharacters = Characters.GetAllCharacters;
export const DeleteCharacterByID = Characters.DeleteCharacterByID;
Characters.ts:
import * as functions from "firebase-functions";
import { initializeApp } from "firebase-admin/app";
// [custom classes imports]
// DATABASE INITIALIZATION
initializeApp();
const db = getFirestore();
// CREATE NEW CHARACTER
export const CreateNewCharacter =
functions.https.onCall(async (data, context) =>
{
...
});
// GET ALL CHARACTERS
export const GetAllCharacters =
functions.https.onCall(async (data, context) =>
{
...
});
// DELETE CHARACTER BY ID
export const DeleteCharacterByID =
functions.https.onCall(async (data, context) =>
{
...
});
In step-by-step debugging, here is what I find:
The StackTrace value is :
" at Firebase.Functions.HttpsCallableReference.b__9_0 (System.Threading.Tasks.Task'1[TResult] task) [0x00063] in <9b40ff23f61a4fcf97a5710997860279>:0 \n at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2[TAntecedentResult,TResult].InnerInvoke () [0x00024] in <4ba27aa039714eafa1e8892e51af2932>:0 \n at System.Threading.Tasks.Task.Execute () [0x00000] in <4ba27aa039714eafa1e8892e51af2932>:0 "
I am working on the migration from SQLite/WebApis to Realms in an App in Xamarin Forms.
This application manages a messaging service (Chat through SignalR).
The problem that has arisen is when a message is received, which I try to store in a database, the application crashes unexpectedly. (Question that did not happen with SQLite).
I am getting the famous error: realm accessed from incorrect, exactly when the 3rd or 4th message is trying to insert, it has been a bit difficult to see the precise moment.
As I could read, both in questions right here on Stackoverflow, and on the Dot-Net Realm GitHub. the instance must be accessed in the same thread that it was created.
As they suggest, one way to achieve this is by using the correct SynchronizationContext through AsyncContext.Run Nito.AsyncEx by Stephen Cleary or Device.BeginInvokeOnMainThread.
I ask the question because unfortunately, I handle the subject of threads and tasks at a basic level, in what way do I have to approach the previous suggestions to my code? or what should I set correctly to access the thread in which it was created?
This is my code:
LobbyViewModel
public LobbyViewModel()
{
ChatService.OnReceivePrivateMessage += ChatService_OnReceivePrivateMessage;
}
private async void ChatService_OnReceivePrivateMessage(object sender, MessageEventArgs args)
{
await SendMessage(…);
}
private async Task SendMessage(…)
{
await UpdateMetaData(…);
}
public async Task UpdateMetaData(…)
{
await ManagerService.InsertMetaDataChatAsync(metaDataChat);
}
ManagerService
public async Task InsertMetaDataChatAsync (MetaDataChatModel MetaDataChatModel)
{
IMetaDataChatServices MetaDataChatServices = App.AppContainer.Resolve<IMetaDataChatServices>();
IResponse DataResult = (await MetaDataChatServices.Insert(MetaDataChatModel));
}
Repository
public async Task<IResponse> CreateAsync(MetaDataChatModel MetaDataChatModel)
{
MetaDataChatModel.Id = Guid.NewGuid().ToString();
MetaDataChatModel.Partition = _realmManager.projectPartition;
var MetaDataChatDto = MetaDataChatModel.ToDto();
var realmInstance = await _realmManager.GetInstanceAsync();
if (realmInstance == null)
return new Response(false, "Realm instance can't be null");
await realmInstance.WriteAsync(realm =>
{
realm.Add(MetaDataChatDto, false);
});
return new Response(true);
}
RealmManager
public RealmManager()
{
RealmApp = App.Create(appId);
//DataBase = Realms.Realm.GetInstance(syncConfig);
}
public Task<Realms.Realm> GetInstanceAsync()
{
return Realms.Realm.GetInstanceAsync(syncConfig);
}
public async Task RealmLogInAsync()
{
if (RealmApp.CurrentUser == null)
{
User user = await RealmApp.
LogInAsync(Credentials.EmailPassword("email", "password"));
if (user == null)
{
return;
}
}
projectPartition = $"project={RealmApp.CurrentUser.Id}";
syncConfig = new SyncConfiguration(projectPartition, RealmApp.CurrentUser);
}
public async Task RealmLogOutAsync()
{
if (RealmApp != null && RealmApp.CurrentUser!=null)
{
await RealmApp.CurrentUser?.LogOutAsync();
}
}
I have to perform Auth0 authentication process and extract the token.
I have Authenticator class as below -
class Auth0Authenticator
{
public Auth0Authenticator() { performAuthentication(); }
public void performAuthentication()
{
Auth0Client auth0Client = new Auth0Client(new Auth0ClientOptions()
{
Domain = "mydomain",
ClientId = "clientid",
});
var extraParameters = new Dictionary<string, string>();
extraParameters.Add("connection", "parameter");
var result = auth0Client.LoginAsync(extraParameters: extraParameters);
}
}
while executing LoginAsync I am getting error - The calling thread must be STA, because many UI components require this.
even after creating STA thread or adding attribute [STAThread] not helping.
When i executed the same code in a simple dialog based application, code is successufully returning me the token. but putting the same code in my project(consists of MFC/C#/CLI) throwing error.
Can anyone help please?
This may be an XY problem. Auth0Client.LoginAsync is an async API and you are trying to invoke it in the constructor of your class. This can have negative consequences if there is code dependent on that function completing before being able to perform their functions.
Refactor the code to follow suggested syntax
public class Auth0Authenticator {
public Auth0Authenticator() {
//Subscribe to the event
autoAuthenticate += onAutoAuthenticating();
//raise event to allow async operation.
autoAuthenticate(this, EventArgs.Empty);
}
private event EventHandler autoAuthenticate = delegate { };
private async void onAutoAuthenticating(object sender, EventArgs args) {
await PerformAuthenticationAsync();
}
public async Task PerformAuthenticationAsync() {
Auth0Client auth0Client = new Auth0Client(new Auth0ClientOptions() {
Domain = "mydomain",
ClientId = "clientid",
});
var extraParameters = new Dictionary<string, string>();
extraParameters.Add("connection", "parameter");
var result = await auth0Client.LoginAsync(extraParameters: extraParameters);
//...do something with the result as needed
string access_token = result.AccessToken;
string refresh_token = result.RefreshToken;
//...
}
}
I'm facing difficulties understanding how to handle program control during asynchronous flow.
I have a SessionManager class which calls the initiates the session and we need to register
for the event OnStartApplicationSessionResponse and my control will return to the calling point. I will get the session id in the eventhandler after sometime or the error code if there is an error.
class SessionManager
{
public bool startUp(Object params)
{
try
{
serviceProvider = new ServiceProvider();
serviceProvider.OnStartApplicationSessionResponse += new StartApplicationSessionResponseHandler(ServiceProvider_OnStartApplicationSessionResponse);
serviceProvider.startUp(params);
}
}
public void ServiceProvider_OnStartApplicationSessionResponse(object sender, ServiceProvider.StartApplicationSessionResponseArgs e)
{
//e.getError
//I will get the session Id here or error code
}
}
How do I get sessionId or the error as my control is now at the calling position?
You could use TaskCompletionSource to make the Event awaitable.
class SessionManager
{
private ServiceProvider _serviceProvider;
public int SessionId
{
get;
private set;
}
public Task<bool> StartUp(Object param)
{
_serviceProvider = new ServiceProvider();
var tcs = new TaskCompletionSource<bool>();
_serviceProvider.OnStartApplicationSessionResponse += (sender, args) =>
{
// do your stuff
// e.g.
SessionId = 0xB00B5;
tcs.SetResult(true);
};
_serviceProvider.startUp(param);
return tcs.Task;
}
}
The call would look like:
private static async void SomeButtonClick()
{
var mgr = new SessionManager();
var success = await mgr.StartUp("string");
if (success)
{
Console.WriteLine(mgr.SessionId);
// update ui or whatever
}
}
note: This Feature is available in .Net 4.5.
With the C# feature async and await you are able to rewrite an asynchronous flow into something that is like a synchronous flow. You have only provided some fragments of your code so to provide a complete example I have created some code that resembles your code:
class StartEventArgs : EventArgs {
public StartEventArgs(Int32 sessionId, Int32 errorCode) {
SessionId = sessionId;
ErrorCode = errorCode;
}
public Int32 SessionId { get; private set; }
public Int32 ErrorCode { get; private set; }
}
delegate void StartEventHandler(Object sender, StartEventArgs e);
class ServiceProvider {
public event StartEventHandler Start;
public void Startup(Boolean succeed) {
Thread.Sleep(TimeSpan.FromSeconds(1));
if (succeed)
OnStart(new StartEventArgs(321, 0));
else
OnStart(new StartEventArgs(0, 123));
}
protected void OnStart(StartEventArgs e) {
var handler = Start;
if (handler != null)
handler(this, e);
}
}
The ServiceProvider.Startup method will delay for a second before firing an event that either signals success or failure depending on the succeed parameter provided. The method is rather silly but hopefully is similar to the behavior of your ServiceProvider.Startup method.
You can convert the asynchronous startup into a task using a TaskCompletionSource:
Task<Int32> PerformStartup(ServiceProvider serviceProvider, Boolean succeed) {
var taskCompletionSource = new TaskCompletionSource<Int32>();
serviceProvider.Start += (sender, e) => {
if (e.ErrorCode > 0)
throw new Exception(e.ErrorCode.ToString());
taskCompletionSource.SetResult(e.SessionId);
};
serviceProvider.Startup(succeed);
return taskCompletionSource.Task;
}
Notice how an error signaled by the Start event is converted into an Exception (in production code you should use a custom exception type instead).
Using the async and await feature of C# you can now write code that looks very much like synchronous code even though it actually is asynchronous:
async void Startup(Boolean succeed) {
var serviceProvider = new ServiceProvider();
try {
var sessionId = await PerformStartup(serviceProvider, succeed);
Console.WriteLine(sessionId);
}
catch (Exception ex) {
Console.WriteLine(ex);
}
}
If an error is reported by the Start event you can now deal with in the catch block. Also the session ID is simply a return value of the function. The "magic" is that using await on a Task will return the result of the task when it completes and if an exception is thrown in the task it can be caught on the thread awaiting the task.
So I'm trying to use Signalr with the Twitter Streaming API, and specifically, for this I'm using the Tweetinvi C# API (http://tweetinvi.codeplex.com/).
The purpose of the app is to stream tweets to a page in realtime filtered with certain keywords.
The TweetInvi library works a treat, and I have a command line application successfully printing out tweets with certain keywords in.
The basic outline of my usage is as follows:
I have an MVC web app with a single page, with a text input and a button (for updating filters) it then calls the Hub method in the Signalr Hub, to start the stream if there isn't one already present and Stops it on a second button click.
All this is working fine, except when it comes to the signalr part.
public class TweetHub : Hub
{
private IStreamManager _streamManager;
public void AddTweet(String tweet, double lat, double lon)
{
Clients.All.addTweet(tweet, lat, lon);
}
public void StartStream(String[] filters)
{
string accessToken = ConfigurationManager.AppSettings["AccessToken"];
string accessTokenSecret = ConfigurationManager.AppSettings["AccessTokenSecret"];
string consumerKey = ConfigurationManager.AppSettings["ConsumerKey"];
string consumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"];
IToken token = new Token(accessToken, accessTokenSecret, consumerKey, consumerSecret);
if (_streamManager != null && _streamManager.StreamIsOpen())
{
_streamManager.StopStream();
_streamManager.StartStream(token, filters, tweet => AddTweet(tweet.Text, tweet.LocationCoordinates.Lattitude, tweet.LocationCoordinates.Longitude));
}
else if (_streamManager != null && !_streamManager.StreamIsOpen())
{
_streamManager.StartStream(token, filters, tweet => AddTweet(tweet.Text, tweet.LocationCoordinates.Lattitude, tweet.LocationCoordinates.Longitude));
}
else
{
_streamManager = new StreamManager();
_streamManager.StartStream(token, filters, tweet => AddTweet(tweet.Text, tweet.LocationCoordinates.Lattitude, tweet.LocationCoordinates.Longitude));
}
}
public void StopStream()
{
if (_streamManager != null && _streamManager.StreamIsOpen())
{
_streamManager.StopStream();
}
}
}
That is the code for my Signalr Hub. As I said, using js I can trigger the start and stop stream methods fine.
This is the code for my StreamManager class:
public class StreamManager : IStreamManager
{
private StreamClient _streamClient;
private bool _streamOpen = false;
public void StartStream(IToken token, String[] filters, Action<ITweet> action)
{
if (_streamClient == null)
_streamClient = new StreamClient(token, filters, new FilteredStream());
_streamClient.StartStream(action);
_streamOpen = true;
}
public void StopStream()
{
if (_streamClient != null)
{
_streamClient.StopStream();
_streamOpen = false;
}
}
public bool StreamIsOpen()
{
return _streamOpen;
}
public void Dispose()
{
if (_streamOpen)
{
StopStream();
}
_streamClient.Dispose();
_streamClient = null;
}
}
The code for my StreamClient class:
public class StreamClient : IStreamClient
{
private IFilteredStream _filteredStream;
private IToken _token;
private bool _streamOpen = false;
public StreamClient(IToken token, String[] filters, IFilteredStream filteredStream)
{
_token = token;
_filteredStream = filteredStream;
AddFilters(filters);
}
private void AddFilters(String[] filters)
{
for (int i = 0; i < filters.Length; ++i)
{
_filteredStream.AddTrack(filters[i]);
}
}
public void StartStream(Action<ITweet> action)
{
_filteredStream.StartStream(_token, action);
_streamOpen = true;
}
public void StartStream(Func<ITweet, bool> predicateFunc)
{
_filteredStream.StartStream(_token, predicateFunc);
_streamOpen = true;
}
public void StopStream()
{
_filteredStream.StopStream();
_streamOpen = false;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources
if (_streamOpen)
{
_filteredStream.StopStream();
_filteredStream = null;
_token = null;
}
}
}
This code above, is where it makes a call to the Tweetinvi library directly.
My problem is that when I pass the Hub method into the StreamManager's StartStream method as an Action parameter, the AddTweet method never gets hit.
As I said, this all works fine, when using a command prompt application as a client instead, and using this code:
static void Main(string[] args)
{
string accessToken = ConfigurationManager.AppSettings["AccessToken"];
string accessTokenSecret = ConfigurationManager.AppSettings["AccessTokenSecret"];
string consumerKey = ConfigurationManager.AppSettings["ConsumerKey"];
string consumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"];
IToken token = new Token(accessToken, accessTokenSecret, consumerKey, consumerSecret);
String[] filters = new string[2]
{
"test",
"twitter"
};
StreamClient streamClient = new StreamClient(token, filters, new FilteredStream());
streamClient.StartStream(tweet => TestMethod());
}
public static void TestMethod()
{
Console.WriteLine("test");
}
This works perfectly and prints out tweets with those keywords as they are received.
This leads me to believe that is a problem with the way I am using Signalr, that the signalr method is never getting hit, because the stream definitely gets opened, I just have a sneaky suspicion that it is something to do with the lifetime of the hub and the way I am using it.
I suspect this because, although the StartStream Method in my Hub gets called fine, and updates the button being clicked, when I think click again to call StopStream, the StopStream method gets hit, but my "_streamManager" member variable is null, which it shouldn't be IF the hub maintains state during it's lifetime, which I guess it doesn't.
Either that or it's being disposed of and then the stream wouldnt exist anymore anyway.
I don't really have enough experience with Signalr to properly debug.
Thanks in advance for any help.
Instances of a hub class are transient. That means that SignalR creates an instance of the hub class each time a method in that hub class is called or when a connection event occurs (e.g. onConnected, onDisconnected). When the method being called is done doing its work, that hub instance is disposed.
Read this: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#transience
So you should not try to maintain state information about a connection in your hub class. In your case that would be "_streamManager".
So I think you should move all your business logic to another class (that doesn't derive from Hub).Encapsulate them in methods and call them from your signalR methods.
If you need to call a method in the hub from your sever code, you should get a hub context first.
See how to do that here: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#callfromoutsidehub
Hope this helps!