调用服务最简单的方法就是,直接在VS里面添加服务引用,输入服务的地址即可,无论是普通Web服务,还是WCF服务均可。VS会根据获取到的元数据,自动生成客户端代码。

如果服务的调用量很大,应用广泛,可以放在IIS上作为一种Web资源使用。但WCF不限于此,它可以在一个进程中运行,或者可以放到Windows服务进程上运行,实则是一种Windows平台的万能通信技术。

为了装逼,今天老周将演示如何手动调用WCF,仅通过Channel(通道)就可以调用。其实,在某些时候,手动也有手动的好处,手动调用的话,代码量不多,也比较灵活。

当然,这个演示仅供参考。

为了顺利完成装逼演示,首先得弄个服务示例,以往常用的是做一个执行加减乘除的服务来测试,今天既然要装逼,就装得有创意一点,就来一个计算N次方的吧,比如2的3次方为8。

不知各位是否记得建立WCF的步骤,这么小的程序,就不用IIS来运行了,直接用一个控制台应用程序可以了,简单大方美观有层次。

首先要声明服务协定。

    [ServiceContract(Name = "pow_service", Namespace = "http://my")]
interface IService
{
[OperationContract(Name = "pow", Action = "PowAction", ReplyAction = "PowReply")]
double Pow(double x, double y);
}

协定只是个接口,在服务器端要实现它,但在客户端不需要知道实现这接口的代码,只要在客户端也定义一个这样的接口,就可以了。当然,如果你不想重复定义协定,你可以把这个接口定义到一个共享的类库中,最好用可移植的库,这样保证平台万能性。

在服务器和客户端中分别定义协定接口有一个好处就是可以两边不必保持一致,接口名、接口的方法都可以不同,参数名也可以不同,只要参数 的顺序、类型、数量,以及返回值的类型相同就可以。

重点是附加在接口上的ServiceContractAttribute,和附加到方法上的OperationContractAttribute特性。服务器和客户端的接口名字可以不同,只要附加的这些特性的属性值相同即可。

所以,在Win10 App客户端,我可以自己声明这样的接口:

    [ServiceContract(Name = "pow_service", Namespace = "http://my")]
interface IPowService
{
[OperationContract(Name = "pow", Action = "PowAction", ReplyAction = "PowReply")]
Task<double> PowAsync(double x, double y);
}

你不妨看一下,接口名字和接口成员名字不同,但标注的协定特性是相同的。所谓的协定者,就是服务器和客户端之间必须有一点“默契”,协定接口就是一种规范,不然,客户端不知道服务有哪些操作方法,就无法调用了。

协定完成后,在服务器端要实现协定接口,进行具体的操作。

    class PowService : IService
{
public double Pow(double x, double y)
{
double res = Math.Pow(x, y);
return res;
}
}

承载在进程上的WCF比较好处理,不用太复杂的配置,几行代码就可以启动服务主机。

            using (ServiceHost host = new ServiceHost(typeof(PowService)))
{
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None); // 直接添加终结点
host.AddServiceEndpoint(typeof(IService), binding, "net.tcp://localhost:1700/pow"); host.Opened += (h, ea) => Console.WriteLine("服务已打开。");
// 打开服务
try
{
host.Open();
}
catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey();
}

其实很Easy,ServiceHost负责运行服务,可解释为服务主机。因为是手动访问服务,基址可以省略。然后你直接将服务协定相应地作为终结点添加到服务主机中即可。在添加终结点时,需要指明协定的Type,一个Binding,当然还要包含地址。

这里我选用TCP协议来通信,就用NetTcpBinding类,NET TCP的地址要以“net.tcp:”开头。

之后,直接Open就可以运行服务了。

注意这个服务只能手动调用,不能用服务引用生成代码,因为没有公开元数据,生成代码时会找不到WSDL。

=========================================================

然后在Windows App客户端中就可以直接调用了。

            // 终结点地址
EndpointAddress ep = new EndpointAddress("net.tcp://localhost:1700/pow");
// TCP绑定
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None); // 创建通道
ChannelFactory<WCFSVContracts.IPowService> factory = new ChannelFactory<WCFSVContracts.IPowService>(binding, ep);
WCFSVContracts.IPowService channel = factory.CreateChannel(); // 调用服务
double x = double.Parse(txt1.Text);
double y = double.Parse(txt2.Text);
double r = await channel.PowAsync(x, y);
tbres.Text = $"计算结果:{r:G}";

WCFSVContracts.IPowService就是在客户端上重新定义的服务协定,但协定的特性要与服务相同,接口名字可以不同。这个上面贴过代码,下面我再贴一段完整的。

using System;
using System.ServiceModel;
using System.Threading.Tasks; namespace WCFSVContracts
{
[ServiceContract(Name = "pow_service", Namespace = "http://my")]
interface IPowService
{
[OperationContract(Name = "pow", Action = "PowAction", ReplyAction = "PowReply")]
Task<double> PowAsync(double x, double y);
}
}

与服务器上的定义有些不同的是,在客户端中,我将操作方法声明为支持异步等待,即返回Task<TResult>,这个是允许的,大家不必怀疑。

你会看到,在客户端上调用也是挺简单的,首先用一个EndpointAddress表示终结点的地址,这个地址必须和服务器上添加的终结点的地址一致,否则找不到服务。

