WebServiceHostFactory and WebServiceHost instance lifetime - wcf

I am trying to figure out the lifetime of a WebServiceHost. I thought that it would initially be per-call/per-request (i.e. Similar to an ASP.Net page being created for each request). I've created a Custom WebServiceHostFactory and WebServiceHost, but noticed that the Factory and Host are only created once.
The CustomWebServiceHostFactory overrides CreateServiceHost and the CustomWebServiceHost overrides OnOpening to spit out some diagnostics to track lifetimes.
My Service File
[ServiceContract]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public partial class ProductService
{
... // code
}
My Global.asax File
private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("products", new CustomServiceHostFactory(), typeof(ProductService)));
}
Is anyone able to explain why two requests are hitting the same instance of CustomWebServiceHost, and how I would create a new Host for each service request?
Thanks

Creating the host for each new request doesn't make sense - the service host is the WCF runtime on the server side - the piece of code that will
listen for incoming requests
dispatch those requests to the service classes to be handled
Creating the service host is a pretty expensive and extensive operation - in the case of hosting in IIS, this will be done "on demand" when the first request comes in, but the service host will stay around for a given time and be reused.
When self-hosting, you typically create a single service host instance in your managed application, and then leave that host open and active until you want to shut down your services.
What will be created on a per-call basis for each request is the service class instance that actually handles the request coming in (but not the service host).

Related

WCF solution needed for a service class

I have a class raises some events and do operations. Eg
class MyService
{
EventHandler MessageSent;
EventHandler StatusReceived;
public void StartService(Serviceconfig configObject)
{
//Intialize serial port with OnSerialPortReceived event handler.
}
public void GetStatusForMessage(string messageID)
{
}
public void OnSerialPortReceived(string data)
{
if(data=="123")
MessageSent(this,null);
if(data=="456")
StatusSent(this,null);
}
}
This is a console application, it will be started when the system is started. Now we need a monitor application(basically a client with call back) when some event triggered on the event service, for that we should use WCF. and also the monitor application makes call to the service class.In the above eg GetStatusForMessage method will be invoked by the monitor application. So now how can we implement using WCF. If make the above class as service with the service contract, it wont be initialized and started until the client has initiate a call. This class object will be initialized and starts its function when ever the system restarts.
I found this article http://msdn.microsoft.com/en-us/magazine/cc163537.aspx. With this approach my service will become as publisher client and monitor application will become as subscriber client application. But the client has to make calls to the service class. So my client application should support both callbacks and also it should be able to call the service methods. How can I achieve this using WCF? Note the service class which is monitoring for events is a single instance and initialized when the application started.
Hope I ll get solutions for this. Please let me know for more clarifications.
Don't try to make your service classa WCF service. Make it a singleton and have WCF talk to it.
If you want the events to fire "events" to the monitoring application you will need to use a duplex binding (NetTcpBinding if cross machine or NetNamedPipeBinding on the same machine would be my recommendation). When the monitoring application connects save its callback channel and in the method wired up to the events call back on the callback channel.
Note you will have to keep sessions alive on both sides so the monitoring application and the service will have to fire something to each other more regularly than the configured receiveTimeout (10 minutes by default) but this can simply be a "ping" method to use as a keep-alive
I blogged about duplex communication a while back if it helps
Make your "serivce" a Widnows Service not a console app.
You can make your MyService class a WCF service without any problems. But You can also create some other class to host Your service contract and simply communicate with your windows service implementation.
There is no connection between windows service activation time and first WCF request ( this in not IIS, this is a self hosted WCF service, you start it when you want to).
Here's link to self hosting WCF service tutorial
Install your windows service on your machine with autorun option.

WCF service hosted in Windows service

I have a WCF service hosted in a Windows service. When user modifies the WCF service configuration,he needs to restart the service.
I wanted to know if restarting the windows service is better by using
serviceController.stop()
servicecontroller.start()
or by creating a new instance of the WCF client every time he wants to restart it. No information will be lost if created a new instance of the WCF client.
In your service container which is inherited from System.ServiceProcess.ServiceBase
you should start your service inside method
protected override void OnStart(string[] args)
{
servicecontroller.start()
}
and stop your services inside method
protected override void OnStop()
{
//here clean up code or any tear-down necessary to stop your service.
serviceController.stop()
}
so these methods are called automatically when you start/stop windows service from services pallet.
As others said there is no effect of creating a new instance of the WCF client every time on your service

What is the entry method for WCF service hosted on IIS?

