一、创建WCF服务器

1、创建WCF服务器的窗体应用程序

打开VS2010,选择文件→新建→项目菜单项,在打开的新建项目对话框中,依次选择Visual C#→Windows→Windows窗体应用程序,然后输入项目名称(Name),存放位置(Location)和解决方案名称(Solution Name),点击“确定”生成项目。如下图:

2、在新建的WcfServer项目中右键添加→新建项,新建一个Calculate的WCF服务,接着添加服务操作,本示例中添加了一个Add的加法服务操作

Add的加法服务操作代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text; namespace WcfServer
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“ICalculate”。
[ServiceContract]
public interface ICalculate
{
[OperationContract]
int Add(int i, int j);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text; namespace WcfServer
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Calculate”。
public class Calculate : ICalculate
{
public int Add(int i, int j)
{
return i + j;
}
}
}

3、将该项目中创建的Form1重命名为FrmMain,在窗体中进行WCF服务的操作,如下图:

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 System.ServiceModel;
using System.Configuration;
using System.ServiceModel.Configuration; namespace WcfServer
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
txtWcfServiceURL.Text = ConfigHelper.Config.WcfServiceConnectURL;
} /// <summary>
/// 主机服务
/// </summary>
ServiceHost serviceHost; /// <summary>
/// 开启服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnStart_Click(object sender, EventArgs e)
{
ConfigHelper.Config.WcfServiceConnectURL = txtWcfServiceURL.Text;
if (serviceHost == null)
{
this.btnStart.Enabled = false;
this.btnStop.Enabled = true;
try
{
// 实例化WCF服务对象
serviceHost = new ServiceHost(typeof(WcfServer.Calculate));
serviceHost.Opened += delegate { MessageBox.Show("启动服务OK"); };
serviceHost.Closed += delegate { MessageBox.Show("停止服务OK"); };
serviceHost.Open();
}
catch (Exception ex)
{
MessageBox.Show("启动服务异常:" + ex.Message + "==>" + ex.StackTrace);
}
}
else
{
btnStop_Click(sender, e);
}
} /// <summary>
/// 停止服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnStop_Click(object sender, EventArgs e)
{
this.btnStart.Enabled = true;
this.btnStop.Enabled = false;
try
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
catch (Exception ex)
{
MessageBox.Show("停止服务异常:" + ex.Message + "==>" + ex.StackTrace);
}
}
} public class ConfigHelper
{
private static ConfigHelper _config = new ConfigHelper(); /// <summary>
/// 获取ServerConfig对象
/// </summary>
public static ConfigHelper Config
{
get { return _config; }
} /// <summary>
/// 获取或设置连接服务器地址
/// </summary>
public string WcfServiceConnectURL
{
get { return GetWcfServiceUri(); }
set { SetWcfServiceUri(value); }
} /// <summary>
/// 设置Wcf服务器的地址
/// </summary>
private void SetWcfServiceUri(string uri)
{
Configuration serviceModelConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSectionGroup serviceModel = serviceModelConfig.SectionGroups["system.serviceModel"];
ServiceModelSectionGroup serviceModelSectionGroup = serviceModel as ServiceModelSectionGroup;
ServiceElement service = serviceModelSectionGroup.Services.Services["WcfServer.Calculate"];
service.Host.BaseAddresses[].BaseAddress = uri;
serviceModelConfig.Save();
// 刷新命名节,在下次检索它时将从磁盘重新读取它。记住应用程序要刷新节点
//ConfigurationManager.RefreshSection("system.serviceModel");
ConfigurationManager.RefreshSection("system.serviceModel/behaviors");
ConfigurationManager.RefreshSection("system.serviceModel/bindings");
ConfigurationManager.RefreshSection("system.serviceModel/client");
ConfigurationManager.RefreshSection("system.serviceModel/services");
}
/// <summary>
/// 获取Wcf服务器的地址
/// </summary>
/// <returns></returns>
private string GetWcfServiceUri()
{
Configuration serviceModelConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSectionGroup serviceModel = serviceModelConfig.SectionGroups["system.serviceModel"];
ServiceModelSectionGroup serviceModelSectionGroup = serviceModel as ServiceModelSectionGroup;
ServiceElement service = serviceModelSectionGroup.Services.Services["WcfServer.Calculate"];
return service.Host.BaseAddresses[].BaseAddress;
} /// <summary>
/// 设置指定节点的配置值
/// </summary>
private void SetAppSettings(string key, string value)
{
Configuration appSettingConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
appSettingConfig.AppSettings.Settings[key].Value = value;
appSettingConfig.Save();
ConfigurationManager.RefreshSection("appSettings");// 刷新命名节,在下次检索它时将从磁盘重新读取它。记住应用程序要刷新节点
} /// <summary>
/// 获取指定节点的配置值
/// </summary>
private string GetAppSettings(string key)
{
return ConfigurationManager.AppSettings[key];
}
}
}

