WCF Service application without gui that will stay alive - c#

[WCF newbie]
I have a basic client-server WCF project.
My Service is "gui"less application, meaning that I created winform application, removed the Form1.cs and the lines that starts the gui.
The service is running ok, I am using servicehost.open..
My problem is that it is "serial" (sync), so after a second the application exists.
How can i keep the application alive and listening to the host ?
I need to halt the process and then to host.close when I want to end it.
Thanks
This is code of service:
class Program
{
public static Uri BaseAddress;
[STAThread]
static void Main(string[] args)
{
string baseAddressStr = "http://localhost:7000/someservice";
BaseAddress = new Uri(baseAddressStr);
using (ServiceHost host = new ServiceHost(typeof(MyClass)BaseAddress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.Open();
host.Close();
}
}
}

I don't think you want to host your WCF service in a windowless WinForms app.
If you want it to stay open indefinitely, the way to go is to host the WCF service in a Windows Service. Here you have a basic sample.
The benefits should be obvious:
Can run even if no user is logged in.
Does not require a workaround for keeping the application open.
Additionally, you should consider externalizing your WCF configuration (like the base address, service behavior) to the application configuration file. You don't want to rebuild and redeploy your service each time something (anything) changes in the configuration, which may vary from development, test, acceptance and production environments.

Related

Consume WCF Service over named pipe hosted in WPF app from Windows Service

I host a WCF Service in a WPF appilication which updates the GUI using a named pipe. In a Windows Service I consume this WCF-Service to update the GUI.
I host it in my WPF app with the following code:
private ServiceHost serviceHost;
public MainWindow()
{
InitializeComponent();
try
{
string address = "net.pipe://localhost/Path/ServiceName";
serviceHost = new ServiceHost(typeof(ComGUIService));
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
serviceHost.AddServiceEndpoint(typeof(IComService), binding, address);
serviceHost.Open();
}
catch (Exception ex)
{
// TODO: Logging & Handling
}
}
And consume it in my Windows service:
string address = "net.pipe://localhost/Path/ServiceName";
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
EndpointAddress ep = new EndpointAddress(address);
IComService channel =
ChannelFactory<IComService>.CreateChannel(
binding, ep
);
try
{
channel.SendUpdatedStatus("test");
}
catch (Exception e)
{
// Throws: The pipe endpoint net.pipe://localhost/... could not be found on your local machine
}
System.IO.PipeException: There was no endpoint listening at net.pipe://localhost/... that could accept the message
The strange thing is, the exact same code works when it is excecuted in a Console app and the communication to the WPF app is successfull. Is there something special about the communication between a Windows Service and a desktop app through named pipes? Is this even possible?
I had the same issue going on. The problem is your service runs in session 0 when running as a service and your app in session 2. You see it working when running the service as a console, because both apps are running under the same session 2 (no additional perms needed). The named pipe has to be created in a shared memory space for the service to actually see the named pipe, and when they are running different sessions you will see this problem crop up. The solution is to simply allow "create Local Object" permission to the necessary users/groups. Go into group policy editor. Windows Settings -> Security Settings -> local Policies -> User Rights Assignments -> Create global objects (add user group to this permission and you should be good to go!). Good luck!
I managed to get it working. The only thing I had to do was to run the WPF application with administrative privileges. Why the communication between those application only works when the WPF application is running as Administrator is still a mystery.

Connect to a self hosted WCF service

So we have a 3rd party software that has it's own API we use to retrieve calculated data inside application only, when ever we try to run a WCF service through the API it runs, and the state is showing as OPEN but we try to add this Service as a Service Reference we can't connect to it for some reason .
The service port is not showing in opened ports list, could the be due to WCF is started on a different thread(3rd party application thread).
I am following this tutorial :
https://blogs.msdn.microsoft.com/brunoterkaly/2013/11/01/wcf-service-hosting-how-to-host-a-wcf-service-from-inside-a-windows-presentation-foundation-application/
which works fine when we create our own software to host the WCF.
The idea behind using WCF in a 3rd party software is we are trying to access calculated data from this software and get it in another client application.
Please your help is needed.
WCF service was no being detected because i have it inside using statement
using(ServiceHost myServ = new ServiceHost(typeof(HelloWorldService), baseAdress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
myServ.Description.Behaviors.Add(smb);
myServ.Open();
MessageBox.Show("Services is :" + myServ.State + "\n" + baseAdress);
}
once the using(){} is removed the WCF is working as a charm

How to Recycle a Self-Hosted WCF Service

I'm hosting a WCF Service in an Azure Woker Role much like this.
I'd like to be able to "recycle" the WCF Service Host on a regular interval. The problem is, I assume the service is running it's own App Domain, and I have no way to poll it for any events, nor can I share any common data between the Worker Role and the WCF Service.
For reference, here's the minimum code to host:
public override void Run()
{
using(var host = new ServiceHost(typeof(MyService))
{
// Configure host here...
host.Open
while(true)
{
Sleep(1000);
}
}
}
I'd like to "restart" the host somehow every 24 hours, but i'm not sure how/what to hook into to accomplish that.
The WCF service is running in-proc to your worker role right (ie. everything is running in WaWorkerHost.exe)? In that case you can either call RoleEnvironment.RequestRecycle, or just let the Run() method exit. Either way will cause WaWorkerHost.exe to gracefully shut down, and then the Azure guest agent will automatically restart everything.

Circular Dependency Issue

I am currently trying to learn how to create a WCF service and I am facing an issue.
I have a project lets call it MainProject which is a console application and a second project called SoapServer which is created as a class library.
The MainProject doesn't need to reference the SoapServer but the SoapServer does need to reference stuff from within the MainProject.
However, even though MainProject doesn't need to access SoapServer at the moment it does so that the console application can start the host on the WCF service.
However, this obviously causes a circular dependency as I can't have MainProject refernece SoapServer and visa versa. Is there a way to get a round this.
Below is how I am opening the connection for the WCF Service.
public class SoapServer : ISoapServerInterface
{
public void startSoapServer()
{
Uri baseAddress = new Uri("http://localhost:6525/hello");
using (ServiceHost host = new ServiceHost(typeof(SoapServer), baseAddress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("The service is ready at: {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service");
Console.ReadLine();
host.Close();
}
}
Thanks for any help you can provide.
There shouldn't be much code in hosting application (MainProject). It is responsible only for hosting the service and this is its sole purpose. Don't place commonly-used code there.
Instead create another class library with commonly-used code and create references to it from SoapServer and from MainProject.

How to consume Windows Communication Foundation (WCF) by a Windows Service

When i create a Windows Service for getting information from a Web Application(ASP.NET c#) for scheduling some task in the client machine.
To consume WCF from the web application. I added WCF reference
to Window Service project as a service reference, everything seems fine. It
updated app.config file, added service reference etc.
it was not working. Any idea will be very helpful.
My Code is shown below
string result = string.Empty;
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://test.com/Service.svc/DevicesService");
using (ChannelFactory<IDevicesService> myChannelFactory = new ChannelFactory<IDevicesService>(myBinding, myEndpoint))
{
IDevicesService wcfClient1 = myChannelFactory.CreateChannel();
result = wcfClient1.CheckNetworkConnection(IPLocalHost);
if (!string.IsNullOrEmpty(result) && result.Equals(IPLocalHost))
{
EventLog.WriteEntry("Test connection succeeded");
}
else
{
EventLog.WriteEntry("No live connection currently available");
}
((IClientChannel)wcfClient1).Close();
}
I find it easier, when building a windows service, to build a console application that performs the same work as the service will. I abstract out the actual working code (e.g. your code snippet above) into a separate assembly and then just invoke it from either my service's start method or the console's main method.
If you move your code above into a console application, does it work? If it doesn't, can you step through it and let us know where it fails. And when it fails, what exception information are you seeing?
Let us know and we'll help!

Categories