【4】实现代码分析
上面介绍了WCF相关的一些基本概念、特性和框架模型,现在我们来具体实现一个WCF的应用实例。客户端和WCF服务通信的过程如图:
客户端通过代理调用WCF服务,代理通过服务地址找到特定的服务,调用执行特定的服务方法。
我们代码的演示部分也分为3个部分,首先是服务类(契约部分),其次是宿主(自己定义一个控制台程序),客户端(控制台)。
【4.1】契约(Contract)
定义实现的代码包括服务契约IWCFService、操作契约OperationContract、和数据契约DataContract。具体代码实现如下:
Code
//ServiceContract 属性以及 Indigo 使用的所有其他属性均在 System.ServiceModel 命名空间中定义,
//因此本例开头使用 using 语句来引用该命名空间。
namespace WCFService
{
//1.服务契约
[ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
public interface IWCFService
{
//操作契约
[OperationContract]
string SayHello(string name);
//操作契约
[OperationContract]
string SayHelloToUser(User user);
}
//2.服务类,集成接口。实现契约
public class WCFService : IWCFService
{
//实现接口定义的方法
public string SayHello(string name)
{
Console.WriteLine("Hello! {0},Using string ", name);
return "Hello! " + name;
}
//实现接口定义的方法
public string SayHelloToUser(User user)
{
Console.WriteLine("Hello! {0} {1},Using DataContract ", user.FirstName, user.LastName);
return "Hello! " + user.FirstName + " " + user.LastName;
}
}
//3.数据契约//序列化为XML,作为元数据封装到服务里
[DataContract]
public struct User
{
[DataMember]
public string FirstName;
[DataMember]
public string LastName;
}
}
【4.2】宿主(托管进程)
WCFHost宿主进程托管服务WCFService,项目类型也为控制台应用程序(你也可以创建其他的项目类型)。这里要添加对WCFService类库的引用。托管采用反射方式动态创建服务的实例。具体代码如下:
Code
//采用自托管方式,也可以是IIS、WAS,Windows服务等用户自定义程序托管服务
public class WCFHost
{
static void Main(string[] args)
{
//反射方式创建服务实例,
//Using方式生命实例,可以在对象生命周期结束时候,释放非托管资源
using (ServiceHost host = new ServiceHost(typeof(WCFService.WCFService)))
{
//相同的服务注册多个基地址
//添加服务和URI,用户资源标识符
//Uri tcpAddress = new Uri("http://localhost:8001/WCFService");
Uri httpAddress = new Uri("http://localhost:8002/WCFService");
//Uri httpAddressLisening = new Uri("http://localhost:8002/WCFService");
//host.AddServiceEndpoint(typeof(WCFService.IWCFService), new WSHttpBinding(), tcpAddress);
host.AddServiceEndpoint(typeof(WCFService.IWCFService), new WSHttpBinding(), httpAddress);
//判断是否以及打开连接,如果尚未打开,就打开侦听端口
//if (host.State !=CommunicationState.Opening)
host.Open();
//显示运行状态
Console.WriteLine("Host is runing! and state is {0}",host.State);
//等待输入即停止服务
Console.Read();
}
}
}
这里值得注意的就是绑定协议要和配置文件里的设置一样,不然会出现编译错误或者运行时异常。编译结束会生成可执行文件EXE。
【4.3】客户端
客户端要添加对以上服务的引用,如果你初次建立服务,配置不当很容易出现引用服务失败的问题,配置服务相关的错误和解决办法我也整理到WCF分布式开发常见错误解决里了,大家需要的话可以参考,是在遇到苦难可以留言给我一起交流。
客户端的具体实现代码如下:
Code
class WCFClient
{
static void Main(string[] args)
{
//IWCFService proxy = ChannelFactory.CreateChannel(new WSHttpBinding(),
//////new EndpointAddress("net.tcp://localhost:8001/WCFService"));
////new EndpointAddress("http://localhost:8002/WCFService"));
WCFServiceClient wcfServiceProxy = new WCFServiceClient("WSHttpBinding_IWCFService1");
//通过代理调用SayHello服务
Console.WriteLine(wcfServiceProxy.SayHello("Frank Xu Lei"));
////通过代理调用调用SayHelloToUser,传递对象
User user = new User();
user.FirstName = "Lei";
user.LastName = "Frank";
Console.WriteLine(wcfServiceProxy.SayHelloToUser(user));
Console.Read();
}
}
这里可以通过两种方式调用WCF服务,一种是自己编码实现客户端服务代理,要正确添加服务的地址。第二种是当客户端添加服务成功以后,VS2008集成开发工具会在客户端自动生成服务端的操作契约、服务契约等信息,当然包含客户端服务代理类,这个比较关键。具体方法就是在客户端项目右键添加服务应用。输入服务侦听的地址。查找到服务后添加引用会生成一系列服务引用的文件,如图:
【4.4】运行结果:
首先要启动服务宿主进程WCFhost.如图:
其次运行客户端,结果如图所示: