WCF 学习总结1 -- 简单实例

从VS2005推出WCF以来,WCF逐步取代了Remoting, WebService成为.NET上分布式程序的主要技术。WCF统一的模型整合了以往的 WebService、Remoting、MSMQ 等技术,让分布式开发变得更加简单,方便,快捷。

(上图选自《Programming WCF Services》)

WCF基本概念(ABC): 1.地址(Address):决定服务的地址;2.绑定(Binding):决定服务的细节;3.契约(Contract):服务的定义(抽象),决定消息结构的定义。

WCF的发布:WCF服务的发布可以有几种形式: IIS, Windows Service, Self-Host(可以是Console程序也可以是Winform程序)。

WCF的工具: Windows Communication Foundation 工具


简单实例-1: 内置AppDomain (无配置)

1. Service1.cs

namespace WCFStudy1  
{  
    [ServiceContract]  
 public interface IService1  
    {  
        [OperationContract]  
 string SendMessage(string clientInput);  
    }  
 public class Service1 : IService1  
    {  
        #region IService1 Members 
 public string SendMessage(string clientInput)  
        {  
 return string.Format("Server Get Message: {0}", clientInput);  
        }  
        #endregion 
    }  
}  

2. Program.cs

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.ServiceModel;  
namespace WCFStudy1  
{  
 class Program  
    {  
 static void Main(string[] args)  
        {  
 // 创建一个独立AppDomain作为服务端。 
            AppDomain.CreateDomain("Server1").DoCallBack(delegate 
            {  
                ServiceHost host = new ServiceHost(typeof(Service1));  
                host.AddServiceEndpoint(typeof(IService1),                  //契约(C) 
 new BasicHttpBinding(),             //绑定(B) 
 "http://localhost:9999/myservice"); //地址(A)  
                host.Open();  
            });  
 // 下面是客户端 
            ChannelFactory<IService1> factory = new ChannelFactory<IService1>(  
 new BasicHttpBinding(),  
 "http://localhost:9999/myservice");  
            IService1 client = factory.CreateChannel();  
            var reply = client.SendMessage("Hello WCF");  
            Console.WriteLine(reply);  
            Console.Read();  
        }  
    }  
}  

如图所示:


简单实例-2: 创建 Console Self-Host

WcfServiceLib - 服务契约的实现; *ConsoleHost工程 – Wcf宿主; *ConsoleClient工程 - Wcf客户端

  1. 创建WcfServiceLib工程(选WCF Service Library工程模板: VS为我们自动添加一个IService1.cs和Service1.cs)

  1. Host工程里引用WcfServiceLib工程
  1. 将WcfServiceLib里App.config移动到ConsoleHost工程里,删掉Lib工程里的App.config
  1. Host工程的Program.cs添加下面的代码,右击Builder工程
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.ServiceModel;  
using WcfServiceLib;  
namespace WCFStudy2ConsoleHost  
{  
 class Program  
    {  
 static void Main(string[] args)  
        {  
 using(var host = new ServiceHost(typeof(Service1)))  
            {  
                host.Open();  
                Console.WriteLine("Service start.");  
                Console.Read();  
            }  
        }  
    }  
}  
  1. 运行 ConsoleHost工程 bin/debug 下面的 exe(这一步是为了生成客户端代理,需要启动Host) 
  2. 在Client工程里通过添加 Service References,生成客户端Proxy,关闭exe
  1. 在Client工程的Program.cs里添加如下代码。
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
namespace WCFStudy2ConsoleClient  
{  
 class Program  
    {  
 static void Main(string[] args)  
        {  
            MyWcfSvc.Service1Client client = new MyWcfSvc.Service1Client();  
            var result = client.GetData(123);  
            Console.WriteLine(result);  
            Console.Read();  
        }  
    }  
}  
  1. F5 运行Solution里的Host, 再右击Client工程选Debug的Start new instance方式,运行Client

运行结果:

由于ServiceHost实例是被创建在应用程序域中,必须保证宿主进程在调用服务期间不会被关闭,因此利用Console.Read()来阻塞进程,以使得控制台应用程序能够一直运行,直到人为关闭应用程序。


简单实例-3: 创建 Winform Self-Host

Winform的Self-Host和ConsoleHost类似,先添加 WcfServiceLib 工程引用,将 WcfServiceLib 里的App.config 移到 Winform 工程里。加上启动Service的代码就OK了!

