WCF学习之旅—TcpTrace工具(二十五)
前面的几篇文章,我们学习了怎么开发WCF应用程序与服务,也学习了如何进行WCF的配置。对于Web Service与WCF服务应用,服务端与客户端的通信是通过收发SOAP Message进行,我们如何有效而快速的获取通信信息呢?这就是本文要介绍的一个工具。
一、TcpTrace实现的基本原理
在对Web Service和WCF进行调试时,可以使用Soap Trace 工具对Soap Message进行深入捕获并进行分析。经常使用的工具有TcpTrace与Microsoft Soap Toolkit中的Soap Trace Utility。
对于希望对WCF的消息交换有一个深层次了解的开发者来说,TcpTracer绝对是一个不可多得好工具。我们将TcpTracer置于服务和服务代理之间,TcpTracer会帮助我们接获、显示和转发流经他的消息。
首先来讲讲TcpTrace实现的基本原理。说简单点,TcpTracer就是一个监听/转发器(Listening/Forwarding),就是一个路由器。当启动的时候,我们需要设置两个端口:监听端口(Listening Port)和目的主机(Destination Server)与目的端口(Destination Port),然后TcpTracer就会在本机的监听端口进行网络监听。一旦有针对该监听端口的请求抵达,他会截获整个请求的消息,并将整个消息显示到消息面板上。随后,TcpTracer会将该消息原封不动地转发给目的主机与目的端口。在另一方面,从目的主机与目的端口发送给原端口的消息,也同样被TcpTracer截获、显示和转发。 说白了就是把要发的消息先给我们查看和备份,再转发出去。
接下来我们我们通过下面的步骤演示如何通过TcpTracer在WCF中进行消息的路由。
1) 为了演示TcpTracer在WCF中的应用,还是用我们前面做的书籍查询示例的WCF服务应用(BookService),具体参见WCF学习之旅——第一个WCF示例(一)与WCF学习之旅—WCF第二个示例(五)。
2) 示例中的终结点的地址为:http://127.0.0.1:8888/BookService(Port为8888)。
3) 同时这个服务端的配置文件信息如下:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework
, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logKnownPii="false" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
<endToEndTracing propagateActivity="true" activityTracing="true" messageFlowTracing="true" />
</diagnostics>
<behaviors>
<serviceBehaviors> <behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:8888/BookService/metadata" />
<serviceDebug includeExceptionDetailInFaults="True" /> </behavior>
</serviceBehaviors>
</behaviors>
<services> <service behaviorConfiguration="metadataBehavior" name="SCF.WcfService.BookService">
<endpoint address="http://127.0.0.1:8888/BookService" binding="wsHttpBinding"
contract="SCF.Contracts.IBookService" /> </service>
</services>
</system.serviceModel>
<startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Warning" propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="D:\wcf.svclog" />
</sharedListeners>
</system.diagnostics>
</configuration>
4) 客户端的配置信息如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IBookService" />
<binding name="WSHttpBinding_IBookService1" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://127.0.0.1:8888/BookService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IBookService" contract="SCF.Contracts.IBookService"
name="WSHttpBinding_IBookService">
<identity>
<userPrincipalName value="DEVELOPER\Administrator" /> </identity>
</endpoint>
<endpoint address="http://127.0.0.1:8888/BookService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IBookService1" contract="BookServiceRef.IBookService" name="WSHttpBinding_IBookService1">
<identity>
<userPrincipalName value="DEVELOPER\Administrator" /> </identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
5) 但是通过上面的设置之后,实际上还是不能够进行数据的捕捉,如下图,无论如何在客户端调用WCF应用,TcpTrace是无法捕捉到任何数据的。