然后实例化一个NetTcpBinding对象,Binding的类型与属性值必须与服务器上的Binding一致。服务器上的NetTcpBinding的安全模式设置为None,客户端上的也要设置为None。因为也不是什么见不得人的数据,就禁用安全模式。

最后,用一个ChannelFactory<TChannel>就可以完成服务调用。TChannel的类型就是协定接口,随着当调用CreateChannel方法时,它所创建的通道就以协定接口为基础返回,它返回的实际类型是一个动态类型,但它可以以协定接口为基础来调用。

运行结果如下图。

示例代码下载

【Win 10应用开发】手动调用WCF服务的更多相关文章

  1. 学习调用WCF服务的各种方法

    1.开发工具调用WCF 这中方法很方便也很简单,很多工作VS就帮我们完成了.相信大家也不会对这种方法陌生.这里简单提一下.打开VS,在项目中添加服务引用: 在config中自动声明了有关服务的节点信息 ...

  2. [转]学习 WCF (6)--学习调用WCF服务的各种方法

    转自:http://www.cnblogs.com/gaoweipeng/archive/2009/07/26/1528263.html 作者这篇博文写得很全面. 根据不同的情况,我们可以用不同的方法 ...

  3. 学习之路十四:客户端调用WCF服务的几种方法小议

    最近项目中接触了一点WCF的知识,也就是怎么调用WCF服务,上网查了一些资料,很快就搞出来,可是不符合头的要求,主要有以下几个方面: ①WCF的地址会变动,地址虽变,但是里面的逻辑不变! ②不要引用W ...

  4. C# 调用WCF服务的两种方法

    项目简介 之前领导布置一个做单点登录的功能给我,实际上就是医院想做一个统一的平台来实现在这个统一的平台登录后不需要在His.Emr.Lis等系统一个个登录,直接可以登录到对应的系统,然后进行相应的操作 ...

  5. SharePoint 2013 调用WCF服务简单示例

    内容比较简单,主要记录自己使用SharePoint 2013WCF服务遇到的小问题和小经验,分享给大家,希望能够给需要的人有所帮助.好吧,进入正题! 第一部分 SharePoint 2013调用自带W ...

  6. WCF分布式开发步步为赢(3)WCF服务元数据交换、配置及编程开发

    今天我们继续WCF分布式开发步步为赢(3)WCF服务元数据交换.配置及编程开发的学习.经过前面两节的学习,我们了解WCF分布式开发的相关的基本的概念和自定义宿主托管服务的完整的开发和配置过程.今天我们 ...

  7. Silverlight客户端调用WCF服务难题解疑

    一:解决办法 Silverlight客户端调用WCF服务在实际使用中经常会出现的问题就是无法直接应用类文件和配置文件.微软针对这一情况已经给出了解决办法.WCF开发框架可以帮助我们实现可靠性较高的跨平 ...

  8. WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载]

    原文:WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载] 我们有两种典型的WCF调用方式:通过SvcUtil.exe(或者添加Web引用)导入发布的服务元数据生成服务代理相关的代码 ...

  9. WCF技术剖析之十:调用WCF服务的客户端应该如何进行异常处理

    原文:WCF技术剖析之十:调用WCF服务的客户端应该如何进行异常处理 在前面一片文章(服务代理不能得到及时关闭会有什么后果?)中,我们谈到及时关闭服务代理(Service Proxy)在一个高并发环境 ...

随机推荐

  1. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

  2. “四核”驱动的“三维”导航 -- 淘宝新UI(需求分析篇)

    前言 孔子说:"软件是对客观世界的抽象". 首先声明,这里的"三维导航"和地图没一毛钱关系,"四核驱动"和硬件也没关系,而是为了复杂的应用而 ...

  3. webpack入门教程之Hello webpack(一)

    webpack入门教程系列为官网Tutorials的个人译文,旨在给予想要学习webpack的小伙伴一个另外的途径.如有不当之处,请大家指出. 看完入门教程系列后,你将会学习到如下内容: 1.如何安装 ...

  4. css-父标签中的子标签默认位置

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  5. SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

     SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...

  6. Objective-C中block的底层原理

    先出2个考题: 1. 上面打印的是几,captureNum2 出去作用域后是否被销毁?为什么? 同样类型的题目: 问:打印的数字为多少? 有人会回答:mutArray是captureObject方法的 ...

  7. Yeoman 官网教学案例:使用 Yeoman 构建 WebApp

    STEP 1:设置开发环境 与yeoman的所有交互都是通过命令行.Mac系统使用terminal.app,Linux系统使用shell,windows系统可以使用cmder/PowerShell/c ...

  8. HDU1671——前缀树的一点感触

    题目http://acm.hdu.edu.cn/showproblem.php?pid=1671 题目本身不难,一棵前缀树OK,但是前两次提交都没有成功. 第一次Memory Limit Exceed ...

  9. Smarty的基本使用与总结

    含义: Smarty是PHP的一个引擎模板,可以更好的进行逻辑与显示的分离,即我们常说的MVC,这个引擎的作用就是将C分离出来. 环境需求:PHP5.2或者更高版本 我使用的环境是:PHP5.3,wi ...

  10. Oracle数据库该如何着手优化一个SQL

    这是个终极问题,因为优化本身的复杂性实在是难以总结的,很多时候优化的方法并不是用到了什么高深莫测的技术,而只是一个思想意识层面的差异,而这些都很可能连带导致性能表现上的巨大差异. 所以有时候我们应该先 ...