У меня есть служба WCF net.tcp, и я хотел бы, чтобы ОС выбрала порт, который она должна прослушивать. Поэтому я установил порт на 0 в моем URI и netstat
подтверждает, что ОС выбрала порт в диапазоне 5000.
Как найти фактический порт, выбранный в коде, в процессе обслуживания?
Некоторый код для демонстрации того, что я пробовал:
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
Не уверен, что это поможет, но на SO уже есть похожий вопрос: Как я могу получить адрес/порт прослушивания службы WCF?
Соответствующая часть отправленного ответа, которую вы можете попробовать:
foreach (var channelDispatcher in serviceHost.ChannelDispatchers)
{
Console.WriteLine(channelDispatcher.Listener.Uri);
}
Так что, возможно, вам нужен channelDispatcher.Listener.Uri. Порт
.
Надеюсь, это поможет!
В качестве альтернативы вы можете найти свободный порт для WCF и использовать его самостоятельно:
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;
}
}
Код из здесь.
После запуска службы вы можете получить полное описание конечных точек, которые были фактически созданы, из коллекции Description.Endpoints (это не работает до тех пор, пока не будет вызвана функция Open()). Из этой коллекции вы можете получить адрес. К сожалению, вам нужно разобрать адрес для порта.
Это то, что мой сервер регистрирует после каждой службы Open().
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());