学会WCF之试错法——客户端调用基础

Posted 甜橙很酸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学会WCF之试错法——客户端调用基础相关的知识,希望对你有一定的参考价值。

1当客户端调用未返回结果时,服务不可用(网络连接中断,服务关闭,服务崩溃等)

 客户端抛出异常

异常类型:CommunicationException

InnerException:

 

Message:

接收对 http://localhost/S 的 HTTP 响应时发生错误。这可能是由于服务终结点绑定未使用 HTTP 协议造成的。这还可能是由于服务器中止了 HTTP 请求上下文(可能由于服务关闭)所致。有关详细信息,请参见服务器日志。

Stacktrace:

Server stack trace:

    System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)

    System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

    System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)

    System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)

    System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)

    System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)

    System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

 

Exception rethrown at [0]:

    System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)

    System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

    Client.IService.GetData(Int32 value)

    Client.ServiceClient.GetData(Int32 value) 位置 e:\\projgxz_myself\\WCF_Find_Error\\Client\\ServiceProxy.cs:行号 52

    Client.ServiceProxy.GetData(Int32 value) 位置 e:\\projgxz_myself\\WCF_Find_Error\\Client\\ServiceProxy.cs:行号 19

    Client.Program.Main(String[] args) 位置 e:\\projgxz_myself\\WCF_Find_Error\\Client\\Program.cs:行号 17

 

2 服务地址与元数据访问地址

服务器A192.168.107.13)上部署服务,服务端终结点配置为:http://localhost/S,元数据检索URI配置为http://localhost/S

在客户端(192.168.20.104)上访问A的服务,查看元数据。客户端浏览器输入网址:http://192.168.107.13/S

输出页面为:

 

点击页面链接:无法访问到A机器服务的元素据,这是合理的因为localhost代表本机的ip,此刻操作是在客户端的机器上,而不在服务器上;客户端的机器上并没有这个服务,所以服务端终结点配置为:http://localhost/S,元数据检索URI配置为http://192.168.107.13/S

 

当服务端终结点和元数据访问地址不统一时,服务端通信对象无法打开。

 

3对比无法获得异常真实原因的两种用法

服务端方法:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class Service : IService
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }
}

 

客户端代理:

public class ServiceProxy
    {
        public string GetData(int value)
        {
            string ret = null;
            ServiceClient client = null;
            try
            {
                client = new ServiceClient();
                ret = client.GetData(value);
                client.Close();
            }
            catch
            {
                if (client != null)
                {
                    client.Abort();
                }
                throw;
            }
            return ret;
        }
}

[ServiceContractAttribute(ConfigurationName = "IService")]
    public interface IService
    {

        [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService/GetData", ReplyAction = "http://tempuri.org/IService/GetDataResponse")]
        string GetData(int value);
}

public class ServiceClient : System.ServiceModel.ClientBase<IService>, IService
    {

        public ServiceClient()
        {
        }

        public string GetData(int value)
        {
            return base.Channel.GetData(value);
        }
}

 

客户端调用:

方式一

直接调用ServiceClient,调用数据返回后关闭客户端。

static void Main(string[] args)
{
            try
            {
          ServiceClient clients = new ServiceClient();
                clients.GetData(1);
          clients.Close();
            }
            catch (Exception ex)
            {
                clients.Abort();
            }
}

方式二:

在Main方法中将下面的代码用try...catch包起来。

                ServiceProxy proxy = new ServiceProxy();

                proxy.GetData(1);

方式三:

在Main方法中将下面的代码用try...catch包起来。

               using (ServiceClient client = new ServiceClient())

        {

                    client.GetData(1);

                }

 

方法一和方法二可以返回真实的原因,而方法三不能,他们的区别在于,方法三在客户端捕获异常之前关闭了客户端对象,而其他两种方式则是在获得异常信息后才关闭客户端对象的,所以由上面的测试又可得出WCF客户端程序中慎用using。

 

 

 

 

 

 

以上是关于学会WCF之试错法——客户端调用基础的主要内容,如果未能解决你的问题,请参考以下文章

学会WCF之试错法——数据传输

学会WCF之试错法——安全配置报错分析

can通信系统是啥意思

WCF系列教程之WCF客户端异常处理

从客户端调用 WCF 服务

php之试触法----error--关键字的误用