这是为什么呢?请往下看。
二、通过ClientViaBehavior实现基于TcpTracer的消息路由
在我们创建的WCF服务来说,整个服务访问只涉及到两方:服务(BookService)和服务的调用者(客户端)。从消息交换的角度来看,服务的调用者调用者将请求消息直接发送到服务端,计算结果也以回复消息的形式直接返回到服务的调用者。
现在我们需要将TcpTracer作为一个路由器引入到服务(BookService)和服务的调用者 (客户端)之间,那么我们需要解决的是:服务调用者发送的消息不能直接发送到服务端,而应该先发送给TcpTracer,再由TcpTracer转发给服务。我们可以通过ClientViaBehavior实现逻辑地址和物理地址的分离——逻辑地址指向最终的服务,而物理地址则指向 TcpTracer。
具体的原理如下图所示:我们将TcpTracer的监听端口(Listening Port)和目的端口(Destination port)设置成8080和8888(BookService地址所在的端口)。通过ClientViaBehavior将物理地址的端口设成 8080(TcpTracer监听端口)。

注:对于消息发送方来说,SOAP消息的To报头对应的地址由发送端的终结点地址(逻辑地址)决定。
基于上面的实现原理,我们需要修改客户端的配置, 在<system.serviceModel>/<behaviors>/<endpointBehaviors> 添加ClientViaBehavior,将viaUri的端口指定为8080:http://127.0.0.1:8080/BookService。并将该EndpointBehavior应用到终结点中。
1) 配置文件信息修改一下,如下面。请仔细比较一下面的客户端配置文件与上篇文章最后的客户端配置文件的区别:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup> <system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IBookService" />
<binding name="WSHttpBinding_IBookService1" /> </wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="bookServiceEndpointBehavior">
<clientVia viaUri="http://localhost:8080/BookService" /> </behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://127.0.0.1:8888/BookService" binding="wsHttpBinding" behaviorConfiguration="bookServiceEndpointBehavior"
bindingConfiguration="WSHttpBinding_IBookService" contract="SCF.Contracts.IBookService"
name="WSHttpBinding_IBookService">
<identity>
<userPrincipalName value="DEVELOPER\Administrator" /> </identity>
</endpoint>
<endpoint address="http://127.0.0.1:8888/BookService" binding="wsHttpBinding" behaviorConfiguration="bookServiceEndpointBehavior"
bindingConfiguration="WSHttpBinding_IBookService1" contract="BookServiceRef.IBookService"
name="WSHttpBinding_IBookService1">
<identity>
<userPrincipalName value="DEVELOPER\Administrator" /> </identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
2) 经过修改保存之后,现在可以进行Soap Trace了,现在我们再次启动TcpTrace。进行如下的设置,如下图。
监听端口(Listen On Port#):可以自由设置,但是不能够与服务的端口重合,并且该端口还需要在客户端注册。在这里设置成8080
目标端口(Destination Port #):服务端口。在这里设置成8888。

3) 先运行Hosting程序,然后运行WinClient,在WinClient中发起请求,这时请求消息和回复消息将会显示到TcpTracer的消息显示面板中,如下图所示:

4) 我们还可以通过日志,把信息记录下来,记录日志的配置如下图。

5) 当关闭tcpTrace时相应的内容被记录到我们指定的Log文件中:

