WCF寄宿方式
WCF寄宿方式是一种非常灵活的操作,可以在IIS服务、Windows服务、Winform程序、控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便、高效提供服务调用。本文分别对这几种方式进行详细介绍并开发例子进行说明,以求大家对WCF寄宿的方式进行全面的认识和了解。
1、 WCF服务的IIS服务寄宿
我在我前面几篇WCF开发框架的介绍文章中,介绍过了WCF常用的一种寄宿方式,IIS服务寄宿。这种寄宿方式是最为方便的方式,而且由于服务只需要IIS运行就能自动运行起来,因此广为使用。
创建这种方式IIS寄宿方式的,只需要在解决方案里面,添加WCF服务应用程序,就可以生成这种的服务模块了。

这个是一个基于Web的应用程序,创建项目后会生成一个Service1.svc的服务页面,以及相关的WCF服务接口和实现,如下图所示。

这个就是简单的WCF服务,当然如果是复杂的实际应用,会考虑和数据库打交道,而且可能项目会分成几个进行管理,从而实现更好的逻辑分离操作。
2、 创建WCF服务库为多种寄宿做准备
除了上面常用的IIS服务寄宿,一般还会有各种各样的寄宿方式,不过如果采用其他方式的寄宿方式,一般会把WCF服务和寄宿方式进行项目的分离,实现更好的重用操作,特别WCF需要考虑多种寄宿方式的情况下。下面是WCF服务库和WCF服务应用程序的介绍说明,先了解一下基础。
WCF服务库,可以认为是一个包含WCF服务以及契约定义的类库。这里WCF服务库还不能直接运行,你可以在其他项目里引用,在宿主里启用托管这个库。
而WCF应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定义,可以直接看到运行的效果。此项目模板应该是基于IIS托管的程序。
前者一般考虑WCF服务设计的时候,服务类的定义为单独的库,可以为其它项目使用。提高代码的复用性。后者在开发基于IIS托管的WCF服务程序时,比较多见,自学的时候也可以使用这种类型。当然你也可以修改这些代码,比如把WCF服务程序里的类,移到一个单独的类库里。
创建WCF服务库,可以理解为我们开发.NET程序时创建的一个类库模块,不含界面,如下所示,创建一个WCF服务库。

确定后就只有一个示例服务Service1生成了。

这里,我们为了演示,就不修改任何它们的代码,原始的代码如下所示。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text; namespace WcfServiceLibrary
{
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
} public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
}

3、 WCF服务的控制台程序寄宿
这种也是一种常见的WCF服务寄宿方式,通过启动一个类似DOS窗口的控制台软件,实现WCF服务的动态寄宿,关闭控制台程序,服务就自然终止。
这种方式很简单,创建一个控制台程序,然后添加WCF服务类库的项目应用,在Main函数里面添加下面代码即可实现。

namespace WcfService_HostConsole
{
class Program
{
static void Main(string[] args)
{
try
{
ServiceHost serviceHost = new ServiceHost(typeof(Service1));
if (serviceHost.State != CommunicationState.Opened)
{
serviceHost.Open();
} Console.WriteLine("WCF 服务正在运行......");
Console.WriteLine("输入回车键 <ENTER> 退出WCF服务");
Console.ReadLine();
serviceHost.Close(); }
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}


4、 WCF服务的Winform程序寄宿
和控制台程序一样,我们创建一个Winform项目,然后在窗体启动代码里面添加寄宿方式的代码即可,为了较好的响应体验,可以使用后台线程程序进行服务启动,如下所示。

namespace WcfService_HostWinform
{
public partial class FrmMain : Form
{
ServiceHost serviceHost = null;
BackgroundWorker worker = null; public FrmMain()
{
InitializeComponent(); worker = new BackgroundWorker();
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.DoWork += new DoWorkEventHandler(worker_DoWork); if (!worker.IsBusy)
{
tssTips.Text = "正在启动......";
lblTips.Text = tssTips.Text;
worker.RunWorkerAsync();
}
} void worker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
serviceHost = new ServiceHost(typeof(Service1));
if (serviceHost.State != CommunicationState.Opened)
{
serviceHost.Open();
} e.Result = "正常";
}
catch (Exception ex)
{
e.Result = ex.Message;
}
} void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result != null)
{
if (e.Result.ToString() == "正常")
{
tssTips.Text = "服务正在进行侦听......";
}
else
{
tssTips.Text = string.Format("错误:{0}", e.Result);
} lblTips.Text = tssTips.Text;
}
}
...........................
}
}

当然为了防止Winform程序被不小心关闭,可以添加托盘代码,把程序缩小到托盘图标里面。

5、 WCF服务的Windows 服务程序寄宿
这种方式的服务寄宿,和IIS一样有一个一样的优点,系统启动后,WCF服务也会跟着启动了,不用人工干预,也是一种较好的寄宿方式。
为了实现这种方式的寄宿,我们创建一个控制台程序,然后添加响应的Window服务和安装程序类

