Signalr 2.4 on Shared Hosting - signalr

I am using Signalr 2.4 to broadcast a game loop. My signalr hub has a public static list of broadcasters like so: public static readonly ConcurrentDictionary<string, CribbageBroadcaster> _cribbageBroadcasters = new ConcurrentDictionary<string, CribbageBroadcaster>();
I am getting some strange issues once I deploy my app my shared hosting provider. I have two methods that try and get the count of broadcasters. In my controller I get the count like this:
public ActionResult Index(DataSourceRequest dsr)
{
var viewModel = new HomePageViewModel();
viewModel.Standings = _standingsListFactory.CreateStandings(dsr);
viewModel.GamesBeingPlayed = CribbageHub._cribbageBroadcasters.Count;
return View(viewModel);
}
And another method on the hub itself which I call using javascript :
public int GetGameCount()
{
return _cribbageBroadcasters.Count;
}
I tested these methods locally using multiple browsers and it works perfectly, with both returning the expected number of games. However, once I deploy my code sometimes one method will give a count but the other one wont. Other times both will say 0 when I know there should be one 1. And other times it will display the correct count. Each time I refresh the page the result is different. I am lost as to what is causing this. Any help would be appreciated.

Related

xUnit IClassFixture constructor being called multiple times

I am using xUnit for integration testing. and for that, I use a localdb instance for it. With that being said, I would like to initiate DB instance once with some pre-defined data and of course I would that stay true for all test cases. I could write each test cases isolated so they are not running into each other however I would like to only create DB instance once.
I followed xunit constructor runs before each test and the code looks like
//similar to base class
public class DatabaseFixture : IDisposable
{
public SqlConnection Db { get; private set; }
public DatabaseFixture()
{
InitialDB();
}
public InitialDB()
{
CreateDBInstance();
CreateDBSchemas();
InitDBMetaData();
}
public void Dispose()
{
// clean up test data from the database
CleanUpDB();
}
}
//Class where you want to use shared class instance
public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
DatabaseFixture dbFixture;
public MyDatabaseTests(DatabaseFixture fixture)
{
this.dbFixture = fixture;
}
// write tests, using dbFixture.Db to get access to the SQL Server
}
The problem I am facing is I noticed this DBFixture being called everytime per test case. I thought with iClassFixture it is only called once. which brings problem when test cases run in parallel because it is trying to cleanup db while other test trying to access it and also multiple test cases would try to create the db at the same time which causes error. https://xunit.net/docs/shared-context.html
Can anyone shed light on why it is not working?
I stumbled across the same problem and it was an issue with visual studio:
https://github.com/xunit/xunit/issues/2347#issuecomment-983586580
Right clicking the class file which contains the tests to start the test runner, may lead to this behaviour.
You need to use Collection Fixtures instead.
https://xunit.net/docs/shared-context#collection-fixture
When to use: when you want to create a single test context and share it among tests in several test classes, and have it cleaned up after all the tests in the test classes have finished.

Using Lazy<> with Prism.DryIoc.Forms gives "container is garbage collected" exception

We're using Prism.DryIoc.Forms to create apps with Xamarin.Forms. To minimize the startup time of the app we are using the Lazy<> pattern for classes with a lot of dependencies.
This used to work fine with Prism.Unity.Forms. However, I can't get it to work with Prism.DryIoc.Forms. Any help would be appreciated.
The code is as follows. We have a page view model like this:
public class MySamplePageViewModel
{
private readonly Lazy<ISomeClass> _lazySomeClass;
public MySamplePageViewModel(Lazy<ISomeClass> lazySomeClass)
{
_lazySomeClass = lazySomeClass;
}
public void SomeMethod()
{
_lazySomeClass.Value.DoIt(); //throws exception
}
}
However, after the page view model is being instantiated, when calling _lazySomeClass.Value we get an exception with message "Container is no longer available (has been garbage-collected).".
It seems to be related to how Prism resolves the view model, because when calling the following it works fine:
var container = (Application.Current as PrismApplicationBase<IContainer>).Container;
var lazySomeClass = container.Resolve<Lazy<ISomeClass>>();
lazySomeClass.Value.DoIt(); //works fine
we're doing the registration like this:
container.Register<ISomeClass, SomeClass>(Reuse.Singleton);
container.RegisterTypeForNavigation<MySamplePage, MySamplePageViewModel>("MySamplePage");
The problem should be fixed in v2.10.3.
Therefore the next logical step is to ask Prism.DryIoc.Forms maintainers to update to the latest DryIoc version.

Retrieve names of Online users connected to a Server

