Самостоятельно размещенный Wcf служит wsdl, но 404 при вызове

Я пытаюсь самостоятельно разместить один экземпляр службы, и я, очевидно, теряюсь на уровне косвенности...

У меня есть базовый адрес http://localhost:8050/. Я не слишком обеспокоен тем, где конечная точка службы до тех пор, пока она предсказуема. На данный момент я пытаюсь использовать /Manage/.

Я могу перейти на базовый адрес и посмотреть wsdl. Если я просматриваю wsdl, он указывает на /Manage/..

<wsdl:service name="EngineService">
 <wsdl:port name="BasicHttpBinding_IEngineService" binding="tns:BasicHttpBinding_IEngineService">
 <soap:address location="http://localhost:8050/Manage/">
 </soap:address></wsdl:port>
</wsdl:service>

Когда я использую wsdl, используя WcfTestClient, он перечисляет все правильные методы, но вызов любого из них вызывает следующее исключение

System.ServiceModel.EndpointNotFoundException: не было прослушивание конечных точек в http://localhost:8050/Manage, которые могли бы принять это сообщение. Это часто вызвано неправильным адресом или действием SOAP. См. InnerException, если присутствует, для более подробной информации.

Server stack trace: 
 at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
 at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
 at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
 at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
 at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]: 
 at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
 at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
 at IEngineService.SupportedAgents()
 at EngineServiceClient.SupportedAgents()
Inner Exception:
The remote server returned an error: (404) Not Found.
 at System.Net.HttpWebRequest.GetResponse()
 at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

Журнальные сообщения показывают, что мои методы экземпляра никогда не вызываются. Служба не входит в состояние с ошибкой, она просто выглядит так, как будто она отсутствует.

Я слушаю следующее:

public static ServiceHost Listen<tservicecontract>(
 TServiceContract instance,
 int port,
 string name
 ) {
 //Added this for debugging, was previously just "name"
 string endpoint = String.Format("http://localhost:{0}/{1}/", port, name);
 var svcHost = new ServiceHost(
 instance,
 new Uri[] { new Uri(String.Format("http://localhost:{0}/", port)) });
 /* Snip: Add a Faulted handler but it never called */
 ServiceEndpoint serviceHttpEndpoint = svcHost.AddServiceEndpoint(
 typeof(TServiceContract),
 new BasicHttpBinding {
 HostNameComparisonMode = HostNameComparisonMode.WeakWildcard
 }, endpoint); /*Using name instead of endpoint makes no difference beyond removing the trailing slash */
 /* Snip: Add a ServiceDebugBehavior with IncludeExceptionDetailInFaults = true */
 /* Snip: Add a ServiceMetadataBehavior with HttpGetEnabled = true */
 try {
 log.Trace("Opening endpoint");
 svcHost.Open();
 } catch () {
 /* Lots of catches for different problems including Exception
 * None of them get hit */
 }
 log.Info("Service contract {0} ready at {1}", typeof(TServiceContract).Name, svcHost.BaseAddresses.First());
 return svcHost;
</tservicecontract>

И вызывая метод Listen() следующим образом:

IEngineService wcfInstance = Resolver.Resolve<iengineservice>();
 service = WcfHoster.Listen(wcfInstance, 8050, "Manage");
</iengineservice>

Как я могу отследить, что проблема /debug дальше?

Дополнительная информация: контракт на обслуживание и минимальная реализация:

[ServiceContract]
interface IEngineService {
 [OperationContract]
 List<string> Agents();
 [OperationContract]
 string Test();
 [OperationContract]
 List<string> SupportedAgents();
 [OperationContract]
 string Connect(string AgentStrongName, string Hostname);
}
</string></string>

И реализация:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class EngineService : IEngineService {
 IAgentManager agentManager;
 public EngineService(IAgentManager AgentManager) {
 log.Debug("Engine webservice instantiating");
 this.agentManager = AgentManager;
 }
 public string Connect(string AgentStrongName, string Hostname) {
 log.Debug("Endpoint requested for [{0}], [{1}]", Hostname, AgentStrongName);
 return agentManager.GetSession(AgentStrongName, Hostname);
 }
 public List<string> Agents() {
 log.Debug("Current agents queried");
 throw new NotImplementedException();
 }
 public List<string> SupportedAgents() {
 log.Debug("Supported agents queried");
 return agentManager.SupportedAgents().ToList();
 }
 public string Test() {
 log.Warn("Test query");
 return "Success!";
 }
}
</string></string>

Клиент теста может видеть службу и методы, но выдает исключение выше, когда я нажимаю Invoke...

Изменить: localhost разрешает IPv6 по умолчанию, поэтому я попытался использовать 127.0.0.1 явно на обоих концах. Нет разницы.

Я попытался использовать этот код в новом проекте и получить ту же проблему. Выполнение всего этого на чужой машине тоже не помогло.

Средство просмотра трассировки

Запуск трассировки служб на стороне сервера, а затем просмотр результатов в средстве просмотра дает:

Не удалось найти канал для приема входящего сообщения. Либо конечная точка, либо действие SOAP не были найдены.

Файл конфигурации. Поскольку мне нужен исполняемый файл, чтобы иметь возможность принять решение о том, какая служба Wcf будет отображаться во время выполнения, у меня нет никакого кода, связанного с Wcf, в файле конфигурации.

1 ответ

Это, вероятно, несоответствие привязки клиента/службы. Проверьте привязку тестового клиента. Вы также должны создать unit test, создав прокси-сервер из wsdl.

Ok. Я попытался воспроизвести вашу проблему, и мне удалось вызвать хост, удалив "HostNameComparisonMode = HostNameComparisonMode.WeakWildcard", чтобы получить конечную точку basichttp по умолчанию. Зачем вам это нужно?

licensed under cc by-sa 3.0 with attribution.