然后在服务类启动里面添加WCF的寄宿代码,如下所示。

public class ServiceManager : ServiceBase
{
private static object syncRoot = new Object();//同步锁
private ServiceHost serviceHost = null; //寄宿服务对象 public ServiceManager()
{
this.ServiceName = Constants.ServiceName;
} /// <summary>
/// 设置具体的操作,以便服务可以执行它的工作。
/// </summary>
protected override void OnStart(string[] args)
{
try
{
serviceHost = new ServiceHost(typeof(Service1));
if (serviceHost.State != CommunicationState.Opened)
{
serviceHost.Open();
}
}
catch (Exception ex)
{
LogTextHelper.Error(ex);
} LogTextHelper.Info(Constants.ServiceName + DateTime.Now.ToShortTimeString() + "已成功调用了服务一次。"); LogTextHelper.Info(Constants.ServiceName + "已成功启动。");
}

为了实现通过该控制台程序实现参数化安装和卸载服务,我们需要拦截控制台的参数,并进行相应的操作,如下所示。

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
ServiceController service = new ServiceController(Constants.ServiceName); // 运行服务
if (args.Length == 0)
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new ServiceManager() };
ServiceBase.Run(ServicesToRun);
}
else if (args[0].ToLower() == "/i" || args[0].ToLower() == "-i")
{
#region 安装服务
if (!ServiceIsExisted(Constants.ServiceName))
{
try
{
string[] cmdline = { };
string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location; TransactedInstaller transactedInstaller = new TransactedInstaller();
AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
transactedInstaller.Installers.Add(assemblyInstaller);
transactedInstaller.Install(new System.Collections.Hashtable()); TimeSpan timeout = TimeSpan.FromMilliseconds(1000 * 10);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
catch (Exception ex)
{
LogTextHelper.Info(ex);
throw;
}
}
#endregion
}
else if (args[0].ToLower() == "/u" || args[0].ToLower() == "-u")
{
#region 删除服务
try
{
if (ServiceIsExisted(Constants.ServiceName))
{
string[] cmdline = { };
string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location; TransactedInstaller transactedInstaller = new TransactedInstaller();
AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
transactedInstaller.Installers.Add(assemblyInstaller);
transactedInstaller.Uninstall(null);
}
}
catch (Exception ex)
{
LogTextHelper.Info(ex);
throw;
}
#endregion
}
}

编译程序成功后,我们添加两个批处理的DOS脚本来实现执行程序的自动安装和卸载,如下所示。
安装脚本
"WcfService_HostWinService.exe" -i
pause
卸载脚本
"WcfService_HostWinService.exe" -u
pause

顺利执行脚本后,服务列表里面就增加一个服务项目了。

卸载操作,直接执行脚本就会卸载服务,非常方便哦。
6、 WCF服务的Web寄宿
当然,除了以上几种方式,这种以WCF服务库的方式,也可以在Web方式进行寄宿(IIS方式),这种方式更简单,添加一个后缀名的svc的文件,只需要一行代码即可,如下所示。

7、 使WCF服务支持GET方式调用
有时候,我们为了需要,可能通过一个小程序发布一个服务,然后供其他程序进行调用,可能是Web,也可以是Winform,但是我们是想提供一个基于HTTP,GET或者POST方式来实现接口的调用的,例如,提供一个JSON格式或者文本格式的内容返回操作。
如果是整合在Winform里面,那么我们在Winform里面添加一个WCF的项,修改里面的代码就可以了,如下所示。

首先要在使用GET方式的WCF服务接口的添加说明。如果是POS方式,增加设置有点不同([WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)])。

namespace WcfServiceForWinform
{
[ServiceContract]
public interface IService1
{
[OperationContract]
void DoWork(); [OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]
string GetData(int value);
}
}

第二,在实现类里面添加相应的设置

namespace WcfServiceForWinform
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public void DoWork()
{
} public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
}

配置文件如下所示,颜色标注特别的要注意:

<?xml version="1.0"?>
<configuration> <system.web>
<compilation debug="true"/>
</system.web> <system.serviceModel>
<services>
<service name="WcfServiceForWinform.Service1" behaviorConfiguration="ServiceConfig">
<endpoint address="" binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJsonP" behaviorConfiguration="webHttpBehavior"
contract="WcfServiceForWinform.IService1">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:9000/Service1/" />
</baseAddresses>
</host>
</service>
</services> <bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings> <behaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors> <serviceBehaviors>
<behavior name="ServiceConfig">
<serviceMetadata httpGetEnabled="True" policyVersion="Policy15"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

运行Winform程序,启动了WCF服务后,我们可以在浏览器(Chrome)上进行操作,如下结果所示。