I asked this question before which has got a very good response. But as I am new to asp.net (and jquery) cant understand how the program is flowing.
Summary:
I have created a Basic chat application. Now I am trying to add a advanced function like whenever a user is online (connected to a server), the server should show or broadcast the available online user's username to all the users connected to that server.
By referring the responses to the previous question (s0nica and VinayC), I modified my class file and jquery file, which are giving errors as shown in the below links. (I think I am very close)
Chat.cs (Two errors, I mentioned errors in between code comments)
file.js (Working fine, refer it if you need to)
Please have a look to the above files and assist me.
PS: In the previous post, I was thinking that if I change the Global.asax code, my problem will be solved.. which I realized later as wrong..
Your first error from:
Clients.joins(Context.ConnectionId, Caller.username, DateTime.Now);
Shold be:
Clients.All.joins(Context.ConnectionId, Clients.Caller.username, DateTime.Now);
Other errors associated with it: In your JS file it should be:
Line 15
chat.state.username = chatUsername;
Second error:
The error is exactly as it states, you do not have a toList function off of your dictionary object. Secondly you can't plainly convert a List or a string directly to a Chat object.
Based on your setup you currently dont have a proper "user" list to return. Right now you're saving a List to represent an individual user. You might want to try changing your dictionary object to be something like
static ConcurrentDictionary<string, User> _users = new ConcurrentDictionary<string, User>();
Where User is:
public class User
{
public string Name { get; set; }
public string ConnectionID { get; set; }
}
Then on your Joined function you could just do:
public void Joined()
{
User user = new User
{
Name = Clients.Caller.username,
ConnectionID = Context.ConnectionId
};
_users.TryAdd(user.ConnectionID, user);
Clients.All.joins(user.ConnectionID, user.Name, DateTime.Now);
}
Lastly your GetConnectedUsers would end up(make sure you're 'using System.Linq;'):
public List<User> GetConnectedUsers()
{
return _users.Values.ToList();
}
I probably went a little bit overboard but hopefully this helps!
If you need a reference to the change log from SignalR 0.5.3 to 1.0 alpha here's a great post on all of the modifications:
http://weblogs.asp.net/davidfowler/archive/2012/11/11/microsoft-asp-net-signalr.aspx

How to get HealthVault to work with multiple ApplicationID in same application

We may never know why Microsoft decided to limit developers by making HealthVault applications constrained to a single web/app.config entry for a HealthVault application. However I need to be able to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
I won’t go into the details of the reasoning behind 2 different HealthVault applications, but other than to say we need it to work. I still cannot login correctly with MSDN Forums (think infinite redirection sign in loop) so I am hoping for a post here that will help me.
I did contact a HealthVault developer on how to achieve this however the developer gave a suggestion that I don’t believe would be reliable (if I’m wrong let me know).
The developer’s suggestion was to do the following in code when you needed to connect to HealthVault, but prior to connecting:
ConfigurationSettings.AppSettings[“ApplicationId”] = “[YOUR APP ID]”;
The problem is that this is a static property and I do see this as an issue as our web application will have different users accessing both HealthVault applications at the same time.
Does anyone have any suggestions to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
There is a way to dynamically switch app ids on runtime. Both applications must be created, both certificates must be installed. Few things to keep in mind. For every authenticated connection, user will be granted a token (aka wctoken). This token is consumed when user is redirect back from Live ID (in case live id is used...) by your redirect.aspx page (assuming your redirect page inherits from HealthServiceActionPage.This means that everytime you switch applications, you must redirect user back to Live ID with new app id to receive new token.
Here is code sample that can be user to dynamically change settings:
public class ConfigurationManager : HealthWebApplicationConfiguration
{
private string appid;
public ConfigurationManager(string appid)
{
this.appid = appid;
}
public override Guid ApplicationId
{
get
{
return AppManager.Current.GetCurrentAppId(this.appid);
}
}
}
public class AppManager
{
private static readonly Object lck = new Object();
public Guid? App;
public static AppManager Current
{
get
{
AppManager mgr = null;
if (_current == null)
{
lock (lck)
{
mgr = new AppManager();
}
}
return mgr;
}
}
private static AppManager _current;
public Guid GetCurrentAppId(string id)
{
return new Guid(id);
}
}
Usage:
ConfigurationManager cm = new ConfigurationManager(your-app-id-here);
HealthWebApplicationConfiguration.Current = cm;

Static variables and long running thread on IIS 7.5

Help me solve next problem.
I have ASP .NET MVC2 application. I run it on IIS 7.5. In one page user clicks button and handler for this button sends request to server (jquery.ajax). At server action in controller starts new thread (it makes long time import):
var thread = new Thread(RefreshCitiesInDatabase);
thread.Start();
State of import is available in static variable. New thread changes value of variable in the begin of work.
User can check state of import too with the help of this variable, which is used in view. And user sees import's state.
When I start this function few minutes everything is okey. On page I see right state of import, quantity of imported records is changed, I see changes in logs. But after few minutes begin troubles.
When I refresh page with import state sometimes I see that import is okey but sometimes I see page with default values about import (like application is just started), but after that again I can see page with normal import's state.
I tried to attach Visual Studio to IIS process and debug application. But when request comes to controller sometimes static variables have right values and sometimes they have default values (static int has 0, static string has "" etc.).
Tell me what I do wrong. May be I must start additional thread in other way?
Thanks in advance,
Dmitry
I add parts of code:
Controller:
public class ImportCitiesController : Controller
{
[Dependency]
public SaveCities SaveCities { get; set; }
//Start import
public JsonResult StartCitiesImport()
{
//Methos in core dll, which makes import
SaveCities.StartCitiesSaving();
return Json("ok");
}
//Get Information about import
public ActionResult GetImportState()
{
var model = new ImportCityStatusModel
{ NowImportProcessing = SaveCities.CitiesSaving };
return View(model);
}
}
Class in Core:
public class SaveCities
{
// Property equals true, when program are saving to database
public static bool CitiesSaving = false;
public void StartCitiesSaving()
{
var thread = new Thread(RefreshCitiesInDatabase);
thread.Start();
}
private static void RefreshCitiesInDatabase()
{
CitiesSaving = true;
//Processing......
CitiesSaving = false;
}
}
UPDATE
I think, I found problem, but still I don't know how solve it. My IIS uses application pool with parameter "Maximum Worker Processes" = 10. And all tasks in application are handled by few processes. And my request to controll about import's state always is handled by different processes. And they have different static variables. I guess it is right way for solving.
But I don't know how merge all static values in one place.
Without looking at the code, here are the obvious question. Are you sure your access is thread safe (that is do you properly use lock to update you value or even access it => C# thread safety with get/set) ?
A code sample could be nice.
thanks for the code, it seem that CitiesSaving is not locked properly before read/write you should hide the instance variable behind a property to handle all the locking. Marking this field as volatile could also help (see http://msdn.microsoft.com/en-us/library/aa645755(v=vs.71).aspx )

Resources