How to: Avoiding Cold-Start issues with IIS hosted WCF applications? - wcf

We have a system where we host a couple of WCF applications in IIS. Some of these applications have a bit of an extended start-up time taking a couple of seconds (more than a users would be happy to wait for). Once it's up and running, everything is snappy though, so it really is only the startup time.
The client also has a requirement to recycle the application pools every night.
Is there some way to wake all these services up so that the start-up time is not an issue for the first user of the system?
Initial thoughts where to write a windows service that would simply call a lightweight method on each service every x (configurable) minutes to keep the apps alive, but since we are in a load balanced environment, and the applications need specific host headers to be passed, we would always hit the load balance address which means there is no way for us to make sure that all services on all boxes in the cluster are actually started.
Since a single wcf application in IIS can only have a single host header, the only other way would be to setup a second iis web site pointing at the same application. I'm just not sure if that would do the trick since it would be in another host context.
another option could be to wright something like an extension to IIS (not sure if this is possible yet) that could call each of our services when IIS or the app pool actually starts up again. (Something that notices when the app pool has recycled but before the first user request.
Any ideas would be much appreciated.
Thanks
Gineer

Excellent. Thanks Dercsár.
After a quick Google, I found the following arcticle on the subject: Using the IIS Application Warm-Up Module
The limitations here are that this is only available on Windows 2008 R2 with IIS 7.5. Although our client is in the process of upgrading to Win 2K8R2, this may still be some time off.
Does anyone know of a solution that would work for Windows 2003 with IIS 6 or will we have to write something do make this work?
Gineer

For those of us running on a version of IIS before 7.5, we are in the process of testing the following solution...
As mentioned in the original post, the initial idea was to fire off a WebRequest from a service running on each machine to the local web sites (which host the WCF services), but this would be impossible, since they all make use of Host headers, and they all live in a Network load balanced farm.
We then thought that we could simply provide the custom host headers in the web request to the localhost.
Turns out you can not update the host header name in a WebRequest. It’s a Read only field.
Messing with a proxy class makes it work though.
See: http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/1b35c665-fe32-4433-8877-a62f2d400a8e/
And a short piece of my test code below in C#.
WebRequest req = WebRequest.Create("<Correct Host name>");
req.Proxy = new WebProxy("127.0.0.1");
StreamReader stream = new StreamReader(
req.GetResponse().GetResponseStream());
StringBuilder sb = new StringBuilder();
String LineString;
while ((LineString = stream.ReadLine()) != null)
{
if (LineString.Length > 0)
sb.Append(LineString);
}
stream.Close();
String response = sb.ToString();
This may not be what the proxy class was intended for, but it seems to work either way.
Gineer
Ps. No, you do not need to have any actual proxy server installed on the local host machine.

Related

Is it possible to run ASP.NET 5 site directly on Kestrel in Azure WebApps?

I have checked that in the web response the server is IIS when I deploy ASP.NET5 to azure web app, so I guess the IIS platform handler is used to redirect it to Kestrel. So I am wondering if it is possible to run directly on Kestrel, and what benefits/drawbacks will that have (probably regardless if it's in Azure or not). I suppose it will be a bit faster since IIS will be excluded from the pipline, but it should not be too much overhead I suppose...
On Azure Web App, you cannot bypass IIS.
But in the general case, you can definitely run Kestrel directly. It is after all just dnx web and it's exactly what the XPlat version (Linux, OSX) will end-up using (almost).
What you lose from not using IIS
Security (newer component compared to IIS)
Easy setup of SSL
Kernel module that handle file/cache and other things (kernel = faster)
Application monitoring/Keep-Alive (what happens if Kestrel crash)
Multiple hostnames single-port (80) reuse
etc.
What you gain from not using IIS
Complete control over your process
Higher overall performance
Simpler installation/execution
What you should do if you choose not to use IIS
If you are OK with the "lose" points, I would still go and host your Kestrel behind a reverse proxy or an NGINX server. Kestrel was made to be "production ready" but it's not NGINX or IIS.
It will not keep itself alive as far as I know.
If I missed anything, please let me know.
Your question is a bit ambiguous, as it asks at the same time about Azure Web Apps and about the general case. #Maxime answered the general part, so I'll answer the Azure Web App part.
It is not possible to bypass IIS in Azure Web Apps. Stack that normally run without IIS are typically handled using HttpPlatformHandler (as is the case for ASP.NET 5), or in the case of Node some variant of that (iisnode).

Intermittent WCF Connection (There was no endpoint .. ) error

I have a WCF service hosted in the IIS (IIS 8). The service is in a Per Call Mode and the concurrency mode is set to Multiple. I have around 600 clients connecting to it. It has a HTTPS end point. It also has a net.tcp endpoint but that is not used. Not all but some of my clients face a very weird problem. The client stops working after using for a while. I have error logging and at the client side I see the error which says
There was no end point listening at ...
There are no errors on the server, or the service. The service seems to be working fine. I can browse to the service page from a browser and other clients are still able to use the service. Running a trace is also not helping. I have spent enough time trying to figure it out but with no luck. Further more, on the same computer just restarting the client seems to work and connect to the same service. The client is a WinForms Application.
I performed a DNS flush on my machine and even that does not help.
What could be the possible issue? The things that hit my mind are that maybe the client is unable to resolve the name, but that is contradictory to it connecting in the first place.
The service maybe down, but my other clients are still using the same and they do not face problems.
It might be a problem with the client machine as it Uses Win XP but I am not sure if that would cause a problem.
Or it might be a problem because of intermittent internet connection.
Has anyone ever faced such a problem before? Some insight would be really helpful
IIS can only serve a limited number of clients at a time. It will then place additional requests onto a queue. That queue is also limited. When that queue fills up then IIS returns a 500 error, which is interpreted as "There was no end point listening at ..."
You should try this piece of code.
public void Main()
{
while(thereIsStillThisProblem)
{
var pc = new Pc();
pc.OS = new Windows2012();
pc.Start();
pc.Software.Add(new ServiceHost());
}
}
http://www.microsoft.com/technet/prodtechnol/windowsserver2003/library/iis/64e30660-d2f0-4e90-98cc-1652214a2b93.mspx
Edit: Just remembered that there is one more thing you can do, if you are using .net 4.5. I will let Jon Skeet explain.

how can I test a WCF service using XAMPP to work with Apache server?

I built a WCF service on a windows virtual machine, and tested it with the WCF test client by typing this on my browser:
http://localhost/Service1.svc/getAllCustomers
... and it works pretty good. Now the problem is that I want to do the same test in my real computer (not the VM).
I'm using XAMPP on the VM, I have set the project on the htdocs folder, and I type this on my browser:
http://10.211.55.3/WCFWebService/Service1.svc.cs/getAllCustomers
The problem is that it doesn't return the result of calling getAllCustomers, instead it returns the Service1.svc.cs in plain text.
I want it to do the same thing it does on the VM - can someone tell me what the problem is? I think it's because on the VM it works with the WCF test client, and since my computer is a Mac I can't run the WCF test client.
A WCF service can't run on an Apache web server instead you should install IIS Server on the VM in order to test the service.
Refer to this: http://msdn.microsoft.com/en-us/library/ms733766.aspx
I found this with a Google query.
I kept the tab open, but continued exploring the other search results.
One I found particularly interesting was this one: WCF acting as Web Service without IIS
It appears WCF gives options other than IIS to host the web service (Console Application, Windows Application, Windows Services).
The Windows Service link is provided here: How to: Host a WCF Service in a Managed Windows Service
I have not done this, so I cannot elaborate on what problems you will run into.
I just want others that may run into this (like I did) to know that the one answer posted last year may not actually be the end of the road.

Delphi / WCF SOAP connectivity and Virtual Machine (VMWare) settings

I've got a working WCF service and a working Delphi client. On a normal PC, they work nicely. On a VM that's "Bridged" they work nicely if I log onto the domain (but not if I logon locally to the VM as administrator). If the VM is NATed, the connection attempt times out.
I would love to hear people's thoughts on what could be making such a difference to whether the client can successfully connect to the WCF service. Bear in mind I'm connecting with basicHttpBinding with no security.
The service is setup to use System Account (interact with desktop is NOT checked), and it starts automatically. The service URI doesn't change, the port is open, and can be telnet'd to in all scenarios.
Any ideas or pointers?
Within the VM, open Internet Explorer and verify that you can view the WSDL of the WCF service. If you can't, then your issue is connectivity and has nothing to do with your Delphi code.
Group Policies and Enterprise Security solutions that swap certificates or require certificates to be registered (we're using a UTM called CyberRoam) make a difference.
Also when Virtual Machines join a domain, their ComputerNames are added to a list maintained by the Domain Controller. When the same Virtual Machine is "moved" or "copied", its ComputerName should be changed to avoid DNS resolution issues.
I'm not claiming this as the definitive answer, however it does explain the issues I noticed in this instance.

How can I use net.tcp without IIS?

I have a web site and build a wcf service in it. I can run the code by calling it from a test page in the web site. The web site is ran by the vs2010 development server.
I do have IIS 7 but never use it.
Now I want to use the NetTcpBinding instead of BasicHttpBinding, everyone says it should be enabled in IIS, but how can this be done without using IIS and keeping everything in 1 project?
Thanks for any help
edit: A Windows service would be a solution, but that would mean adding a project to the solution, I really want to keep everything in 1 website, took me quite some time to get the service in the website in the first place.
This is about my own test version of the website, the production server is out of my reach. The service must be expanded by other developers later on it's bad if they have to run IIS just to test the service.
One way is to host the WCF service in a Windows Service - see How to: Host WCF in a Windows Service Using TCP for sample code.
Are you talking about how to develop without using IIS7 or how to put the service into a production environment without IIS7?
If it's the latter, then Stuart's answer is correct, but otherwise I would suggest that you start to develop using the web server that you will eventually be hosting the web site/service on.
Hosting in IIS7 has several advantages over hosting in a Windows Service such as fault tolerance and process isolation already built in.
Thanks for the replies guys, it looks like I have 3 options:
1. Host the service in a seperate project.
2. Host the website in IIS.
3. Use HTTPS, also secure.
PS: My development environment is very different from production :(
In development I have unit testing and in production there are old ASP pages, that I can't even acces, but sometimes must refer to...