学习了wcf一周了,趁着周末,记录下来,温故一下。不对的地方请多多指教!
一.WCF出现的背景
二.契约方法的同步,异步调用方式
三.WCF的无配置
一.WCF出现的背景
.net平台下,有很多的分布式技术
1. webservice 基于http协议的soap模式。。。
2. remoting 也是一种分布式架构技术,常常用于tcp模式的二进制传输。。。
3. MSMQ 这是一种分布式的离线式技术,用于业务解耦。
面对上面那3中需求,我们是不是需要整合一下,所以wcf应运而出了。
我们先理解以下慨念,方便我们对 wcf的理解
(1)ABC的概念
①:A:address:服务的地址
②:B:binding:client和service的通道,比如我们访问web,我们使用http通道。 那么wcf支持哪些通道呢?如:BasicHttpBinding,NetTcpBinding等等。
③:C:contract 我们定义的接口是怎么样的,参数,返回值,方法名。
(2)承载WCF的宿主:IIS,Console,winform
什么是宿主呢?
WCF服务类不能凭空存在。每个WCF服务都必须托管(Hosting) 在Windows 进程中,该进程被称为宿主进程(Host Process)。单个宿主进程可以托管多个服务,而相同的服务类型也能够托管在多个宿主进程中。
按我的理解应该是这样的:假如A和B是两个http地址,我们都在C公司上班(宿主),
去上班时我们可以从相同的门进入办公室(port),也就是说,宿主相当于托管。
二.契约方法的同步,异步调用方式
(1)WCF中常见的三种绑定方式
1. basichttpbinding...
2. nettcpbinding...
3. netmsmqbinding...
net程序互通的binding, 一般都是netxxxxxbinding...
非net程序互通的binding. 一般都是wsxxxxbinding...
(2)契约中的调用方式。 client和servcie之间的调用方式。
1. 同步方式: 阻塞式方式【默认的调用方式】
Service端
public class FlyService : IFlyService
{
public string Fly(string message)
{
//阻塞5s
Thread.Sleep(5000);
Console.WriteLine("接收了Fly消息:{0}-{1}",message,DateTime.Now);
return message+DateTime.Now;
}
}Client
ServiceReference1.FlyServiceClient flyClient = new ServiceReference1.FlyServiceClient();
Console.WriteLine("开始调用:{0}",DateTime.Now);
string res = flyClient.Fly("Hello World");
Console.WriteLine("结束调用:{0}",res);
2. 异步方式:
①第一种异步方式:开一个线程来访问WCF
Task.Factory.StartNew(() =>
{
string res = flyClient.Fly("Hello World");
Console.WriteLine("子线程访问:{0}",res);
});运行结果我就不上传图片了,主要来讲下第二步是怎么实现的。
②我们在控制面板中使用生成异步操作。
首先,配置下服务引用,如下图
然后我们在Reference上会看到生成如下几个异步方法,也就是证明我们配置成功咯,接下来就开始撸代码了。
/*按F12进入,我们可以看到如下代码
public System.IAsyncResult BeginFly(string message, System.AsyncCallback callback, object asyncState) {
return base.Channel.BeginFly(message, callback, asyncState);
}
我们来分析下传的形参
message:传给接口的参数
callback:回调函数
asyncState:状态
*/
flyClient.BeginFly("hello World", new AsyncCallback((obj) =>
{
var myClient = (FlyServiceClient)obj.AsyncState;
string res = myClient.EndFly(obj);
Console.WriteLine("调用结束:{0}", res);
}), flyClient);
三.WCF的无配置
1. 我们在开启ServiceHost的时候,启用了一些配置文件.
也就是说这些config信息最终会被C#代码读取,然后C#代码会动态的去读取config,那何不我们自己去写呢??
这样的话,我们就可以最小化配置.
2.首先我们可以在ServiceHost上面开启一个监听器,用我们自己的代码来实现配置文件。
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;
namespace WcfServiceLHost
{
class Program
{
static void Main(string[] args)
{
#region
//// <host>
//// <baseAddresses>
//// <add baseAddress="http://localhost:8733/MyService" />
//// </baseAddresses>
////</host>
//ServiceHost host = new ServiceHost(typeof(Service1), new Uri("http://localhost:8733/MyService/"));
////这是我们服务的地址
//// <endpoint address="" binding="basicHttpBinding" contract="WcfServiceConfig.IFlyService">
//// <identity>
//// <dns value="localhost" />
//// </identity>
////</endpoint>
//host.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), string.Empty);
////mex元数据的地址
//// <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
//host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
////host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
//// <behaviors>
//// <serviceBehaviors>
//// <behavior name="">
//// <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
//// <serviceDebug includeExceptionDetailInFaults="false" />
//// </behavior>
//// </serviceBehaviors>
////</behaviors>
////host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true, HttpsGetEnabled = true });
////var single = host.Description.Behaviors.Find<ServiceDebugBehavior>();
////single.IncludeExceptionDetailInFaults = false;
//host.Open();
//Console.WriteLine("WCF开启!");
//Console.ReadKey();
#endregion
//// <host>
//// <baseAddresses>
//// <add baseAddress="http://localhost:8733/MyService" />
//// </baseAddresses>
////</host>
ServiceHost host = new ServiceHost(typeof(Service1), new Uri("http://localhost:8733/MyService/"));
//// <endpoint address="" binding="basicHttpBinding" contract="WcfServiceConfig.IFlyService">
//// <identity>
//// <dns value="localhost" />
//// </identity>
////</endpoint>
//这是我们服务的地址
host.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), string.Empty);
//// <behaviors>
//// <serviceBehaviors>
//// <behavior name="">
//// <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
//// <serviceDebug includeExceptionDetailInFaults="false" />
//// </behavior>
//// </serviceBehaviors>
////</behaviors>
//mex元数据的地址
host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
//<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
//mex元数据的地址
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
host.Open();
Console.WriteLine("WCF 服务开启");
Console.Read();
}
}
}
本文出自 “11581236” 博客,谢绝转载!
原文:http://11591236.blog.51cto.com/11581236/1879337