I am looking for advice on the best approach for doing inter-process communication.
The solution consists of 3 projects.
GUI: This will only display messages to the user and get user input
Windows Service: Communicates with the UI and runs the 3rd module using elevated credentials
Worker: Internal DLL that will perform the actual work
I need a way to make the worker communicate with the GUI directly to send and receive updates.
I have two ways in mind to do it (will be happy to see more suggestions):
Use two named pipes. One for the GUI<>Service communication. And the other for GUI<>Worker communication
Raise an event from Worker to Service. And use WCF callback from service to UI
What will be the best way to implement the communication?
NOTE: The problem here is the GUI<>Worker communication. Not the UI<>Service communication.
1) WCF is officially recommended way to implement interprocess communication (tcp or named pipes are fastest), it replaces remoting (but always use serialization/deserialization).
In advanced scenarios communication can be implemented using
Memory mapped files;
Service Bus. (Service Bus allows to create loosely coupled components/communication. Google for nservicebus, rabbitmq, masstransit etc);
Something like Web Sockets or SignalR (consider using this if you have browser/javascript client/GUI).
2) If your Worker is just library (.net assembly) - it will work within Service process. In this case you dont need to invent something to pass data/events from Worker to GUI, all communication (duplex, I suppose, with subscribing to service events) will be perfomed between GUI and Service (Service only delegate some work to Worker via regular .net calls)
3) Sometimes we need something like dispatcher between services, client and server. You can find some information here.
Related
I'm re-writing a tcp server program in .net core.
I have difficulties implementing my design.
The server has three basic functions/services:
service 1. accept and manage client connections
service 2. handle each kind of client messages and send acknowledge message
service 3. keep track of inactive clients(clients who haven't sent any message for a time) and close those connections.
I'd like to have each of these functions on a dedicate IHostedService.
But I've no idea how should these services communicate with each other.
These services are registered by AddHostedService, and seem can't be injected.
And I'm not sure if it's a correct way to expose public methods on a Hosted Service for others to call.
The most relevant SO question I've found is this one.
In my situation, it means that I should register one mediator service for each of the three services. It doesn't seem to be a clean way because these mediators are just for communication, without semantic meanings...
I'd like to know if the mediator is the only approach,
or is my design totally incorrect?
That really depends on strategy. Each hosted service could take in a configuration as part of its dependencies for communication. However, TCP port binding will need to be unique.
In a prior life, I wrote a UDP service that broadcast and which TCP services were available for communication and mediated the services in chat room sort of setup. UDP is more of a wide net whereas TCP is specific addressing.
If you were using only TCP, without configuration those services would need to know who is the mediator and what address to reach it at.
I have a c# client app and service which hosts job server.
Example:
Service has class and 3 methods
public class TransferData
{
..
TransferToSQLServer
TransferToRDS
TransferToAzure
}
Client application knows nothing about this class.
How client can create jobs to transfer data via one of these methods?
Must client application have copy of this class in their code to know this type for a job creation?
It´s the good practice to transfer data between diferent systems, thas it, different domains, you must integrate using a service bus. And usualy service bus are implemented with queue servers, like RabbitMQ or ActiveMQ. In this case, the both involved systems need have knowledge of a simple POCO class, called of Contract.
This contracts must be knowledge for all applications and are the messages that you transfer between applications. When a application 'publish' a message, you can have many other applications 'listening' a exchange waiting messages. And after receive the message, do the necessary processing.
Using this method, you can integrate applications and different languages.
Bellow a basic example transfering basic messages (simple strings):
https://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html
You can yet add a above layer like MassTransit (free) or NServiceBus (commercial)
An example:
http://docs.masstransit-project.com/en/latest/configuration/quickstart.html
Scenario :
I want to implement an MSMQ in which users input message through System.Messaging API's. And there should be a listener which always observes this queue so when ever there is a message in queue I want to make a database updation.
My first approach was to implement MSMQ trigger. I was able to implement a COM interop dll trigger. But I wasnt able to do database operation and I couldnt figure out what was wrong, I tried a lot . Then I came to know about this WCF MSMQ binding. As I am new to this WCF I have some doubts.
Which is the best approach to host WCF for this case. Is it IIS with WAS or Windows service?
And for this kind of listener service is a client necessary or can we write the database operations directly under the Service host operations without client invocation?
Then I came to know about this WCF MSMQ binding. As I am new to this
WCF I have some doubts
Well, that's valid. WCF has a fairly steep learning curve, is very config-heavy, and is not everyone's cup of tea.
However, if you're integrating to MSMQ, WCF has very good support and is rock solid in terms of the way it is implemented.
Which is the best approach to host WCF for this case. Is it IIS with
WAS or Windows service?
Unless you're hosting exclusively on a web environment, I would choose a windows service every time. Using something like topshelf, the deployment and management overhead is tiny, and there are no external dependencies.
Remember to use msmqIntegrationBinding rather than netMsmqBinding, as the latter relies on WCF at both ends, whereas the former supports System.Messaging on the client, or even better, use WCF on the client and then you can use netMsmqBinding which support "typed" messages.
I have a basic windows service which does some conversions of data. There's decoupled GUI which allows user to changes some configuration and this needs to be proprogated to the Windows Serivice running. Both of them are running the same box and implemented using C# .NET. Which is the best way to communicate to the service other than interprocess communication mechanisms like mutex, events etc.
Also I'd like to avoid to implement it as a web service because it's not a webservice.
I would use a WCF Service to communicate.
You can use netNamedPipe binding but that might not work on Windows 2008/Windows 7 since the Service runs in session 0 and all user code runs in sessions >0 and they would not be able to communicate.
So I used netTcpBinding in my own project.
If the processes are not going to move to different machines, you can use memory mapped files as the communication mechanism.
If that's not the case, WCF is a good option.
Since you're dealing with configuration data for the service, I would persist it somewhere. Database, file, registry, etc. UI writes the information and the service reads it when appropriate (e.g. each run).
I have a timer in a windows service (.NET C#). I need to be able to change the elapsed value from an external program. If the timer is currently running, I need to be able to shorten the time elapsed value from an external program. I was thinking of having a public method in the service that would change the timer elapsed value and restart the timer, but can an external program call a public method on a windows service?
In short, it's not possible to directly call functions in another process. The process containing the function you want to access (in this case, your Windows service) will need to expose it through some sort of IPC (inter-process communication). What type of IPC you choose will probably depend on how complex the communication needs to be, and whether or not the "client" is a .NET application.
If your needs are simple (e.g. just setting a timer value), or if your client does not use .NET, using named pipes (or TCP, if you need to access the service from another physical machine) is probably your best bet. Both named pipes and TCP give you a Stream that you can write messages to and read on the other end.
If you need to expose many different functions or send and receive complex data types, and if you are using .NET on both ends, .NET Remoting or WCF is probably best. .NET Remoting is simpler but has more constraints; WCF is very flexible but has a steeper learning curve.
Yes this is possible.
You might want to consider created a NetNamedPipe endpoint on your service and controlling the service through that interface.
NetNamedPipeBinding binding = new NetNamedPipeBinding();
MyService myService = new MyService(binding,
new EndpointAddress("net.pipe://localhost/MyService"));
myService.ResetTimer(30);
You cannot call a method in a Windows service process directly, but you can have the Windows service expose this function as a WCF service, for instance. The Windows service would be acting as a service host as well. That's possible and not complicated.
Older (non WCF) services can use .NET Remoting. Have a look here for some info on how to get started. This is the pre-WCF way of communicating between applications across process boundaries.