How to make IIS wait for WCF service gets ready? - wcf

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+

Related

Use IOptionsSnapshot in Startup.ConfigureServices()

I want to be able to reload my Swagger configuration without redeploying my service.
So I'm trying to use an IOptionsSnapshot directly in the Startup.ConfigureServices() method :
public void ConfigureServices(IServiceCollection services)
{
services.Configure<SwaggerSettings>(Configuration.GetSection("BaseTemplate:Swagger"));
var swaggerSettings = new IOptionsSnapshot<SwaggerSettings>(); //get an instance
//Configure Swagger
}
I guess that the Startup.ConfigureServices() is called only once when the application is starting ?
Is there any workaround to use and reload a IOptionsSnapshot in the the Startup.ConfigureServices() ?
Yes, the Startup.ConfigureServices() is called only once when the application is starting.
Is there any workaround to use and reload a IOptionsSnapshot in the
the Startup.ConfigureServices() ?
Do you mean you want to create the service instance each time they're requested from the service container or once per client request (connection)? If that is the case, you could try to use AddTransient method or AddScoped method to register the service. Code like this:
services.AddScoped<IMyDependency, MyDependency>();
More detailed information, see:
Transient
Transient lifetime services are created each time they're requested from the service container. This lifetime works best for lightweight, stateless services. Register transient services with AddTransient.
In apps that process requests, transient services are disposed at the end of the request.
Scoped
For web applications, a scoped lifetime indicates that services are created once per client request (connection). Register scoped services with AddScoped.
In apps that process requests, scoped services are disposed at the end of the request.
Reference: Dependency injection in ASP.NET Core and Service lifetimes.

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

WebServiceHostFactory and WebServiceHost instance lifetime

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).

Startup Code for Loading COM Object for WCF Service

I am currently have a WCF service that uses a COM DLL for its service. The COM object is only loaded once and saved via a singleton. The problem is the first run takes about 1 minute to load the COM Object. The WCF service is hosted via a Windows Service. I am wondering how can I load the COM Object singleton via the startup of the Windows Service.
protected override void OnStart(string[] args)
{
if (host != null)
{
host.Close();
}
Type serviceType = typeof(MyService);
host = new ServiceHost(serviceType);
host.Open();
objectConn.getInstance()
}
When I try to add the load of the Singleton in the OnStart of the Windows Service startup, it always fails. I would like to ask if this i the proper way to add startup routine for the objectConn instance. I tried to place the singleton loading in the MyService construtor but it is only called with the first call to the web service operation/method that I invoke which makes the first service call awkward.
I read about DependencyInjection but I think the added behavior is not applicable since I just want to load the COM object source once.
You can probably do this - but I would recommend doing it before the
host.Open()
call. This call spins up the entire WCF runtime and everything, and I would prefer to do all initialization tasks before that, if ever possible.
Marc