WCF服务承载
自托管(也做自承载)
承载 WCF 服务最灵活、最便捷的方法就是进行自承载。要能够自承载服务,必须满足两个条件。第一,需要 WCF 运行时;第二,需要可以承载 ServiceHost 的托管 .NET 应用程序。您需要自己动手编写启动和停止宿主的代码。
什么时候使用自托管?
当应用程序的各个组件之间需要相互通信,或者在一个本地环境中,客户端和事务的数量都十分受限是常使用自托管。对于企业级方案来说不应考虑自承载方式。自承载适用于企业项目的开发或演示阶段。此外,当您希望用户桌面应用程序进行相互通信或在点对点情况下,可以对服务进行自承载。
自承载的优点:
• 易用性:只需几行代码即可使服务运行。
• 灵活性:通过 ServiceHost<T> 的 Open() 和 Close() 方法,可以轻松控制服务的生存期。
• 易调试性:可以使用熟悉的调试方式对自承载环境中承载的 WCF 服务进行调试,而不必连接到单个应用程序来激活服务。
• 易部署性:通常,部署简单 Windows 应用程序与使用 xcopy 一样容易。您不必在服务器场和类似地方部署复杂的方案,即可部署简单的 Windows 应用程序来充当 WCF ServiceHost。
• 支持所有绑定和传输:自承载并不限制您仅能使用现有的绑定和传输技术。在 Windows XP 和 Windows Server 2003 上,IIS 限制您只能使用 HTTP。(备注:II6以下)
下面是自承载的缺点:
•可用性受到限制:服务只有在应用程序运行时才能被访问。
•功能受到限制:自承载的应用程序在对高可用性、易管理性、可靠性、可恢复性、版本控制和部署方案的支持方面受到一定限制。至少,现有的 WCF 无法提供这些支持,因此在自承载的情况中,您必须自己实现这些功能;例如,默认情况下 IIS 提供了这些功能中几项。
下面是一个小例子
1 using System.ServiceModel;
2
3 namespace Halower.SelfHost
4 {
5 [ServiceContract(Namespace = "http://www.cnblogs.com/rohelm")]
6 public interface ICalcuContract
7 {
8 [OperationContract]
9 double Add(int x, int y);
10
11 [OperationContract]
12 double Substrate(int x, int y);
13
14 [OperationContract]
15 double Multiply(int x, int y);
16
17 [OperationContract]
18 double Divide(int x, int y);
19 }
20 }
1 namespace Halower.SelfHost
2 {
3 public class CalculatorService : ICalcuContract
4 {
5 public double Add(int x, int y)
6 {
7 return x + y;
8 }
9
10 public double Substrate(int x, int y)
11 {
12 return x - y;
13 }
14
15 public double Multiply(int x, int y)
16 {
17 return x * y;
18 }
19
20 public double Divide(int x, int y)
21 {
22 return x / y;
23 }
24 }
25 }
1 using System;
2 using System.ServiceModel;
3 using System.ServiceModel.Description;
4
5 namespace Halower.SelfHost
6 {
7 internal class Program
8 {
9 private static void Main(string[] args)
10 {
11 Uri[] baseAddresses = new Uri[] {
12 new Uri("http://localhost:10101/CalculatorService"),
13 new Uri("net.tcp://localhost:10102/CalculatorService")
14 };
15 using (ServiceHost host = new ServiceHost(typeof(CalculatorService), baseAddresses))
16 {
17 host.AddDefaultEndpoints();
18 try
19 {
20 host.Open();
21 Console.WriteLine("WCF服务已经启动!");
22 foreach (var endpoint in host.Description.Endpoints)
23 {
24 Console.WriteLine("\t" + endpoint.Address.Uri.ToString());
25 }
26 Console.ReadKey();
27 }
28 catch (CommunicationException ex)
29 {
30 host.Abort();
31 }
32 }
33 }
34 }
35 }
虽然我们知道每一个服务的实现只能有一个serviceHost,但是可以公开多个终结点和接口,同理,我们可以在同一个进程中创建多个serviceHost,而且我们有时候有需求控制他们的启动顺序,我们就是可以尝试着使用一下serviceHost异步启动的方式。
1 using System;
2 using System.ServiceModel;
3
4 namespace Halower.SelfHost
5 {
6 internal class Program
7 {
8 private static void Main(string[] args)
9 {
10 Uri[] baseAddresses = new Uri[] {
11 new Uri("http://localhost:10101/CalculatorService"),
12 new Uri("net.tcp://localhost:10102/CalculatorService")
13 };
14 using (ServiceHost host = new ServiceHost(typeof(CalculatorService), baseAddresses))
15 {
16 host.AddDefaultEndpoints();
17 IAsyncResult result = host.BeginOpen(new AsyncCallback(ServiceHostOpenCallBack), null);
18 while (!result.IsCompleted)
19 {
20 Console.WriteLine("做一些与服务无关的事情");
21 }
22 Console.ReadKey();
23 }
24 }
25
26 private static void ServiceHostOpenCallBack(IAsyncResult ar)
27 {
28 Console.WriteLine("服务1已经启动!");
29 ServiceHost host2 = new ServiceHost(typeof(CalculatorService), new Uri("http://localhost:10103/CalculatorService"));
30 Console.WriteLine("服务2即将启动!");
31 host2.Open();
32 Console.WriteLine("服务2已经启动!");
33 host2.Close();
34 }
35 }
36 }
什么有时候需要自定义serviceHost?
有些时候,我们需要在不同的地方重用配置参数相同的同一个ServiceHost类,例如,我们已经创建了一个ServiceHost对象,可以用编码的方式控制服务配置或者部分配置。在这种情况下,如果使用这个类,就需要扩展并编写自定义的ServiceHost类的实现。
例如,.NET Framework 提供了专门宿主实现,都极大的方便了我们的操作,而不去自己配置某些关键项:
WorkflowServiceHost 类,为基于工作流的服务提供宿主。
WebServiceHost 类,它是对 Windows Communication Foundation (WCF) REST 编程模型的补充
1 [ServiceContract]
2 public interface ICalculator
3 {
4 [OperationContract]
5 [WebInvoke(UriTemplate = "add?x={x}&y={y}")]
6 long Add(long x, long y);
7
8 [OperationContract]
9 [WebInvoke(UriTemplate = "sub?x={x}&y={y}")]
10 long Subtract(long x, long y);
11
12 [OperationContract]
13 [WebInvoke(UriTemplate = "mult?x={x}&y={y}")]
14 long Multiply(long x, long y);
15
16 [OperationContract]
17 [WebInvoke(UriTemplate = "div?x={x}&y={y}")]
18 long Divide(long x, long y);
19
20 [OperationContract]
21 [WebGet(UriTemplate = "hello?name={name}")]
22 string SayHello(string name);
23 }
24
25 public class CalcService : ICalculator
26 {
27 public long Add(long x, long y)
28 {
29 return x + y;
30 }
31
32 public long Subtract(long x, long y)
33 {
34 return x - y;
35 }
36
37 public long Multiply(long x, long y)
38 {
39 return x * y;
40 }
41
42 public long Divide(long x, long y)
43 {
44 return x / y;
45 }
46
47 public string SayHello(string name)
48 {
49 return "Hello " + name;
50 }
51 }
52
53 class Program
54 {
55 static void Main(string[] args)
56 {
57 Uri baseAddress = new Uri("http://localhost:8000/");
58
59 WebServiceHost svcHost = new WebServiceHost(typeof(CalcService), baseAddress);
60
61 try
62 {
63 svcHost.Open();
64
65 Console.WriteLine("Service is running");
66 Console.WriteLine("Press enter to quit...");
67 Console.ReadLine();
68
69 svcHost.Close();
70 }
71 catch (CommunicationException cex)
72 {
73 Console.WriteLine("An exception occurred: {0}", cex.Message);
74 svcHost.Abort();
75 }
76 }
77 }
自定义ServiceHost类说起来用以做起来难,简单的说,如果我们直接继承自ServiceHost,我们要从读取配置文件读取参数后修改他们就重写ServiceHost类的ApplyConfiguration,如果是在宿主创建之前修改配置参数,就可重写ServiceHost类的Opening方法。
IIS承载
在 IIS 上的 Web 服务开发长期以来一直是 ASP.NET 的领地。ASP.NET 1.0 发布后,Web 服务框架成为它的一部分。Microsoft 利用 ASP.NET HTTP 管道使 Web 服务在 Windows 平台上成为现实。遗憾的是,ASP.NET 和 Web 服务之间的这种紧密耦合在面向服务的世界中产生了几个限制,对 HTTP 的依赖性是主要原因。在不同宿主上运行 ASP.NET HTTP 管道很困难,因此很少采用这种方案。甚至在此后,ASP.NET Web 服务(也称为 ASMX 服务)在部署方案和配置依赖性方面一直是非常面向 Web 的。Microsoft 最初发布了几个版本的 Web 服务增强 (WSE),以弥补 ASP.NET Web 服务的某些局限,尤其是消除在实现 WS-* 协议方面的限制。但是,WSE 非常依赖于 ASP.NET Web 服务实现。
WCF 服务采用了完全不同的途径来实现面向服务。WCF 的统一编程模型基于严格分层的模型,以分解面向 Web 的范例,并使服务模型和通道层与受支持的传输方式断开连接。此模型允许 WCF 支持几个不同的宿主,其中 IIS 是最重要的。
构建 WCF 是为了支持 Windows XP、Windows Server 2003、Windows Vista 和 Windows Server 2007。自从 IIS 5.1(与 Windows XP 一起发布)以来,有了很多变化。但是,Microsoft 仍然继续支持旧版上的 WCF。这可能是因为 Microsoft .NET Framework 和 CLR 提供的功能所导致的,该功能是构建 WCF 的基础。
IIS 7.0 推动了 Web 服务器领域中的又一重大演进。可以在图中看到两个重要改变。第一,现在特定于协议的侦听器适配器支持所有四种 WCF 传输,而不是仅限于 IIS 6.0 中的 HTTP 传输。此外,出现了称为 Windows 激活服务 (WAS) 的新操作系统服务。W3svc.exe 和 WAS 都运行在称为 SvcHost.exe 的操作系统宿主的内部。为了能够将 IIS 6.0 进程模型的强大功能与 WCF 结合使用,则需要进行这些更改。您可能会问“为什么?”好的,WCF 服务也工作在 IIS 5.1 和 IIS 6.0 中,那么,通过在 IIS 中推广进程模型和激活功能可以获得什么好处呢?很简单:通过推广激活概念使它与协议无关,而不是绑定到 HTTP,可以将平台的激活功能扩展到几乎所有传输类型。
.gif)
IIS 7.0 进程模型体系结构
HTTP、TCP/IP、命名管道和 MSMQ 的特定于协议的侦听器适配器运行于它们自己的进程内部,并将特定传输桥接到 WAS。侦听器适配器要求 WAS 激活工作进程,然后将实际通信转交给这些工作进程内部的特定协议处理程序。因此,WAS 现在拥有 W3svc.exe 中具备的所有功能。通过将此责任拆分成多个单独的进程,其他三种传输也受益于过去内置在 IIS 6.0 中但只用于 HTTP 的进程模型和激活功能。总而言之,使用 IIS 7.0 可以跨越 IIS 中提供的任何传输类型承载任何 WCF 服务。
IIS承载WCF服务的功能建立在Asp.net HTTP管道的基础上,这意味着这类宿主你支持HTTP/HTTPS传输协议。ASP.NET HTTP 管道有HTTP处理器(HTTP Handler)和HTTP模块(HTTP Module)两个概念。尽管HTTP处理器是一个特殊类,可以用它截获及处理传入及传出的信息,但是HTTP处理器会专门负责处理特定的消息。当吧一个扩展名映射到一个实现IHttpHandler接口的类时,就会启动HTTP处理器。在WCF环境下,.svc文件是用来标识服务的扩展名。
IIS承载WCF服务的的实现很简单,可是使用VS的一键发布工具轻松完成,以下是几个需要注意的地方:
- 1.按需选择激活HTTP非HTTP协议功能