A little background info -
I'm trying to host a RESTful WCF service on Azure. As I understand, unless I have the ASP.NET type hosting on the role, I don't really need the global.asax class (which has the application_start method).
From basic prototyping, all I needed was the svc file and the implementation behind it and it automatically gets initialized on role startup (I mean, hosted up on IIS).This is great because I need no extra code other than web.config and my service is up and running. I don't need to create a new service host and start listening on it, etc. I'm able to deploy the role and POST messages to my service.
The problem -
I have custom logging and initialization classes implemented that I need to initialize when my service starts up. I configured my service to be a singleton and I'm not sure where I should put my custom initialization components.
Without an explicit application start method and my service configured as a singleton, can I assume that when the first request comes in, my service constructor gets called? (along with all my custom initialization?).
can I assume that when the first request comes in, my service constructor gets called?
Yes, but you should ask yourself whether you really want your service to run as a singleton. If you're happy with this then it will work fine; if you don't want it to run as a singleton then you should look into Russell's answer using a custom factory.
Look at Should WCF service typically be singleton or not? for some discussion about whether WCF services should be singletons. You need to decide for your situation, but generally WCF services are not singletons unless they need to be.
To implement a custom factory, see this MSDN link Extending Hosting Using ServiceHostFactory. As the link describes, extend the service host factory like so
public class DerivedFactory : ServiceHostFactory
{
public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
{
return new ServiceHost(t, baseAddresses )
}
}
And then specify your factory in the ServiceHost directive
<% # ServiceHost
Service="MyNamespace.MyService"
Factory="MyNamespace.DerivedFactory" %>
You're looking for ServiceHostFactory. You can add a part to the SVC file to use a factory, where you can do any logging etc. you may need.
I have used this in the past to start a background worker to launch a separate thread for some background work.
http://msdn.microsoft.com/en-us/library/system.servicemodel.activation.servicehostfactory.aspx
Hope this helps you get where you need to be. :)

Configure WCF without using config file and instantiating proxy client with default constructor

I am not sure this is even possible to be honest,
I am wondering if there is a way of removing the use of the config file without having to override the creation of the client proxy. Let me give an example:
In a client app we have a WCF DAL project. This is a wrapper for their WCF Server for the client app to consume. At present the client app would need all the bindings and endpoints given in the config file and would normally (in our projects) do something like the following to wrap the WCF service:
public MyObject GetMyObject(int id)
{
using(var service = new MyObjectDataServiceClient())
{
return service.GetMyOBject(id);
}
}
This would create the call to the server and get an object back. If the client app didn't have the bindings and endpoints it would blow up. We could change each creation of the data service client to create the binding and endpoint, or create our own chanelfactory to do this for us but this means changing the current WCF DAL layer code.
My goal is to try and create a way of inserting a process into the WCF DAL layer that will handle the bindings and endpoints without the consuming code having to change, whilst removing the need for the config file.
My thoughts so far were to try and use a TT file so that it would create a partial class of the data service client and override the channel factory part. This failed because of the constructor call for the data service client goes straight into the abstract class (System.ServiceModel.ClientBase<T>) and tries to get the config stuff out. I could not find a way of stopping it looking in the config via this partial class and not changing the WCF DAL service layer.
If you have the binding and the endpoint at the DAL, you can use a different constructor of the client class (one which takes the binding + endpoint address). That constructor completely bypasses configuration, so you don't need to have anything in config.

How to make IIS wait for WCF service gets ready?

I have a WCF service hosted in IIS 7. It takes some minutes until this service finish to load its data and ready for external calls. Data loads in internal thread. The problem is that from IIS point the service is ready just after it was activated (by some call), and it process a request without waiting for data to be loaded.
Is it possible to tell IIS that the service is still loading and make this service unavailable for requests? No problem if such request will throw an exception.
You could invoke the initialization logic synchronously in the service's default constructor. The service operations won't be invoked until the service instance has been created, which will only happen after the initialization has completed. In the meantime clients simply won't receive a response.
Here's a quick example:
public class MyService : IMyService
{
public MyService()
{
// Blocking call that initializes
// the service instance
this.Initialize();
}
public void GetData()
{
// The service operation will be invoked
// after the service instance has been created
// at which point the initialization is complete
}
private void Initialize()
{
// Initialization logic
}
}
If the initialization logic is expensive, you should consider making your service run as a singleton, so that the price is paid only at the first request. Alternatively you could store the data loaded during initialization in a centralized cache. This way it can be made available to multiple service instances while still having to load it only once.
If the initialization logic is shared across multiple services, you should consider implementing it once in a custom ServiceHost by overriding the OnOpening method. Since you're hosting your services in IIS, you would then also need to implement a custom ServiceHostFactory to create instances of your ServiceHost.You can read more about this approach in this MSDN article.
Found this new feature described in "ASP.NET 4 and Visual Studio 2010 Web Development Overview": http://www.asp.net/LEARN/whitepapers/aspnet4/#0.2__Toc253429241
The problem that it's requires IIS 7.5 running on Windows Server 2008 R2, but works with ASP.NET 2.0+