How to eliminate AddressAlreadyInUseException with Console host

Topics: Web Api
Jan 29, 2012 at 2:41 AM

Clearly I am having an issue with the way I am starting my APIs when running with a Console host.  I am having no issues running the APIs with a web or Windows Service host but cannot get the APIs started in a Console app.

Using this code:

var host1 = new HttpServiceHost(typeof(Service1), config, new Uri("http://localhost:59108/myapi1"));
var host2 = new HttpServiceHost(typeof(Service2), config, new Uri("http://localhost:59108/myapi2"));
host1.Open();
host2.Open();

I am getting the following exception:

System.ServiceModel.AddressAlreadyInUseException was unhandled
  Message=HTTP could not register URL http://+:59108/myapi2/ because TCP port 59108 is being used by another application.
  Source=System.ServiceModel
  StackTrace:
       at System.ServiceModel.Channels.SharedHttpTransportManager.OnOpen()
       at System.ServiceModel.Channels.TransportManager.Open(TransportChannelListener channelListener)
       at System.ServiceModel.Channels.TransportManagerContainer.Open(SelectTransportManagersCallback selectTransportManagerCallback)
       at System.ServiceModel.Channels.TransportChannelListener.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.HttpChannelListener.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at Microsoft.ServiceModel.Channels.LayeredChannelListener`1.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at Microsoft.ServiceModel.Channels.LayeredChannelListener`1.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open()
       at Acme.Hosting.Console.Bootstrapper.CreateServiceRoutes(HttpConfiguration config) in C:\Source\Acme.Hosting.Console\Bootstrapper.cs:line 32
       at Acme.Hosting.HostBootstrapper.Run() in C:\Source\Acme.Hosting\HostBootstrapper.cs:line 96
       at Acme.Hosting.Console.Program.Main() in C:\Source\Acme.Hosting.Console\Program.cs:line 19
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Net.HttpListenerException
       Message=The process cannot access the file because it is being used by another process
       Source=System
       ErrorCode=32
       NativeErrorCode=32
       StackTrace:
            at System.Net.HttpListener.AddAllPrefixes()
            at System.Net.HttpListener.Start()
            at System.ServiceModel.Channels.SharedHttpTransportManager.OnOpen()
       InnerException:

From what I am reading, the problem is with WCF not accepting a second ServiceHost on the same port.  Unfortunately, as I mentioned, this works perfectly fine when starting up the APIs in IIS or as a Windows Service.  So, what gives?

 

Jan 30, 2012 at 12:29 PM
Edited Jan 30, 2012 at 5:10 PM

Try to issue the following command from the command prompt:

 

netsh http add urlacl url=http://+:59108/ user="<Machine Name>\<User Name>"

it's explained here why it's nessary

http://msdn.microsoft.com/en-us/library/ms733768.aspx

Jan 30, 2012 at 1:17 PM
Edited Jan 31, 2012 at 1:35 AM

Ok, but before I do so and change the configuration of my system which might mask other issues, can you tell me why it is necessary to add a URL reservation to host my APIs in a Console app but not when hosting as a Windows Service?  And if this is necessary, why has the Web API team not documented it somewhere as they frequently promote the fact that the APIs can be hosting in a Console app?

 UPDATE

Actually, I read that article before my original reply and it doesn't explain why it's necessary, just what it does and how to use the command. Furthermore, it does not answer the question why it would be needed for the Console host but a Windows Service host runs without such changes?

 Let me explain. In order for me to deploy this solution, I would theoretically have to execute this command on every target system.  We currently have a deployment base of over 5,000 and I have to go through a pretty rigorous process to get such a change approved and implemented.  And the first question I will be asked is "why".  I need an answer or it goes no further than this discussion.