- 2.为新建的网站按需添加的协议类型的绑定,为相应的应用程序也添加必须的协议


- 3.如果安装了 .NET Framework 4,随后启用了 .NET Framework 3.5WCF HTTP 激活,则会发生如下错误。

若要解决该问题,请在 Visual Studio 命令提示符下运行下面的命令行:aspnet_regiis.exe -i -enable
WCF服务承载的更多相关文章
- WCF初探-8:WCF服务承载 (上)
前言 任何一个程序的运行都需要依赖一个确定的进程中,WCF服务也不例外.如果使用WCF服务,我们就必须将服务承载于创建它并控制它的上下文和生存期的运行时环境中,承载服务环境的程序,我们称之为宿主.WC ...
- WCF初探-9:WCF服务承载 (下)
在WCF初探-8:WCF服务承载 (上)中,我们对宿主的概念.环境.特点做了文字性的介绍和概括,接下来我们将通过实例对这几种寄宿方式进行介绍.为了更好的说明各寄宿环境特点,本实例采用Http和net. ...
- WCF服务承载(笔记)
自托管(也做自承载) 承载 WCF 服务最灵活.最便捷的方法就是进行自承载.要能够自承载服务,必须满足两个条件.第一,需要 WCF 运行时:第二,需要可以承载 ServiceHost 的托管 .NET ...
- WCF系列教程之WCF服务宿主与WCF服务部署
本文参考自http://www.cnblogs.com/wangweimutou/p/4377062.html,纯属读书笔记,加深记忆. 一.简介 任何一个程序的运行都需要依赖一个确定的进程中,WCF ...
- WCF服务编程-基础
WCF是微软建立新一代的分布式应用及面向服务应用的标准平台,是基于原有.NET Framework 2.0的扩展.虽然在WCF发布不久就已经在项目中使用WCF技术了.但是由于在项目中还没有较大规模的应 ...
- Wcf for wp8 使用iis Express 承载Wcf服务部署发布网站(三)
我们接下来要做的是 本地电脑当作服务器(模拟外网服务器)来承载Wcf服务程序,通过引用本地电脑ip地址访问wcf服务程序接口 http://192.168.1.123/Service1.svc 一.先 ...
- WCF中常见的几种Host,承载WCF服务的方法
1:写在前面 我们都知道WCF在运行的时候必须自己提供宿主来承载服务.WCF 本身没有附带宿主,而是提供了一个 ServiceHost 的类,该类允许您在自己的应用程序中host WCF 服务.然后调 ...
- WCF学习心得----(四)服务承载
WCF学习心得----(四)服务承载 这一章节花费了好长的时间才整理个大概,主要原因是初次接触这个东西,在做练习实践的过程中,遇到了很多的问题,有些问题到目前还没有得以解决.所以在这一章节中,有一个承 ...
- WCF学习笔记(2)——使用IIS承载WCF服务
通过前面的笔记我们知道WCF服务是不能独立存在,必须“寄宿”于其他的应用程序中,承载WCF服务的应用程序我们称之为“宿主”.WCF的多种可选宿主,其中比较常见的就是承载于IIS服务中,在这里我们来学习 ...
随机推荐
- Xutils呼叫流源代码文件下载方法
//我主要是好奇Xutils哪里回调onLoading(),查找等了很久也没找到,果然easy查找只是把它写下来 前言: 1.代码摘要只有主线,提供一般流程 2.为了易于理解,码变量名,而是类名的驼峰 ...
- python元类分析
刚開始接触到Python新式类中的元类的概念的时候非常是纠结了下..不知道这是个啥东西... 用下面几个定义来说明吧: (1)Python中,类也是对象..仅仅只是这样的对象比較的特殊,他用于创建别的 ...
- uva 11529 - Strange Tax Calculation(计数问题)
题目链接:uva 11529 - Strange Tax Calculation 题目大意:给出若干个点,保证随意三点不共线.随意选三个点作为三角行,其它点若又在该三角形内,则算是该三角形内部的点.问 ...
- linux通过建模工具Umbrello
https://umbrello.kde.org/ Umbrello UML Modeller is a Unified Modelling Language (UML) diagram progra ...
- Mac OSX操作系统安装和配置Zend Server 6教程(4)
在前三节中,完成了安装和配置,最后是登录后台,并设置权限.Zend server后台登录默认端口是10081.浏览器中的的地址应输入http://localhost:10081/ZendServer. ...
- 如何把va_list可变参数传送到下一级函数中(如传送到printf)
最近我在一个LCD上想实现打印格式化字符串的功能,实现这样的功能可有两种方式: 一 最直接的就是自己去解析类似于printf功能的一个函数: 二 比较简单的方法是使用已有的sprintf功能,把格式化 ...
- 我的Android 4 学习系列之创建应用程序和Activity:Manifest、Application、Activity
目录 介绍Android应用程序组件,以及使用这些组件构建的各种Android应用程序 Android应用程序的生命周期 如何创建应用程序Manifest 如何使用外部资源提供对位置.语言和硬件配置的 ...
- 【转】android 欢迎界面翻页成效,仿微信第一次登陆介绍翻页界面
android 欢迎界面翻页效果,仿微信第一次登陆介绍翻页界面 本实例做的相对比较简单主要是对翻页控件的使用,有时候想要做一些功能是主要是先了解下是否有现成的控件可以使用,做起来比较简单不用费太大的劲 ...
- 什么是PHP
PHP(PHP: Hypertext Preprocessor的缩写,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,入门门槛较低,易于学习,使用广泛, ...
- Web应用和RESTful架构
Web应用和RESTful架构 单页Web应用 概述 单页Web应用并不是突然诞生的一门新技术,而是web展示的一种新的尝试.它将所有的动作局限于一个Web页面,在加载站点首页的时候就加载站点需要的J ...