public partial class Form1 : Form  
{  
 public Form1()  
    {  
        InitializeComponent();  
    }  
 private ServiceHost host = null;  
 // 开启服务端 
 private void btnStart_Click(object sender, EventArgs e)  
    {  
 try 
        {  
 if (host != null)  
                    host.Close();  
            host = new ServiceHost(typeof(WcfServiceLib.Service1));  
            host.Open();  
 this.textBox1.Text = "Server Opened!";  
        }  
 catch (Exception ex)  
        {  
            MessageBox.Show(ex.ToString());  
 if (host != null)  
                host.Close();  
        }  
    }  
 // 关闭服务端 
 private void btnStop_Click(object sender, EventArgs e)  
    {  
 if (host != null)  
        {  
            host.Close();  
 this.textBox1.Text += "Server Closed!";  
        }  
    }  
}  

在Winform中,不要使用 using(...) 代码块,这将导致在Button方法结束后自动销毁Host对象而关闭服务。


简单实例-4: 创建 Windows Service Host

Windows Services宿主便于管理者方便地启动或停止服务,且在服务出现故障之后,能够重新启动服务。还可以通过Service Control Manager(服务控制管理器),将服务设置为自动启动方式,省去了服务的管理工作。此外,Windows Services自身还提供了一定的安全性以及检测机制和日志机制。

1. 创建Windows Service工程

2. 引用 WcfServiceLib 工程,添加 App.config (和前面Host添加的App.config一样)

3. 重写 WindowsService 类的 OnStart 和 OnStop 方法

public partial class Service1 : ServiceBase  
{  
 public Service1()  
    {  
        InitializeComponent();  
    }  
 private ServiceHost host = null;  
 protected override void OnStart(string[] args)  
    {  
 if (host != null)  
            host.Close();  
        host = new ServiceHost(typeof(WcfServiceLib.Service1));  
        host.Open();  
    }  
 protected override void OnStop()  
    {  
 if (host != null)  
            host.Close();  
    }  
}  

4. 创建Service的安装类:在WindowsService 类的设计界面上右击选择 [Add Installer]

修改 serviceProcessInstaller 的 Account 属性 (默认为User) 改为 LocalSystem

通过在Visual Studio的 [Command Prompt] (命令行)模式下通过 InstallUtil 工具安装 Windows服务: InstallUtil [绝对路径]/WCFStudy2WindowsServiceHost.exe (安装成功之后,使用Services.msc查看服务)


简单实例-5: 创建 IIS Host

最简单的就是直接创建一个 WCF Service Application 就OK了。

以上所有工程的关系图如下:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术分享

.NET应用程序调试—原理、工具、方法

阅读目录: 1.背景介绍 2.基本原理(Windows调试工具箱、.NET调试扩展SOS.DLL、SOSEX.DLL) 2.1.Windows调试工具箱 ...

1946
来自专栏一名叫大蕉的程序员

关于Java健壮性的一些思考与实践 No.102

上面两种模式都可以实现标准的 response 的封装,那么具体要封装哪些东西呢?其实最主要的就是统一的 try catch,防止出现任何的 500 错误给到调...

672
来自专栏大内老A

ASP.NET Core应用中如何记录和查看日志

日志记录不仅对于我们开发的应用,还是对于ASP.NET Core框架功能都是一项非常重要的功能特性。我们知道ASP.NET Core使用的是一个极具扩展性的日志...

2138
来自专栏技术分享

.NET应用程序调试—原理、工具、方法

随着应用程序的复杂度不断上升,要想将好的设计思想稳定的落实到线上,我们需要具备解决问题的能力。需要具备对运行时的错误进行定位且快速的解决它的能力。本篇文章我将分...

730
来自专栏大内老A

[WCF-Discovery]让服务自动发送上/下线通知[实例篇]

在《原理篇》我们对客户端如何监听通知,以及服务在上下线时如何发送通知从原理上进行了深入地剖析。我们现在通过一个简单的实例演示如何通过ServiceDiscove...

1886
来自专栏极客编程

Vuex 2 入门与提高

计数器应用的数据模型很简单:使用一个counter属性来表示计数器的 当前值就够了。

421
来自专栏向治洪

python日志配置文件

python的log使… import logging logger = logging.getLogger() # 生成一个日志对象 # logfile...

1838
来自专栏SDNLAB

OpenFlow协议库开发者指南

介绍 OpenFlow协议库是OpenDaylight的一个组件,调解OpenDaylight controller和支持OpenFlow协议的硬件设备之间通...

3698
来自专栏奔跑的蛙牛技术博客

servlet 理解大全

java创建的对象存放在堆中。java虚拟机会主动察觉不再使用的java对象,内存紧张的时候,垃圾收集器会启动清理垃圾,回收空间

712
来自专栏Hadoop实操

如何使用Java访问集成OpenLDAP并启用Sentry的Impala和Hive

在前面的文章Fayson介绍了《如何使用java代码通过JDBC连接Hive(附github源码)》和《如何使用java代码通过JDBC连接Impala(附Gi...

3265

扫描关注云+社区