您的位置:首页 > 其它

WCF学习笔记(一)创建一个简单的Demo

2012-12-12 10:09 357 查看
由于很久没用WCF,导致今本配置都忘了,今天又一次温习了一遍,顺便做下记录吧,也分享给大家一下。基础知识大概就不提了。很多百度都能找到。

1.什么是WCF

Windows通信基础(Windows Communication Foundation,WCF)是基于Windows平台下开发和部署服务的软件开发包(Software Development Kit,SDK)。WCF为服务提供了运行时环境(Runtime
Environment),使得开发者能够将CLR类型公开为服务,又能够以CLR类型的方式使用服务。理论上讲,创建服务并不一定需要WCF,但实际上,使用WCF却可以使得创建服务的任务事半功倍。WCF是微软对一系列产业标准定义的实现,包括服务交互、类型转换、封送(Marshaling)以及各种协议的管理。

2.建立简单的框架





Client:Windows窗体应用程序,这里是当作客户端的。引用System.ServiceMode程序集
和Contract
Contract:类库,用来定义服务的契约的,主要存放的都是Interface。 引用System.ServiceMode程序集

Hosting:Windows窗体应用程序,用来当作宿主,Service中的服务寄宿在着。引用System.ServiceMode、Contract、Service

Service:类库,提供所有契约的实现,可以当作业务逻辑层。Contract、Service

[b]3.建立服务契约

[/b]
WCF包含四种类型的契约:服务契约、数据契约、消息契约和错误契约,这里着重于服务契约。从功能上讲,服务契约抽象了服务提供的所有操作;而站在消息交换的角度来看,服务契约则定义了基于服务调用的消息交换过程中,请求消息和回复消息的结构,以及采用的消息交换模式。

一般来说服务的契约用的是接口来定义的!我们将一个IUser定义成服务契约。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace Contract
{
[ServiceContract ]
public interface IUser
{
[OperationContract]
String GetName();
}
}
在WCF中,Contract的功能实际上就定义一个Service包含哪些可用的Operation,以及的每个Opertaion的方法签名。

4.建立服务

当服务契约创建成功后,我们只需要实现契约中的所有方法即可,在service项目中,直接创建一个UserService类,直接实现IUser即可。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Contract;
using System.ServiceModel;

namespace Service
{
public class CalculatorService : IUser
{

public String GetName()
{
return "WCF!";
}
}
}


5.建立宿主

WCF往往是通过寄宿在别的进程中来监听我们的客户端的,这里的别的宿主一般都是:Managed
Application——Console Application、WinForm Application、ASP.NET Application或者是Windows Service中和IIS中 这些都可以。

我们知道WCF中,Client端和Service端是通过Endpoint来通信的,Endpoint有包含3个部分,经典地称为ABC。

A代表Address,它包含一个URI,它指明Service存在于网络的某个地方,也就是说它为Client断指明在什么地方去找到这个Service。

B代表Binding,Binding封装了所有Client和Service段消息交换的通信细节。Binding是可以自定义实现的,可WCF框架已经为我们实现了足够多的Binding。
另外一篇文章介绍《Binding的选择》

C代表Contract这在上面已经说过,就是契约

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Contract;
using Service;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Hosting
{
public partial class HostForm : Form
{
public HostForm()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
HostingServiceViaCode();
}
public void HostingServiceViaCode()
{
//指定基地址,TCP的写法为:net.tcp://localhost:8000/XX
Uri baseUri = new Uri("http://localhost:30525/calculatorService");
//创建一个新的ServiceHost对象,并指定相应的  服务和基地址
//建议应用使用模式来确定  这个服务主机可以被正常关闭。
//第一个参数是 服务的实例,第二个参数是基地址。
ServiceHost calculatorServiceHost = new ServiceHost(typeof(UserService), baseUri);

//创建一个Binding TCP为:NetTcpBinding
BasicHttpBinding Binding = new BasicHttpBinding();
//创建一个服务端点通过指定的地址(这是绝对或相对路径基于基地址,空字符串表示地址等于基地址),
//第一个参数是契约,第二个是绑定终结点,第三个是终结点的地址 空的话就是基地址
calculatorServiceHost.AddServiceEndpoint(typeof(IUser),
Binding, string.Empty);
//这样的一段代码展示了如何让剪元数据  暴露在外部世界通过设置服务元数据的行为
//找到服务元数据的行为如果存在,类型,不存在返回null
ServiceMetadataBehavior behavior = calculatorServiceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();

//如果服务元数据的行为不添加到服务。  
//我们将创建一个新的HttpGetEnabled&HttpGetUrl和评估  
//让外部世界可以检索元数据。
if (behavior == null)
{
behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
//HttpGetUrl是绝对或相对基于基地址
behavior.HttpGetUrl = baseUri;
//我们必须添加新的行为创建行为集合,
//otherwize它永远不会生效。
calculatorServiceHost.Description.Behaviors.Add(behavior);
}
//如果元数据的行为存在于行为集合,我们只需要评估HttpGetEnabled&HttpGetUrl
else
{
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = baseUri;
}
//添加事件处理程序来打开做一个友好的消息显示 打开后服务主机指示 这项服务开始倾听来自客户机的请求。
calculatorServiceHost.Opened += delegate
{
Console.WriteLine("服务已经启动,开始监听:{0}",
calculatorServiceHost.BaseAddresses[0].ToString());
};
//打开服务主机让它开始监听客户
calculatorServiceHost.Open();

}

}
}

注册代码是在加载事件里面写的,所以窗口运行后,就开始监听我们的端口了。附一张运行的样子。



6.建立客户端

当我们把服务端完成后,就可以建立客户端来调用我们的服务。

创建服务代理的方法,就是通过ChannelFactory<T>通过他,我们可以获得我们的服务。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Contract;
using System.ServiceModel;

namespace Client
{
public partial class ClientForm : Form
{
public ClientForm()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void button1_Click(object sender, EventArgs e)
{
IUserr uu = ChannelFactory<IUser>.CreateChannel(new BasicHttpBinding(),
new EndpointAddress("http://localhost:30525/calculatorService"));
MessageBox.Show(uu.GetName());
}
}
}

这个简单的Demo 并没有用到配置文件,所有配置方法基本是通过代码配置的。灵活性基本没有的。我们也可以通过配置的方法来实现,这样大大提高了灵活性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: