Issues with "Deadlocks" in WCF routing service - c#

I've tried a few different ways to do this, but I keep coming up short.
In short, here's what I need to do:
Create a WCF service that acts as a router between client (desktop pc) run diagnostic tools and "widgets" (that also run desktop windows and are have internet connectivety). Since these "widgets" are typically behind some sort of firewall, we've decided to use an IIS hosted WCF service over a tcp connection (port 800, i believe) for callbacks.
Notifications of what the widget is doing need to be sent, asyncronously up through the router to any "connection" clients.
Clients need to be able to syncronously call into the widgets to get diagnostic data or command them to perform a task.
Right now I have a windows service running on the widget that monitors it's status and provided a link to the internal programs to get data.
I also have a light weight diagnostic application running on desktops.
I have created a single callback interface for both status-push and data-pulls that both the widget monitoring program and desktop program implement.
My first attempt was to have the router service keep a list of registered devices and clients and pass messages between them.
Ie: Desktop calls server.getwidgetcolor("widgetid"); and the service calls _widgetlist["widgetId"].getcolor() and returns it.
Similarly the widget monitoring program calls server.notifywidgetcolorchange("widgetid") and the service calls, on all registered client _widgetlist["widgetid"].clients.Notifiycolorchange()
The problem I am running into is that if a wigdet is calling up to the server at the same time the client is calling down to that widget, both calls timeout.
I initially had the server setup as a singleton, and have played with changing the concurancy mode to multiple or re-entrant, but those didn't seem to work.
Conceptually, i'd like to have the service be per-call and persist somehow, that device and client call backs so that when a call comes in, the server wakes up, depersists the call back, sends the message, then goes back to sleep.
With all that said:
Is that ^^ possible (to persist call-back data so that a per-call server can call back on clients)? If not, could I make the service per session (for clients/widgets) but pass the data between service sessions through some other means? Shared memory? File?
Is the over all design possible/recommended? I've looked into the WCF routing library, but that doesn't seem to do what I want, unless I'm reading it wrong?
Are there other technologies I should be using that can do this more easily?
Thanks,
-Bill

Related

Signal from cloud to internal network

We have a microservice based application/ website hosted currently in Azure, and we need to have a function where we press on a button, and it sends some data to another webservice currently hosted inside our corporate network.
Our IT bods are against being able to POST to a service hosted inside our network, and I am wondering how people normally deal with this problem.
I can think of 2 possible solutions, neither of which I like particularly:
Set up a VPN to the internal network, which feels a bit of a heavy solution to me
The internal network service polls the cloud application for changes of state continuously, an triggers an update process when a change is recorded. This will generate a lot more traffic than I would ideally want
How do other people address this issue? Essentially I just want to send some data from the cloud into our network in a secure fashion. Pulls from our network are OK, but pushes into it are not.
Even sending a signal to get the internal network to initiate a pull would also work fine.
Both the solutions you came up with are fairly common patterns in Azure architecture. Of the two, the second would be the one I would generally choose for this particular scenario, but it does depend on how fast you need the push to happen. VPN is going to be the fastest as you have a direct connection between your Azure service and your internal one, but it is a bit more complex to set up for a single pipeline.
The second is generally accomplished through a messaging service like Service Bus as it adds a lot of resiliency to that sort of arrangement. You can configure your onprem service to ping Service Bus based on the interval you define- more often if you need the updates to happen quickly, less often if you want to reduce traffic. Depending on the size of the data, you can load it directly into Service Bus for pickup or the message can contain the location of the required data. Event Grid is another option for a messaging service. It sends notifications out instead of waiting for you to poll, so it would be a good choice if you wanted to ping your onprem service to reach out and pick up the changes.
If you are open to using Logic Apps to do the push, it accesses onprem resources via a data gateway that you install inside your network. It does use Service Bus in the background to accomplish this so you will be using your second solution, but it would be a bit simpler from a development perspective.

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

why is wcf duplex required?

WCF duplex performs a callback after a method has run on the server that then runs code on the client.
If i want to execute a method on the client from the server at the push of a button on the server then i don't think WCF duplex is appropriate.
Why would i not just create a client and a server at each end of my 2 applications?
I was one of the people that commented on your previous question so I probably owe you an answer here :o)
You have posted rather a lot of code and I have not looked at it in detail. However, in general terms, there is a reason for using wsDualHttpBinding and duplex contracts in general instead of more of a peer-to-peer approach where you have services on both sides, as follows:
The duplex approach is appropriate where you have a clearly defined server that is running permanently. This provides the hub of the interaction. The idea is that clients are in some way more transient than the server. The clients can start up and shut down or move location and the server does not need to be aware of them in advance. When the client starts up, it is pre-configured to know where the server is, so it can "register" itself with the server.
In contrast, the server does not need to be preconfigured to know where the clients are. It starts up and can run independently of any clients. It just accepts "registrations" from all clients that have valid credentials whenever they come online, and can continue to run after the client goes offline. Also, if the client moves, it just re-registers itself with the server at its new location.
So the server is in some sense a more "important" part of the system. No client can participate in the communication without the server, but the server can operate independently of any client.
To do this with WCF duplex service, you have to do some extra work yourself to implement the publish/subscribe behaviour. Fortunately, the MSFT Patterns and Practises team have provided some guidance on how to do it
http://msdn.microsoft.com/en-us/library/ms752254.aspx
This is fundamentally different from a genuine peer-to-peer approach where there is no well-defined hub (i.e. server) for the network and each node can come and go without affecting the overall functioning of the network.
WCF Duplex is used when you have a Publish/Subscribe setting (also known as the Observer Pattern). Let's say you have a service that subscribes for notifications of some sort (e.g. new email). Normally, you would need to check periodically for updates. Using WCF Duplex, the subscriber can be notified automatically by the publisher when there are updates.

What is the simplest way to do simple distributed communication in .NET?

So basically I am thinking about attempting load testing on my asp.net application using various features all at once. There is a lot of dependencies and ajax requests being performed in this application so it seems like a simple replay of captured http requests will not suffice and due to other features like picking out random operations, performing then verifying results across several machines, simple load testing software will not suffice.
Also there is no budget to this project for spending, so commercial implementations can not be used. I'm debating on trying to use MSMQ (never used before) to handle communication between clients, but if that is really complicated to set up then I would either use a database table as a queue or a simple TCP server with each test machine as its clients.
Features I want are: immediate failure (one client crashes, then all clients should stop), each test run should start with a brand new scenario with no prior messages, and ability to publish a start and stop event. Also it would be nice if I don't have to worry about state management (leaning towards TCP server for this over database) or concurrency.
It doesn't sound like MSMQ is what you need. It is a message-passing asynchronous communication method, akin to email. You can send a message to another queue that no one is even listening to (i.e. the application isn't running). It seems to me you want a more "online" communication model.
How about creating agents (client applications that sit on many machines and create the load) that expose a WCF service where a controller program can connect to all of them and instruct the agents what to do? It can be a duplex contract, so that the agents can send the controller a notifications. When one of them send a error notification, the controller can instruct all the other agents to shut down. Also I'd go for a Net.TCP binding rather than HTTP binding.

How does the WCF service interact with my winform app?

I am currently developing a C# Windows Form Application that I intend to let it interact with a server. The server will receive posting from a mobile application that I have developed and whenever a posting is received, my Windows Form Application should be notified and give me a notification. In order to do this, I intend to use WCF duplex service for it.
E.g. My mobile application sends an posting over to my server. Once my server reads and receives the new posting, the service should send a message over to my winform app to alert me that a posting is received. And the UI of the winform app should update accordingly to what I want to updated. (e.g. adding new panels)
This is basically how I wish for it to work
They way this would work is
WCF Service in running on my server
Windows Form connects to my server's WCF service using Duplex Contract
Mobile app posts to a webpage
Once the webpage receives the posting, the asp.net will invoke the WCF service
WCF duplex service receives the posting and sends the information to the winform app
My winform Application aka WCF Client updates UI with this new message received
My question is, how does step 4 proceed to step 5? To be specific, how does the service sends the information over to the winform app upon receiving the posting.
To be even more specific, once the posting is received from the webpage, the service contract is invoked and the information is sent and received by the service, how does the service make use of the call back channel to send the information over to the winform app and update the UI accordingly?
The answer to this question depends on how your WCF service is hosted and how "big" the service will eventually be (in terms of number of simultaneous clients).
The simplest scenario is a self-hosted WCF service (meaning hosted in a Windows Service or as a desktop application--not in IIS). In this case, you can use InstancePerSession mode and make your service use sessions. In this case, you'll have a 1:1 correspondence between clients and instances of your service class. When a client connects, retrieve the callback reference and store it in a static list outside of the service class. When you need to send a message to one or more clients, simply iterate over (or find the desired client in) your list and call the appropriate function on the callback contract
If you need to host your service in IIS, then the situation is trickier because you have the possibility of multiple processes hosting your service, so your list can potentially get fragmented (or blown away in the event of an app pool recycle). In this case, you'll have to use something external to your service (MSMQ, perhaps) to notify other application pool processes that a message needs to be sent.
In terms of a duplex connection, you are really just able to communicate two way over that one connection, not with all connections of the service without doing some tricky thread stuff and shutting the door on any scalability (or using something outside the service to handle to pub/sub).
One solution though that may work a lot more along the lines of what you want to do would be SignalR. It allows a single client to make a request and then you can broadcast data from that request to other clients (or target it). Take a look at its info, its sole purpose is real time communication in .NET with multiple clients.
Also another note, is that you will want to use some sort of BackgroundWorker or something for your listening thread in WinForms so that the UI is not locked while the background operations are running.

Categories

Resources