Context:
I need to develop a monitoring server that monitors some of our applications (these applications are in c#). So I decided to develop the system with WCF which seems suitable for my needs.
These applications must register themselves to the monitoring server when they start. After that the monitoring server can call the methods Start or Stop of these applications.
Everything is completely executed on the same machine, nothing needs to be executed remotely.
So I developed a good prototype and everything works fine. Each application registers itself to the monitoring server.
Question:
ApplicationRegistrationService
(see the code below) is the implementation of the monitoring service and it is a singleton instance due to the ServiceBehavior
attribute.
Here my problem: I want to access the content of ApplicationRegistrationService
per example, the number of connected applications from my server (ConsoleMonitoringServer
in the example). But, I am not sure how to achieve this.
Do I need to create a channel in my server to the service like I did in my clients (ConsoleClient
) or it exists a better way to achieve this?
Code:
The code is very simplified for the purpose of this question:
//The callback contract interface
public interface IApplicationAction
{
[OperationContract(IsOneWay = true)]
void Stop();
[OperationContract(IsOneWay = true)]
void Start();
}
[ServiceContract(SessionMode = SessionMode.Required,
CallbackContract = typeof(IApplicationAction))]
public interface IApplicationRegistration
{
[OperationContract]
void Register(Guid guid, string name);
[OperationContract]
void Unregister(Guid guid);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple)]
public class ApplicationRegistrationService : IApplicationRegistration
{
//IApplicationRegistration Implementation
}
public class ApplicationAction : IApplicationAction
{
//IApplicationAction Implementation
}
Console application for this example
class ConsoleClient
{
static void Main(string[] args)
{
ApplicationAction actions = new ApplicationAction();
DuplexChannelFactory<IApplicationRegistration> appRegPipeFactory =
new DuplexChannelFactory<IApplicationRegistration>(actions,
new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/AppReg"));
IApplicationRegistration proxy = appRegPipeFactory.CreateChannel();
proxy.Register(Guid.Empty, "ThisClientName");
//Do stuffs
}
}
Console server for this example
class ConsoleMonitoringServer
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(ApplicationRegistrationService),
new Uri[]{ new Uri("net.pipe://localhost")}))
{
host.AddServiceEndpoint(typeof(IApplicationRegistration),
new NetNamedPipeBinding(), "AppReg");
host.Open();
//Wait until some write something in the console
Console.ReadLine();
host.Close();
}
}
}
Finally, I find the answer and it was pretty easy. I just need to create the service instance and pass the reference to the constructor of ServiceHost.
So I need to replace the following code:
using (ServiceHost host = new ServiceHost(typeof(ApplicationRegistrationService),
new Uri[]{ new Uri("net.pipe://localhost")}))
by :
ApplicationRegistrationService myService = new ApplicationRegistrationService();
using (ServiceHost host = new ServiceHost(myService,
new Uri[]{ new Uri("net.pipe://localhost")}))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With