在本次实验中,你将会将一个普通的C/S程序移植为一个WCF的C/S程序。并且你也将会尝试不同的方式来完成WCF的配置工作,尝试不同的宿主方式和绑定设置。
经典Client/Server程序
打开Essentials文件夹下的WCFEssentials.sln解决方案。解决方案中包含了一个名字为MyClient的winform客户端和一个名为Service的类库。在Service project中可以看到MyService类实现了IMyContract:
{
void MyMethod();
void MyOtherMethod();
}
public class MyService : IMyContract
{
public void MyMethod()
{
MessageBox.Show("MyMethod()","MyService");
}
public void MyOtherMethod()
{
MessageBox.Show("MyOtherMethod()","MyService");
}
}
点击button不会有任何反应,因为button事件还没有添加任何代码。
关闭客户端。选择client项目并添加到service项目的引用。在client端的button click事件中添加如下代码:
{
IMyContract service = new MyService();
service.MyMethod();
}
编译项目确保没有错误发生。
定义WCF服务
选择Service项目并添加引用到System.ServiceModel.dll。在MyService.cs文件中添加using语句:
using System.ServiceModel;
通过添加ServiceContract和OperationContract将IMyContract接口定义为WCF契约,并去掉public的定义:
interface IMyContract
{
[OperationContract]
void MyMethod();
[OperationContract]
void MyOtherMethod();
}
同样去掉MyService的public定义:
宿主服务
我们将把服务宿主到一个控制台程序。选中service项目,并打开属性页。在Application页签中,选择Console Application作为输出类型:
下一步,在service项目中添加一个名为Program.cs的文件,并在其中添加main方法。并在main方法中添加宿主的代码:
class Program
{
static void Main()
{
Uri baseAddress = new Uri("http://localhost:8000/");
ServiceHost host = new ServiceHost(typeof(MyService), baseAddress);
host.Open();
Console.WriteLine("Host open. Type any key to close");
Console.ReadLine();
host.Close();
}
}
配置服务
为service项目添加App.config文件(文件名必须为App.config)。并在配置文件中为服务添加三个endpoint:
<configuration>
<system.serviceModel>
<services>
<service name="MyService">
<endpoint
address="MyService"
binding="wsHttpBinding"
contract="IMyContract" />
<endpoint
address="http://localhost:8001/MyService/"
binding="wsHttpBinding"
contract="IMyContract" />
<endpoint
address="net.tcp://localhost:8002/MyService/"
binding="netTcpBinding"
contract="IMyContract" />
</service>
</services>
</system.serviceModel>
</configuration>
将Metadata Exchange置为有效
为service添加属性,将Metadata Exchange置为有效:
<services>
<service name="MyService" behaviorConfiguration="MEX Enabled">
……
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MEX Enabled">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
客户端编码
将client项目中对service项目的引用移除,并添加对System.ServiceModel.dll的引用。
在client项目中添加名为Proxy的类。为了简单,我们将命名空间MyClient删除,并重命名Proxy类为MyContractClient:
class MyContractClient
{
}
将contract的定义添加到proxy文件的顶部
interface IMyContract
{
[OperationContract]
void MyMethod();
[OperationContract]
void MyOtherMethod();
}
class MyContractClient
{
}
将MyContractClient类修改为继承ClientBase<IMyContract>并实现接口IMyContract:
{
public void MyMethod()
{
Channel.MyMethod();
}
public void MyOtherMethod()
{
Channel.MyOtherMethod();
}
}
修改client端的按钮事件,使用代理类来完成:
{
MyContractClient proxy = new MyContractClient();
proxy.MyMethod();
proxy.Close();
}
配置客户端
Client端我们将使用service端的TCP endpoint。为client项目添加App.config。并添加如下配置:
<configuration>
<system.serviceModel>
<client>
<endpoint
address="net.tcp://localhost:8002/MyService/"
binding="netTcpBinding"
contract="IMyContract" />
</client>
</system.serviceModel>
</configuration>
测试应用程序
将解决方案设置为多项目启动,如图:
然后直接F5就可以了。
使用VS2008自动配置客户端
将解决方案设置为单项目启动,并把service项目设为启动项目。启动service但不要进入调试。为client项目添加service reference。在地址栏中输入http://localhost:8000/,点击Go按钮:
点击OK后,VS2008会为你自动生成客户端代理在命名空间:MyClient.ServiceReference下。
在client项目中删除Proxy.cs。打开ClientForm.cs文件,并添加using语句:
using System.ServiceModel;
VS2008会重新修改配置文件。打开app.config并修改它为如下所示(很多东西是不需要的):
<configuration>
<system.serviceModel>
<client>
<endpoint
address="net.tcp://localhost:8002/MyService/"
binding="netTcpBinding"
contract="ServiceReference.IMyContract"
/>
</client>
</system.serviceModel>
</configuration>
保存所有修改并编译后测试程序。
使用Channel Factory
使用channel factory,我们只需要一个interface的定义。打开Proxy.cs文件,删除MyContractClient类的定义。
在ClientForm.cs文件中,添加using语句:
using System.ServiceModel;
修改OnCallService方法,使用ChannelFactory<T>:
{
ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>("");
IMyContract proxy = factory.CreateChannel();
proxy.MyMethod();
ICommunicationObject channel = proxy as ICommunicationObject;
channel.Close();
}
编译并测试程序。
使用自动宿主工具
.NET3.5提供了两个简单的工具—WcfSvcHost.exe用于宿舍服务,WcfTestClient.exe用于测试client。下面我们将会同时使用它们。
在解决方案中删除client项目。
将service项目改为Class Library。
在Debug页签中,选中Start external program,并浏览到文件:C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ WcfSvcHost.exe。在Command line arguments中输入:/service:Service.dll /config:Service.dll.config /client:WcfTestClient.exe。如图:
接下来,在service项目中删除Program.cs文件。在config文件中需要添加base address:
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/"/>
</baseAddresses>
</service>
接下来运行项目,在系统托盘会看到如下图标:
测试工具将会弹出:
在任意一个endpoint中选中MyMethod()方法,并点击Invoke按钮,就可以进行测试了。