这样WCF服务器基本上就做好了,接下来就是在WCF客户端调用了!

二、WCF客户端

1、新建的控制台程序项目WcfClient,右键添加服务引用,弹出添加服务引用对话框,点击前往,在地址上输入WCF服务器的地址,找到服务后,修改命名空间,点击确定,项目自动生成服务。如下图:

2、客户端(控制台应用程序)中调用WCF服务操作

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels; namespace WcfClient
{
class Program
{
// 要想异步调用,需要在添加服务引用时,选择“高级”按钮→勾选“生成异步操作”
static void Main(string[] args)
{
EndpointAddress endPoint = new EndpointAddress("http://192.168.8.184/Calculate");
// 基于WSHttp请求方式
Binding wshttpBinding = new WSHttpBinding();
wshttpBinding.SendTimeout = new System.TimeSpan(, , );
// 手动调用WCF地址
WcfService.CalculateClient calcTest = new WcfService.CalculateClient(wshttpBinding, endPoint);
// 进行异步操作
calcTest.AddCompleted += new EventHandler<WcfService.AddCompletedEventArgs>(calcTest_AddCompleted);
calcTest.AddAsync(, ); Console.ReadKey();
} /// <summary>
/// 调用AddAsync方法完成后回调事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void calcTest_AddCompleted(object sender, WcfService.AddCompletedEventArgs e)
{
Console.WriteLine(e.Result);
}
}
}

使用ChannelFactory类动态调用WCF地址

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels; namespace WcfClient
{
class Program
{
static void Main(string[] args)
{
WcfService.ICalculate icalcTest = null;
try
{
EndpointAddress endPoint = new EndpointAddress("http://192.168.8.184/Calculate");
// 基于WSHttp请求方式
Binding wshttpBinding = new WSHttpBinding();
//using (ChannelFactory<WcfService.ICalculate> channelFactory = new ChannelFactory<WcfService.ICalculate>("ClientEndpoint", endPoint))
using (ChannelFactory<WcfService.ICalculate> channelFactory = new ChannelFactory<WcfService.ICalculate>(wshttpBinding, endPoint))
{
icalcTest = channelFactory.CreateChannel(); // 建立连接通道
(icalcTest as ICommunicationObject).Closed += delegate
{
Console.WriteLine("连接已关闭");
};
int addResult = icalcTest.Add(, );
Console.WriteLine(addResult);
}
}
catch (TimeoutException)
{
(icalcTest as ICommunicationObject).Abort();
}
catch (CommunicationException)
{
(icalcTest as ICommunicationObject).Abort();
}
catch (Exception)
{
(icalcTest as ICommunicationObject).Close();
} Console.ReadKey();
}
}
}

本示例的源码:http://files.cnblogs.com/lusunqing/WcfTest.rar

