How do I push data from a console program over SignalR websockets? - c#

I have a website running as an Azure Web App which is configured to use SignalR and the Azure Service Bus scaleout backplane. All working well, and clients connect via the /signalr URL and I can push data from the server to the connected clients.
I also have several console apps which periodically run and output new data. I would also like to push the new data to the web-connected clients.
How can I tie in my non-web applications with SignalR? All the examples I see assume every server in the scaleout cluster are web-facing. Is there some special setup I need to do to have external processes join the SignalR cluster and be able to push data to web-connected clients over the SignalR websocket connection without having to make them web apps as well?

There are two options.
First Option
You can connect your "console apps" to the signalR backplane, and these apps will be able to call client's methods with something like
var hub = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
hub.Clients.All.doSomething("blah-blah");
You can use any port for the signalR config but same backplane configuration and same Hubs. You can use Owin for self hosting. Nobody will connect to these console apps.
Disadvantages:
1) Your console applications needs to reference SignalR.SelfHosting and your hubs classes. This is not good from architecture point of view.
2) Your console apps will listen some ports (since they're signalR servers). Theoretically somebody could connect to this hubs and do something. This is not good neither from architecture point of view no from security.
Second Option
You can implement Hub method like "PushSomeDataToClients" and call it from your console apps using SignalR client as mentioned in #bartbje comment.
Pros: no disadvantages from the first option.
Cons: You need to implement some security stuff to prevent anybody outside the system to call this method. SignalR has a lot of stuff to do this, so just google. For example you can create separate Hub for inter-system communications.
Third Option
Interact with web-server apps with another way then SignalR. Probably you're already using something like rabbitMq or any type of service bus. Also you can implement it using separate ApiController at your web-server app. But it seems to be closer to the second option.
Due to me, I would probably choose the third option since it's clean from architecture point of view.

Related

Theory: Azure Websockets

Is it possible to consume an external (to Azure) API that requires you to establish a wss connection to receive notifications of changes in some kind of Azure container (Kubernetes/Durable Function)?
Or do I need to run a Virtual Machine with a background service keeping the socket alive until it's got no more data to send (hours). No UI.
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview?tabs=csharp
Durable functions look promising but I'm unsure if these will cover my requirements.
Any advice welcomed.
Yes, you should be able to use WebSocket connections to services deployed on Kubernetes. And also the other way around where services in Kubernetes is WebSocket clients with connections to external services.
I haven't tested, but Azure Web App supports Web Socket. As you can host Azure Functions in the same App Service which is running your web app, I think it's possible to support web sockets on your functions with durable function.
Another point that leads me to think this, is the native support of Azure Functions to SignalR Service, which runs on Web Socket too.

What are some known ways to push data from web api to a windows form client

I'm having trouble finding some documentation or services available to help push data to clients on winforms. (Maybe my search query sucks)
Ex.
I open an application on my phone which sends a request to a web api controller to run some code in a windows form app that is already running somewhere else. (for example, my PC)
I can find an abundance of information on Azure Notifications Hub and push messaging when it comes to mobile devices and windows store 8 apps but not for plain old winforms app.
I am aware I can create a que on a db and poll it with clients but want to see if there is a way to avoid polling scenarios.
What are some known ways to push data from web api to a windows form client?
Learn About ASP.NET SignalR
ASP.NET SignalR is a new library for ASP.NET developers that makes
developing real-time web functionality easy. SignalR allows
bi-directional communication between server and client. Servers can
now push content to connected clients instantly as it becomes
available. SignalR supports Web Sockets, and falls back to other
compatible techniques for older browsers. SignalR includes APIs for
connection management (for instance, connect and disconnect events),
grouping connections, and authorization.
Here is a sample in the topic area.
Using SignalR in WinForms and WPF
Implementing SignalR in Desktop Applications
ASP.NET SignalR Hubs API Guide - .NET Client (C#)
This document provides an introduction to using the Hubs API for
SignalR version 2 in .NET clients, such as Windows Store (WinRT), WPF,
Silverlight, and console applications.
The SignalR Hubs API enables you to make remote procedure calls (RPCs)
from a server to connected clients and from clients to the server. In
server code, you define methods that can be called by clients, and you
call methods that run on the client. In client code, you define
methods that can be called from the server, and you call methods that
run on the server. SignalR takes care of all of the client-to-server
plumbing for you.

How to connect multiple clients to multiple servers and send alerts from servers based on certain events?

Background
I have multiple servers that I currently connect to remotely to run a number of different commands/scripts to obtain information about the servers and/or applications running on the servers.
I'd like to automate running the commands/scripts (or the code contained in the scripts converted to C#/.NET) and have the server send alerts/notifications/messages to a client (basically a Windows Form) running on multiple workstations, but need some guidance.
For reference, I have limited experience creating Windows Services, but feel fairly confident in being able to create them on the server to handle to command/script automation, which I'm assuming would be the best way to go about handling the command/script automation on the server (since the commands/scripts would need to be run all the time or at set intervals).
Question
How can I connect multiple servers to multiple clients so that the server sends alerts/notifications/messages to the client when a command/script or even an event occurs on the server?
For instance, if an application on the server has a built-in command that can be run to determine the status of the application (up, down, limbo, etc.), I would like the Windows Form on the client to receive an alert from the server when the command returns "down" or "limbo" when it is run, presumably from a Windows Service. The alerts would be displayed on the Windows Form that would be setup basically as a dashboard for the servers that the client can connect to.
An even better outcome would be that the client runs as a background application and a notification appears similar to how Microsoft Outlook displays a notification when new email messages arrive (although these notifications would likely require user interaction to close instead of fading out like the Outlook notifications).
I would also like for the client to use a configuration file that has the connection information for the servers in it so that the servers being used can be changed quickly new servers are added or existing servers are decommissioned.
Research (so far)
I've read about WCF and duplex contracts, and how WCF can be hosted in Windows Services. From what I've read, this seems promising. However, I'm not quite sure how I would set this up so that the client can connect to a WCF service on multiple servers.
One thing that I'm concerned about with WCF is that in all of the WCF examples (which implement a calculator-type service) I've seen the client has to initiate the communication with the server in order to receive a message through a callback. In the calculator service examples, the client sends numbers to the service and the result is provided in the callback. I've also seen an asynchronous example, but in that example the client initiated a single, long running request and the callback returned a single response when it was finished processing.
And, just so I'm clear about bindings in WCF, it is possible to create and use bindings for multiple servers using a configuration file without having to use SvcUtil.exe to generate the code, correct? The reason I ask is because the servers that will be configured will likely be change for different users, so the client needs to be flexible when connecting to the services.
I've just now started looking at Sockets, but I'm not familiar enough with them to know if this would be the better option to achieve my objective.
Summary
I'm just looking for guidance, so if you can help direct me to some resources that will help me achieve my objective, I would appreciate it. I've searched extensively, but the majority of my searching either doesn't apply to my scenario, it is limited to a single server/client interaction, or it is limited to a single server with multiple clients.
Since I'm not sure what direction to go in, I don't have any code examples, although I have implemented the examples in the following Microsoft article: Windows Communication Foundation - Getting Started Tutorial
So you want to build a system of
multiple servers which execute commands on the computer they are running on
multiple clients which will receive the status of the commands executed on server or such information from the server
This would be my advice
Servers can be implemented as windows service. You will be able to administrate them easily this way using the services console or the scm. Checkout this link for a creating a simple C# service How do you write and use a Windows Service in C#?
Also, you can set the service to run as an in-built service user with different levels of permissions in addition to regular user accounts.
I have not used WCF, but usually clients connect to the server; this is a pretty common model, and hence all samples are such. Initiating connection from server is not a big deal (at least in a socket program), but just a bad model. You have to ask yourself, if no client is connected to your servers, how can they relay a status to the end user. You have to think clearly about the communication model. I would suggest a central repository of messages. It can be a file on a shared file system or a database or any such entity which can act as a data repository. This way all servers can convey there messages without caring if a client is connected or not. You can use Sockets to achieve what you want to do. Check the asychronous socket server sample from MSDN to understand how to do it.
Making the client run in the background and just have a notification area icon is also easy in c#. You can use NotifyIcon Class for that. This CodeProject article (Formless System Tray Application) demonstrates its usage. To show notification a la outlook style, you can refer to the following post: How to create form popup from from system tray on windows application (not web) with c#. Look at not only the accepted answer but other answers too; there are lot of useful links in it.
So far we have windows service talking over sockets, storing messages in a central repository and capable of handling multiple clients with toast style pops for client side notification.
You need a far richer client side GUI so the end users can take actions on the messages sent from the server. You can maintain a list of servers in app.config for the client that the client connects on startup. You should to provide a GUI for users to manage all servers and their connections.
Lat but not least, by building such a client server model, you are effectively building a security loophole in your systems. You should implement a good authorization mechanism. Checkout the following post: Authenticate user in WinForms (Nothing to do with ASP.Net)
EDIT:
You can also implement your server to accept "custom command" when you implement it as a service. This way, your client server communication will be standardized by using ServiceController to pass the command. This post might help: How to send a custom command to a .NET windows Service from .NET code?.
Don't get confused in the "command" terminology here. ServiceController issues standard commands to a service for start, stop, pause, resume and restart the service. These are the same items you see on the context menu when you right click a service in the services.msc snap-in. The same way a service can respond to custom commands. In your case the custom command maybe a request to execute a process.
Note that some mechanisms I have described are geared towards an intranet setup while others scale fine on both intranet and internet

WCF, Windows service - needs to notify client application

I am a newbie developer to WCF and Windows services. I do know c#. The scenario requires various custom applications running on Windows 7 to call methods in another application. It is a client/server relationship, all running on the same computer. The server must be able to notify each client (one at a time) when a specified condition occurs.
I need to develop the server code only.
Would the following be an acceptable solution:
Make the server a windows service that uses WCF. The server could notify the clients by using a different named pipe for each client ?
Thank you...any suggestions would be appreciated.
Just use duplex communication over tcp/named pipes/msmq/http (WSDualHttpBinding) channel.
AFAIK you need two ports (in/out) for duplex over http
I would ditch wcf altogether. Although as Brian says, you can use the duplex bindings, these are complicated at best.
If it's all going to run on the same computer, why do you even need client/server? Just build a single client which does everything you need.
That is a acceptable solution and should work fine.
Other option for consideration (in the spirit of learning) is creating a Routing Service as an intermediary service which spawns the calls to multiple services. So in your scenario, your client would call the routing service and the routing service will in turn call each of your service
The following link should provide more information on routing service...
[Routing Service][1]
http://msdn.microsoft.com/en-us/library/ee517423.aspx

.NET Scalable Pub/Sub service implementation

I need to build a system that is similar to a pub/sub system. It is composed of multiple sub-systems or services running in separate executables or as a Windows Services.
The sub-systems are:
The pub/sub service
A pub/sub service managing communications between the internal sub-systems and the users.
A user can have multiple channels open (A web page connected to a SignalR service, a mobile device connected to a duplex WCF service, etc.).
The service should manage all the channels of an user and be able to send information to them on demand based on topics or specific users.
The service must support multiple transports like SignalR, WCF, or others ...
Worker services
A worker that runs as a Windows Service and sends information to the users using the pub/sub service.
The SignalR and WCF host
The SignalR service and WCF service will be hosted on IIS
My questions are
As the sub-systems run in separate processes, how do I communicate between the pub/sub service and the other sub-systems like (the workers and IIS). The communication must be really fast. Do I use named-pipes, is it fast enough ?
An example; The worker tells the pub/sub system to send a message to a user, the pub/sub systems checks the channels opened for the user (let's say a SignalR channel), then in turn it must notify the SignalR service running in IIS to send the message to the user's browser.
Do you know of implementations of similar systems ?
Observations
I cannot use third-party service-bus services (Azure ..). And even with that .. I can't see a solutions to the problems above.
The service must be very scalable and high-demand proof.
If the question is how to bridge SignalR with other transports there are several solutions.
On a single server you could just connect them up with the Reactive framework's own pubsub mechanism which is neatly encapsulated in the Subject class.
If you need to scale out to multiple servers you'll want to use an existing service bus or perhaps roll your own simple one using SQL server and a SqlDependency.
You could also use SignalR as a client on one server communicating with the other servers to copy messages between them.
I recommend you look into some of the existing Service Bus technologies for .NET.
There is an article which clearly explains the possible mechanism of how to incorporate a pub/sub design pattern in your .NET application. The answer lies in using a .NET In-Memory distributed cache and use its clustering capabilities as a publish subscribe medium. Since it's clustered therefore you won't have to worry about down-times as well.
Basically you'll be using the Application Initiated Custom Events
Register your events
public void OnApplicationEvent(object notifId, object data)
{
...
}
_cache.CustomEvent += new CustomEventCallback(this.OnApplicationEvent);
And fire those events whenever you need to
_cache.RaiseCustomEvent("NotificationID", DateTime.Now);
Pub/Sub design pattern in a .NET distributed cache
Full disclosure: I work for Alachisoft

Categories

Resources