代码改变世界

简单计算器——远程调用

2013-04-10 13:33  Keiven_LY  阅读(444)  评论(0编辑  收藏  举报

3.1 服务器端程序

第一步:新建一个控制台应用程序,取名Host,作为服务的宿主程序

第二步:右键Host——>添加——>新建项,选择WCF服务,取名Calculator.cs,系统自动生成ICalculator.cs,Calculator.cs和App.config文件;

第三步:在ICalculator.cs中添加契约,程序如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Host
{
    // 注意: 如果更改此处的接口名称 "ICalculatorService",也必须更新 App.config 中对 "ICalculatorService" 的引用。
    [ServiceContract]
    public interface ICalculatorService
    {
        //[OperationContract]
        //void DoWork();
        [OperationContract]
        double Add(double x, double y);
        [OperationContract]
        double Subtract(double x, double y);
        [OperationContract]
        double Multiply(double x, double y);
        [OperationContract]
        double Divide(double x, double y);
    }
}

第四步:在Calculator.cs中添加契约的实现方法,程序如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Host
{
    // 注意: 如果更改此处的类名 "CalculatorService",也必须更新 App.config 中对 "CalculatorService" 的引用。
    public class CalculatorService : ICalculatorService
    {

        public double Add(double x, double y)
        {
            return x + y;
        }
        public double Subtract(double x, double y)
        {
            return x - y;
        }
        public double Multiply(double x, double y)
        {
            return x * y;
        }
        public double Divide(double x, double y)
        {
            return x / y;
        }
    }
}

3.2 客户端程序

第一步:新建一个Windows窗体应用程序,取名为CalculatorClient

第二步:设计计算器界面如下:

第三步:启动服务器,即将服务发布出去

第四步:添加服务引用,将服务端的地址填入地址(A)栏,点击前往,出现CalculatorService服务,修改命名空间为ServiceReference,如下图,点击“确定”即可。

第五步:修改app.config中的代码

系统自动生成的客户端终结点代码:

<client>
     <endpoint address="http://localhost:8731/CalculatorService/"
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculatorService"
     contract="ServiceReference.ICalculatorService" name="WSHttpBinding_ICalculatorService">
           <identity>
                    <dns value="localhost"/>
            </identity>
      </endpoint>
</client>

修改为:

<client>
     <endpoint address="http://10.3.11.162:8731/CalculatorService/"
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculatorService"
     contract="ServiceReference.ICalculatorService" name="WSHttpBinding_ICalculatorService">
           <identity>
                    <dns value="10.3.11.162"/>
            </identity>
      </endpoint>
</client>

注:将原来的localhost改为服务器的ip地址

第六步:运行,在此之前,服务器必须运行

运行出错啦!!

异常1:

“http://tempari.org/ICalculatorService/Add”不正确,消息包含无效或过期的安全上下文令牌,或绑定之间出现不匹配

解决方法:

将客户端的配置文件app.config中的安全模式由“message”改为“None”

即:<security mode="Message">变为<security mode="None">

运行还是出错!!

异常2:

调用方未由服务进行身份验证

解决方法:

上网查找,说要在服务器端App.config添加bingding部分,参考网址链接:http://apps.hi.baidu.com/share/detail/9239981

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="Host.CalculatorServiceBehavior">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
      
      <!—添加binding-->
      <bindings>
        <wsHttpBinding>
          <binding name="NoneSecurity"
            maxBufferPoolSize="12000000" maxReceivedMessageSize="12000000" useDefaultWebProxy="false">
            <readerQuotas maxStringContentLength="12000000" maxArrayLength="12000000"/>
            <security mode="None"/>
          </binding>
        </wsHttpBinding>
      </bindings>
      <!-- 添加完毕-->


   <!-- 远程调用时,需要添加bindingConfiguration="NoneSecurity",本机调用时不需要添加-->
      <services>
            <service behaviorConfiguration="Host.CalculatorServiceBehavior"
                name="Host.CalculatorService">
                <endpoint address="" binding="wsHttpBinding"  bindingConfiguration="NoneSecurity" contract="Host.ICalculatorService">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8731/CalculatorService/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>
</configuration>

客户端将安全模式改为:<security mode="None">

运行还是出错,询问技术群,可能服务器端,添加绑定部分,参数设置不对

参考网址链接:http://blog.csdn.net/woxpp/article/details/6732123

修改为:

<bindings>
    <wsHttpBinding>
        <binding name="NoneSecurity">
            <security mode="None"/>
         </binding>
     </wsHttpBinding>
</bindings>

运行,终于成功!!!