创建一个简单的WCF程序2——手动开启/关闭WCF服务与动态调用WCF地址的更多相关文章

  1. 如何创建一个简单的struts2程序

    如何创建一个简单的Struts2程序 “计应134(实验班) 凌豪” 1.创建一个新的Web项目test(File->new->Web Project) 2.Struts2框架的核心配置文 ...

  2. 使用visualStudio2017创建一个简单的控制台程序

    步骤: 1.  打开visual studio开发工具 2. 选择文件>新建>项目 如下图所示: 3. 选择window金典桌面>控制台应用程序 并填写好想项目名称和选择项目存储地址 ...

  3. 使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(二)(代码篇)

    这篇是上一篇的延续: 用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(一) 源代码在github上可以下载,地址:https://github.com/guoxia ...

  4. [WCF学习笔记] 我的WCF之旅(1):创建一个简单的WCF程序

    近日学习WCF,找了很多资料,终于找到了Artech这个不错的系列.希望能从中有所收获. 本文用于记录在学习和实践WCF过程中遇到的各种基础问题以及解决方法,以供日后回顾翻阅.可能这些问题都很基础,可 ...

  5. 创建一个简单的maven的web程序

    最近学习Hadoop,发现学习要想用hadoop作为后台运行web程序,必须应用maven,所以学习了今天学习了一下maven,然后搭建了一个简单的web程序 首先我使用的是eclipse中自带的ma ...

  6. 在 Visual Studio 中创建一个简单的 C# 控制台应用程序

    转载:https://blog.csdn.net/qq_43994242/article/details/87260824 快速入门:使用 Visual Studio 创建第一个 C# 控制台应用 h ...

  7. 如何创建一个简单的C++同步锁框架(译)

    翻译自codeproject上面的一篇文章,题目是:如何创建一个简单的c++同步锁框架 目录 介绍 背景 临界区 & 互斥 & 信号 临界区 互斥 信号 更多信息 建立锁框架的目的 B ...

  8. Android官方教程翻译(3)——创建一个简单的用户界面

    转载请注明出处:http://blog.csdn.net/dawanganban/article/details/9839523 Building a Simple User Interface 创建 ...

  9. 如何在Liferay 7中创建一个简单的JSF Portlet

    这个将在Liferay IDE 3.1 M3的发布版中提供创建的选项,但是你也可以通过命令行来创建. 1.这是Liferay JSF团队的官网:http://liferayfaces.org/ 你能在 ...

随机推荐

  1. RSA 时序攻击

    RSA的破解从理论上来讲是大数质数分解,可是就是有一些人另辟蹊径,根据你解密的时间长短就能破解你的RSA私钥. 举一个不恰当但是比较容易理解的例子: 密文0101 私钥0110 明文0100 问题的关 ...

  2. what's the 跨期套利

    出自 MBA智库百科(https://wiki.mbalib.com/) 跨期套利的定义 跨期套利是套利交易中最普遍的一种,是股指期货的跨期套利(Calendar Spread Arbitrage)即 ...

  3. Nginx中的rewrite指令(break,last,redirect,permanent)

    rewite 在server块下,会优先执行rewrite部分,然后才会去匹配location块 server中的rewrite break和last没什么区别,都会去匹配location,所以没必要 ...

  4. 发现Boost官方文档的一处错误(numpy的ndarray)

    文档位置:https://www.boost.org/doc/libs/1_65_1/libs/python/doc/html/numpy/tutorial/ndarray.html shape在这里 ...

  5. SQL中查询前几条或者中间某几行数据limit

    SELECT * FROM table  LIMIT [offset,] rows | rows OFFSET offset 使用查询语句的时候,要返回前几条或者中间某几行数据,用Llimit   可 ...

  6. 2018-2019-1 20189221 《Linux内核原理与分析》第六周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第六周作业 实验五 实验过程 将Fork函数移植到Linux的MenuOS fork()函数通过系统调用创建一个与原来 ...

  7. js动态规划---背包问题

    //每种物品仅有一件,可以选择放或不放 //即f[i][w]表示前i件物品恰放入一个容量为w的背包可以获得的最大价值. //则其状态转移方程便是:f[i][w]=max{f[i-1][w],f[i-1 ...

  8. 部署一个不依赖tomcat容器的应用

    一个task项目,应用里边都是一些定时任务.我和新入职的高开商定程序部署不依赖于tomcat. 计划赶不上变化,任务开发完成还没等上线呢,哥们要离职了.工作交接时大概说了一下上线怎么部署. 结果呢,当 ...

  9. react-demo

    实现博客动态的评论.动态的点赞.评论的删除. 百度云链接:https://pan.baidu.com/s/199l3iu0qhM6qSe9CBnHFzw 提取码:n4w6

  10. es6Math对象新增的方法

    Math.trunc() Math.trunc方法用于去除一个数的小数部分,返回整数部分. 对于没有部署这个方法的环境,可以用下面的代码模拟. Math.trunc = Math.trunc || f ...