How should I go about testing a Topshelf windows service that connects to a SignalR hub? - automated-tests

I have inherited an application at my job that is being converted from WCF to SignalR. It is a windows service created using Topshelf. When the service is started is connects to a SignalR hub. Various things may happen, such as a user sending a request to my service through the hub. Then my service will send back a request for their PIN. They send that back and my service then requests if they have authority to do their original request from yet another client. All of these various requests are interfaced of course.
Previously this was all done with WCF and we had a very comprehensive suite of tests for the service. Now that I am trying to switch all the tests over to SignalR I have no idea really where to even begin. Running any test starts the topshelf service as expected, but then of course it tries to connect to the hub which doesn't exist.
I have tried using Moq to simulate the hub, but it doesn't seem to work as mocking a running hub so of course I cannot get my service to connect to a mocked hub while the test is running. I'm not sure if that is a Moq limitation, or just me not understanding how to use it. I have also tried entirely recreating the hub as another project in the same solution as my service and testing project, but again I can't figure out how to actually make the hub run properly so that my service can connect to it when the test is running. Again, I assume that is my lack of knowledge. Our SignalR hub is created using the basic OwinStartup/MapSignalR process (just as in the microsoft chat app tutorial).
I feel like I'm going in a bunch of different directions and not getting anywhere because I don't know enough about SignalR and how to test it. I have done the basic "chat app" tutorial and the related tutorial about testing that with Moq, but once I try to add in the additional complexities of my project I just get lost.
What is need is for a test to run, "connect" to the SignalR hub, and give me a way to simulate the user request, and the user sending back their PIN, and the other client that sends back the authorization granted/denied message. All of the tutorials I find are for testing one single back and forth in that chain. I hope this all makes sense and someone can point me in the right direction of what I need to do to proceed. Thank you!
I have tried to recreate a hub within my project purely for testing, and I have tried setting up a Moq'd hub to connect to. I am expecting (hoping) to get a SignalR hub (real or mocked) that my service can connect to and do all of the various back-and-forths it needs to to test whatever it may be I am testing, for example the entire path of a user requesting to do something that they then have to authenticate with a PIN to do. So, not testing one method of the hub but a whole end-to-end process.

Related

Azure - Sending data from IoT Hub to Web App Backend

I'm searching for a solution to get data from the Azure IoT Hub to the backend of a Web App also hosted in Azure which is written in ASP.NET 4.6.
It would be best to just receive the raw Json string as fast as possible.
I found others suggesting using Webhooks or Azure functions for a similar purpose but the delay these solutions bring aren't really acceptable.
It would be best to just connect directly to the IoT endpoint and get every message as it comes in. Can anybode please point me to the right direction?
You can simply use the EventHub .NET SDK in your web app, connect to the EventHub-compatible endpoint of the IoT Hub and directly consume the events in your app. This has minimal delay and involves no extra components.
How to guide (.NET core but same applies to .NET Framework): https://learn.microsoft.com/en-us/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send#receive-events
var eventProcessorHost = new EventProcessorHost(
EventHubName,
PartitionReceiver.DefaultConsumerGroupName,
EventHubConnectionString,
StorageConnectionString,
StorageContainerName);
// Registers the Event Processor Host and starts receiving messages
await eventProcessorHost.RegisterEventProcessorAsync<SimpleEventProcessor>();
The Azure SignalR Service can help to broadcast messages to the Web App instances.
There are no direct integration between the Azure IoT Hub and Azure SignalR Service. Basically you can use two patterns for this integration such as PULL-PUSH and PUSH-PUSH.
The following screen shows these integration patterns:
Note, that the PUSH-PUSH pattern with the Azure Event Grid is suitable for solution when the subscriber (consumer) is not critical for processing events in the order.

Send SignalR notification from other process

I have an architectural question with signalR
Let's say I have a web app (pure front JS) that use a web api and the web app query an API that do a long task and want to be notified when the task is finished.
So the web api create a fire and forget task, and we use SSE with signalR to notify the web app. It's working. Great, thanks to signalR.
But now, I want the long task to be run in another process, let's say with a msmq based system.
So, the web app query the API, the web api create a message, and the msmq service process the message asynchronously.
Can the msmq service hosted in another process (maybe another machine !) notify the web app that the task is finished ? It can be possible to put the connection id in the message, but the service can be able to send the notification ?
I would use a servicebus, you can then use this library to forward the message directly to the clients.
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy

Determine If Signalr Scale Out Is Necessary

I am having trouble wrapping my head around whether or not my scenario will require scale out. I have a process in a windows service that pushes messages to a hub hosted in a web app via the signalr .net client. These are user specific messages and are distributed using the Client(connectionid) approach. If this is deployed in a web farm scenario will I need to use a scale out approach? When a user joins I am storing that connection info in the database. I store the url of the webserver and connectionid so I can target that when I publish messages from the windows service.
I would use this if it is an option.
http://www.asp.net/signalr/overview/performance/scaleout-with-windows-azure-service-bus
Louis

Sending a signalr message directly via scaleout from different Azure role

I have 2 roles in my Azure cloud service application: a web role (signalr connections here) and a worker role.
The web role uses Azure service bus as its scaleout provider.
At certain points in time the worker role will emit certain events. I'd like to send this data directly to clients connected to a Hub.
My current implementation involves the worker role placing a message on a service bus queue which the web role subscribes to, the web role then forwards this message to clients via a HubContext call.
My question is: how can I send this message directly to connected clients from the worker role? So far I have considered 3 methods:
Configure signalr as in the web role so that they use the same servicebus topic. - this done not work as intended as worker role instances "steal messages" from topic subscriptions intended for the web role. This would seem to be the cleanest way of doing it but configuration is a problem.
Use the .Net client to send a hub message - this is not ideal as it places unnecessary load on the web role, as well as double the amount of service bus messages when compared to the above method.
Manually write a signalr compatible message to the topic - very hacky and succeptable to breaking changes.
I know that the team are currently rewriting scaleout for the next release but will this be possible at some point?
Edit:
I have noticed that this is supported in the RabbitMq implementation.
It seems an issue with my configuration was responsible for the first method not working.
However, it seems like that method is slower end to end (by about 150 ms) even with one less message in the loop.
I will wait and see if the scaleout work brings any improvements to this method before making any changes.

SignalR for updating clients on events passed from another Event system

We have this Pub/Sub system that you subscribe to via a callback mechanism in C# to recieve events from various things that happen within the database. This subscription has a callback signature attached to it that allows for the Pub / Sub system to callback any subscribers it has and notify them of the change on that Callback thread.
We are taking our windows application and migrating it into a web application. In doing so, I need a way to update this Web Application (The clients) with information from this Pub / Sub. I want to use SignalR, but not sure where to host it. I assume if I host it on the same Web Application as the Client, it won't be able to subscribe to the pubsub due to it not being able to do background threading.
Currently, I have it in a Console application hosting the SignalR server on a specific port. Obviously this is for testing and not ideal for a larger scale.
My question is.. is it really safe to be hosting SignalR outside of IIS? should I put this in a Windows Service? Web Service somehow? Can it go in a Web Application somehow?

Resources