【发布时间】:2015-04-20 13:21:30
【问题描述】:
我正在尝试自托管服务的单例实例,但显然我在间接级别上迷路了......
我的基址是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/"/>
</wsdl:port>
</wsdl:service>
当我使用 WcfTestClient 使用 wsdl 时,它会列出所有正确的方法,但调用其中任何一个都会引发以下异常
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's 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;
并调用Listen()方法如下:
IEngineService wcfInstance = Resolver.Resolve<IEngineService>();
service = WcfHoster.Listen(wcfInstance, 8050, "Manage");
如何进一步追踪/调试问题所在?
附加信息:服务合同和最小实现:
[ServiceContract]
interface IEngineService {
[OperationContract]
List<string> Agents();
[OperationContract]
string Test();
[OperationContract]
List<string> SupportedAgents();
[OperationContract]
string Connect(string AgentStrongName, string Hostname);
}
以及实现:
[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!";
}
}
测试客户端可以看到服务和方法,但是点击Invoke时抛出上面的异常...
编辑:localhost 默认解析为 IPv6,因此我尝试在两端显式使用 127.0.0.1。没有区别。
我尝试将上述代码放入一个新项目并遇到同样的问题。在别人的机器上运行整个事情也没有帮助。
服务跟踪查看器
在服务器端运行service trace,然后在查看器中检查结果:
未能查找通道以接收传入消息。未找到端点或 SOAP 操作。
配置文件:由于我需要可执行文件来决定在运行时呈现哪个 Wcf 服务,因此我在配置文件中没有任何与 Wcf 相关的代码。
【问题讨论】:
-
你的异常发生在哪一行代码?
-
在使用服务的客户端,而不是进程托管服务本身,因此我很难调试
-
能否请您更具体一些,例如 try catch 或其他地方?
-
我的实际捕获有
CommunicationObjectFaultedException、TimeoutException和Exception的块。他们都没有受到打击。据我从主机进程中可以看出,服务加载正常,服务wsdl等......只是当调用任何方法时,我在客户端得到一个404。据我所知,主持人甚至没有看到那个电话。我显示的异常消息来自 Visual Studio 附带的 Wcf 测试客户端,用于测试正在使用的 Web 服务。如果你能澄清你想抓住什么,我会添加一个 try/catch -
很抱歉,我无法为您提供更多帮助。当你修好它时请告诉我:) 祝你好运。
标签: c# web-services wcf soap wsdl