WCF学习之旅—TcpTrace工具(二十五)的更多相关文章
- WCF学习之旅—TcpTrace工具(二十六)
止文(WCF学习之旅—TcpTrace工具(二十五))介绍了关于TcpTrance的一种使用方式,接下来介绍第二种使用方式. 三.通过ListenUri实现基于tcpTracer的消息路由 对于路由的 ...
- 学习Spring Boot:(二十五)使用 Redis 实现数据缓存
前言 由于 Ehcache 存在于单个 java 程序的进程中,无法满足多个程序分布式的情况,需要将多个服务器的缓存集中起来进行管理,需要一个缓存的寄存器,这里使用的是 Redis. 正文 当应用程序 ...
- JavaSE 学习笔记之正则表达式(二十五)
正则表达式:其实是用来操作字符串的一些规则. 好处:正则的出现,对字符串的复杂操作变得更为简单. 特点:将对字符串操作的代码用一些符号来表示.只要使用了指定符号,就可以调用底层的代码对字符串进行操作. ...
- WCF学习之旅—第三个示例之三(二十九)
上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) 在上一篇文章中我们创建了实体对象与接口协定,在这一篇文章中我们来学习如何创建WCF的服务端代码.具体步骤见下面. ...
- WCF学习之旅—WCF服务的WAS寄宿(十二)
上接 WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) 八.WAS宿主 IIS ...
- WCF学习之旅—实现支持REST客户端应用(二十四)
WCF学习之旅—实现REST服务(二十二) WCF学习之旅—实现支持REST服务端应用(二十三) 在上二篇文章中简单介绍了一下RestFul与WCF支持RestFul所提供的方法,及创建一个支持RES ...
- WCF学习之旅—HTTP双工模式(二十)
WCF学习之旅—请求与答复模式和单向模式(十九) 四.HTTP双工模式 双工模式建立在上文所实现的两种模式的基础之上,实现客户端与服务端相互调用:前面介绍的两种方法只是在客户端调用服务端的方法,然后服 ...
- WCF学习之旅—第三个示例之二(二十八)
上接WCF学习之旅—第三个示例之一(二十七) 五.在项目BookMgr.Model创建实体类数据 第一步,安装Entity Framework 1) 使用NuGet下载最新版的Entity Fram ...
- WCF学习之旅—第三个示例之四(三十)
上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) WCF学习之旅—第三个示例之三(二十九) ...
随机推荐
- 微信小程序开发心得
微信小程序也已出来有一段时间了,最近写了几款微信小程序项目,今天来说说感受. 首先开发一款微信小程序,最主要的就是针对于公司来运营的,因为,在申请appid(微信小程序ID号)时候,需要填写相关的公司 ...
- ArcGIS 10.0紧凑型切片读写方法
首先介绍一下ArcGIS10.0的缓存机制: 切片方案 切片方案包括缓存的比例级别.切片尺寸和切片原点.这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要.图像格式和抗锯齿等 ...
- FREERTOS 手册阅读笔记
郑重声明,版权所有! 转载需说明. FREERTOS堆栈大小的单位是word,不是byte. 根据处理器架构优化系统的任务优先级不能超过32,If the architecture optimized ...
- Hyper-V3:虚拟机的配置
在Hyper-V成功新建一台虚拟机,在正式使用之前,必须配置VM使用的硬件资源,并授予用户访问VM的权限等,本文罗列出一些常见的配置,供读者参阅. 一,为虚拟机分配使用的内存 在Hyper-V Man ...
- 结巴分词3--基于汉字成词能力的HMM模型识别未登录词
作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 算法简介 在 结巴分词2--基于前缀词典及动态规划实现分词 博 ...
- dagger2系列之Scope
Dagger的Scope注解代表的是作用域,通过实现自定义@Scope注解,标记当前生成对象的使用范围,标识一个类型的注射器只实例化一次,在同一个作用域内,只会生成一个实例, 然后在此作用域内共用一个 ...
- ASP.NET MVC一次删除多笔记录
批量删除数据记录,如下面的截屏: 先选中想删除的记录,然后点一下删除铵钮,系统将把选中的记录一次性删除.在此,Insus.NET不想每删除一笔记录连接一次数据库. 因此需要把选择的记录一次上传至服务器 ...
- AspNetPager分页控件样式的使用
分页是Web应用程序中最常用到的功能之一,AspNetPager 简单实用,应用到项目后台中,棒极了! 自定义样式: <style type="text/css"> ...
- Spark-shell和Spark-Submit的使用
Spark-shell有两种使用方式: 1:直接Spark-shell 会启动一个SparkSubmit进程来模拟Spark运行环境,是一个单机版的. 2:Spark-shell --master S ...
- 一条Sql语句分组排序并且限制显示的数据条数
如果我想得到这样一个结果集:分组排序,并且每组限定记录集的数量,用一条SQL语句能办到吗? 比如说,我想找出学生期末考试中,每科的前3名,并按成绩排序,只用一条SQL语句,该怎么写? 表[TScore ...