2010-08-25 14 views
7

Tengo un servicio net.tcp WCF, y me gustaría que el sistema operativo escoja el puerto que debería escuchar. Así que configuré el puerto en 0 en mi URI, y netstat confirma que el sistema operativo ha elegido un puerto en el rango de 5000.¿Cómo puedo obtener el puerto que escucha un servicio WCF?

¿Cómo puedo encontrar el puerto real que se ha elegido, en código, dentro del proceso de servicio?

algo de código para mostrar lo que he intentado:

Type serviceType = ...; 
Uri address = new Uri("net.tcp://0.0.0.0:0/Service/"); 
ServiceHost serviceHost = new ServiceHost(serviceType, address); 
ServiceEndpoint endPoint = serviceHost.AddServiceEndpoint(type, binding, ""); 
int port1 = endPoint.ListenUri.Port; // returns 0 
int port2 = serviceHost.BaseAddresses.First().Port; // also returns 0 
+0

Es bastante inusual para obtener un servicio para escuchar en un puerto aleatorio - ¿Existe una razón por la que quiere hacer esto? – Cocowalla

+0

@Cocowalla: el servicio es parte de un proceso de trabajo, por lo que puede haber más de uno por vez, y estamos buscando soluciones que no involucren .NET TCP Port Sharing. – ngoozeff

+0

posible duplicado de [¿Cómo puedo obtener la dirección/puerto de escucha de un servicio WCF?] (Http://stackoverflow.com/questions/2207348/how-can-i-get-the-listening-dress-port-of -a-wcf-service) – mafu

Respuesta

10

No estoy seguro si esto ayudará, pero hay una pregunta similar que ya están en SO: How can I get the listening address/port of a WCF service?

La parte pertinente de la respuesta presentada que es posible que desee intentar:

foreach (var channelDispatcher in serviceHost.ChannelDispatchers) 
{ 
      Console.WriteLine(channelDispatcher.Listener.Uri); 
} 

Así que tal vez necesita channelDispatcher.Listener.Uri.Port.

Espero que esto ayude!

+1

@D Hoerster: desafortunadamente eso solo devuelve el URI que pasé. Gracias por el puntero a la otra pregunta. – ngoozeff

+3

@D Hoerster: Parece que tenemos un ganador. También tuve que establecer endPoint.ListenUriMode = ListenUriMode.Unique; para que esto funcione (y deshabilite el uso compartido de puertos en el enlace). – ngoozeff

+0

¿Hizo su llamada a Open? – BozoJoe

1

Como alternativa, se puede encontrar un puerto libre para WCF usen mismo:

Código
private int FindPort() 
{ 
    IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); 

    using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) 
    { 
     socket.Bind(endPoint); 
     IPEndPoint local = (IPEndPoint)socket.LocalEndPoint; 
     return local.Port; 
    } 
} 

de here.

+1

Esto no es seguro. Alguien más puede arrebatar el puerto después de que se haya eliminado el socket, pero antes de que se abra el ServiceHost. Entonces este método puede fallar esporádicamente. – BatteryBackupUnit

3

Una vez que el servicio se ha iniciado se puede obtener una descripción completa de los criterios de valoración que en realidad se crearon a partir de la colección Description.Endpoints (esto no funciona hasta después de abierto() es llamado). De esta colección puedes obtener la dirección. Desafortunadamente, tiene que ensartar la dirección del puerto.

Esto es lo que mi servidor registra después de cada servicio Abrir().

 serviceHost.Open(); 

     // Iterate through the endpoints contained in the ServiceDescription 
     System.Text.StringBuilder sb = new System.Text.StringBuilder(string.Format("Active Service Endpoints:{0}", Environment.NewLine), 128); 
     foreach (ServiceEndpoint se in serviceHost.Description.Endpoints) 
     { 
      sb.Append(String.Format("Endpoint:{0}", Environment.NewLine)); 
      sb.Append(String.Format("\tAddress: {0}{1}", se.Address, Environment.NewLine)); 
      sb.Append(String.Format("\tBinding: {0}{1}", se.Binding, Environment.NewLine)); 
      sb.Append(String.Format("\tContract: {0}{1}", se.Contract.Name, Environment.NewLine)); 
      foreach (IEndpointBehavior behavior in se.Behaviors) 
      { 
       sb.Append(String.Format("Behavior: {0}{1}", behavior, Environment.NewLine)); 
      } 
     } 

     Console.WriteLine(sb.ToString()); 
+0

+1 para ponerme en el camino correcto – ngoozeff

Cuestiones relacionadas