从上图我们可以看到,这个通过Winform启动起来的WCF服务,连接也能通过GET方式进行接口调用了,接口可以通过参数进行传递,对于一些方便传输数据的接口如JSON接口,就是一种非常方便的调用了。
以上轉http://i.cnblogs.com/EditPosts.aspx?opt=1
WCF寄宿方式的更多相关文章
- (转)WCF开发框架形成之旅---WCF的几种寄宿方式
WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便.高效提供服务调用.本文分别对这几种方式进行详 ...
- WCF开发框架形成之旅---WCF的几种寄宿方式
WCF开发框架形成之旅---WCF的几种寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者 ...
- 微软 WCF的几种寄宿方式,寄宿IIS、寄宿winform、寄宿控制台、寄宿Windows服务
WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便.高效提供服务调用.本文分别对这几种方式进行详 ...
- [转]WCF的几种寄宿方式
转自:WCF开发框架形成之旅---WCF的几种寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为 ...
- WCF :IIS寄宿方式的Web地址、BaseAddress和EndPoint Address的关系
对于在IIS中通过W3SVC或WAS寄宿的WCF Service,其在浏览器中显示的地址(Web地址),与其配置文件中的BaseAddress和EndPoint Address有什么关系呢?让我们来分 ...
- WCF引用方式之IIS方式寄宿服务
通过IIS方式寄宿服务 之前的例子是将控制台作为WCF的寄宿方式或者是直接添加契约项目的引用,然后通过配置或者是ChannelFactory的形式进行创建服务对象,其实在大多的开发中以IIS的形式创建 ...
- WCF之各种WCF引用方式
写在开头:本文内容来自 WCF全面解析中的一个经典例子,如果你已经看过了,那么可以忽略本文,本文旨在和大家分享不一样的WCF使用方法. 准备工作: 1.创建解决方案WCFService(当然名字可以任 ...
- WCF引用方式
WCF之各种WCF引用方式 写在开头:本文内容来自 WCF全面解析中的一个经典例子,如果你已经看过了,那么可以忽略本文,本文旨在和大家分享不一样的WCF使用方法. 准备工作: 1.创建解决方案WCFS ...
- 将WCF寄宿在托管的Windows服务中
在我之前的一篇博客中我介绍了如何发布WCF服务并将该服务寄宿于IIS上,今天我再来介绍一种方式,就是将WCF服务寄宿在Windows服务中,这样做有什么好处呢?当然可以省去部署IIS等一系列的问题,能 ...
随机推荐
- CListCtrl使用方法汇总
回顾: 刚刚写完,因为是分期写的,所以最初想好好做一下的文章格式半途而废了~说的也许会有点啰嗦,但是所有的基础用到的技术细节应该都用到了. 如果还有什么疑问,请回复留言,我会尽力解答. 如果有错误,请 ...
- nova读取配置文件流程
在我们安装nova的过程中,设置它的配置文件/etc/nova/nova.conf是必不可少的一步.配置好nova.conf文件,nova-compute.nova-network等服务才 ...
- 【CCS仿真】用matlab把CCS保存的32位16进制的数据转换为十进制的数
2013-12-04 16:37:28 使用fscanf函数即可完成. 例如,CCS保存的.dat文件Copy_of_forward_i_f.dat如下: 1651 1 81008800 0 4000 ...
- Regex count lowercase letters
Description: Your task is simply to count the total number of lowercase letters in a string. Example ...
- 《OD大数据实战》HBase环境搭建
一.环境搭建 1. 下载 hbase-0.98.6-cdh5.3.6.tar.gz 2. 解压 tar -zxvf hbase-0.98.6-cdh5.3.6.tar.gz -C /opt/modul ...
- 基于Linux的oracle数据库管理 part2( 数据库 准备,安装,创建 )
主要内容 1. 准备 2. 安装 与 删除 软件 3. 创建数据库 4. 配置 SQL*PLUS 环境 准备 1. 软件包, rpm –qa , rpm –ivh *.rpm 2. 检查磁盘空间 3. ...
- 【转载】Javascript中的this关键字
看了这篇文章 http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html 分情况讨论. 情况一:纯粹的函数 ...
- Qt之模型/视图(自定义进度条)
简述 在之前的章节中分享过关于QHeaderView表头排序.添加复选框等内容,相信大家模型/视图.自定义风格有了一定的了解,下面我们来分享一个更常用的内容-自定义进度条. 实现方式: 从QAbstr ...
- [转] POJ字符串分类
POJ 1002 - 487-3279(基础)http://acm.pku.edu.cn/JudgeOnline/problem?id=1002题意:略解法:二叉查找数,map,快排... POJ 1 ...
- jquerymobile使用技巧
1)ajax开关(默认jquery以ajax方式加载页面) $.mobile.ajaxEnabled = false; 2)不编译指定标签 $.mobile.page.prototype.option ...