基于WCF MSMQ 的企业应用解决方案

 

  最近研究了一下基于MSMQ的WCF应用,从书上、网上查了很多资料,但始终没能彻底理解WCF-MSMQ的工作原理,也没能得到一个合理的应用解决方案。索性还是自己做个实验,探索一下吧。经过反复试验,颇有收获,现跟大家分享一下。

  首先我的解释一下为什么查了那么多资料却未能理解WCF-MSMQ的工作原理,不是各位大牛没有把原理讲清楚,而是大多数给出的例子都是在单机上运行的,这就很难说明白离线工作的原理。

  为了说明问题,我用了四台虚机来部署我的实验程序,首先我给大家看一下我的程序部署结构:

  4台虚机(红线表示消息流向),它们的操作系统都是Windows2008 R2,并且都需要安装MSMQ服务,否则无法工作。也就是说,如果应用程序客户端发布出去以后,要想实现离线提交,在客户端机器上也必须安装MSMQ服务。

  • WCF Host (10.222.114.76):这台机器用来运行Service程序,它的主要任务是监听MSMQ Host这台机器上的队列。
  • MSMQ Host (10.222.114.78):这台机器用来提供消息服务;当然完全可以由这4台机器的任何一台作为MSMQ的消息服务器,我MSMQ Host这台机器是为了说明一个问题,稍后会提到。
  • WCF Client 1 (10.222.114.77),WCF Client 2 (10.222.114.79):用来运行客户端程序,当然我们可以有无数个客户端。

  接下来看一下WCF程序的配置:

  服务端

  <system.serviceModel>
<bindings>
<netMsmqBinding>
<binding name="msmqBinding" queueTransferProtocol="Srmp">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings>
<services>
<service name="WCF.Msmq.MsmqService">
<endpoint address="net.msmq://10.222.114.78/private/myqueue" binding="netMsmqBinding"
bindingConfiguration="msmqBinding" contract="WCF.Msmq.IMsmqService" />
</service>
</services>
</system.serviceModel>

  客户端  

    <system.serviceModel>
<bindings>
<netMsmqBinding>
<binding name="netMsmqBinding" queueTransferProtocol="Srmp">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings>
<client>
<endpoint address="net.msmq://10.222.114.78/private/myqueue" binding="netMsmqBinding"
bindingConfiguration="netMsmqBinding" contract="WCF.Msmq.IMsmqService"
name="msmqserivce" />
</client>
</system.serviceModel>

  有一点需要指出,那就是Address。和其它绑定方式不同,使用MSMQ的WCF的地址并不是本机IP(大家可以看到我的WCF Host这台机器的IP是10.222.114.76,像我们常用的basicHttpBingding,WSHttpBingDing等地址指向都是本机地址),而是MSMQ Host那台虚机的IP地址。这就是我为什么把专门用MSMS Host单独拿出来作为消息服务器的原因。另外, queueTransferProtocol="Srmp"用的使用 SOAP 可靠消息传送协议 (SRMP),需要安装HTTP支持,可以直接把它删掉使用默认的Native方式。

  这里代码我就不往上贴了,看一下执行过程吧,WCF Client 1,WCF Client 2往MSMQ Host这台机器上发送消息,WCF Host监控MSMQ Host这台机器上的private/myqueue对列,一旦有消息,则把消息提取出来进行处理。下面是我的程序运行结果,在运行程序之前,需要在MSMQ Host上创建一个私有队列private/myqueue。

WCF Client 1执行结果 WCF Client 2执行结果 WCF Host 执行结果

  我们接下来看下离线工作。我们把WCF Client 1的网卡禁用,或者停掉MSMQ Host,会看到以下结果,在Outgonging队列里堆积了很多发不出去的消息。这就是为什么在客户端需要安装MSMQ服务的原因。一旦WCF Client 1与MSMQ Host再次建立连接,在Outgoing队列里的消息就会被发送到MSMQ Host上去。

  关闭WCF Host中我们运行的Service程序,这时会看到,在MSMQ Host这台机器上private/myqueue对列中的消息越积越多。等到再次启动Service后,它里面的消息就会被处理掉。

  经过上面的实验,可以得到一下结论:WCF Host,MSMQ Host,WCF Client这三台机器任何一台发生故障,应用都是可恢复的,而且数据不会丢失。

  接下来我还做了另一个实验,就是在另外一台机器上启动新建的WCF服务程序,发现两个Service都可以去处理同一队列中的消息,从这种意义上来说,这不失是一个负载均衡的一个解决方案。

  最后,附上我的实验代码,供大家参考:Msmq.7z

如何用ASP.NET实现bosh模拟http双向长连接请求

 

  在做研究之前先简单说一下之前公司的通讯模块。最早的时候公司开发的web管理系统是需要配合c++桌面客户端进行一些系统底层操作,并非普通的b/s架构,或者c/s架构,因为需求是可以通过web管理系统向客户端发送一些简单的指令和策略,客户端根据不同只指令或策略进行系统底层的一些操作,并可以向服务器提交日志及状态信息.

  依此我们设计了如下架构:

  

  其中web服务器是用c#写的,通讯服务器是用c++写的,客户端使用c++写的,管理员通过web登录到web服务器管理界面,将相关策略发送到通讯服务器,再由通讯服务器通知到c++客户端,为了保证能够即时得到通知,使用通讯服务器与客户端之间建立tcp连接是必须的。但是由此导致了一个问题,就是通讯服务器中可能包含了和web服务器相同的业务代码,导致维护比较麻烦,并且在c++通讯服务器中修改业务代码,没有web服务器中的asp.net那么方便.

  后来我们修改了这种设计方式,通讯服务器只是用来做和客户端之间的长连接维持,只接收转发web管理服务器下发的指令,当c++客户端需要获取数据,或者提交业务数据的时候,直接连接到web服务器post相关请求获取或者提交数据.这样客户端的连接通道分成了指令通道(TCP)和数据通道(HTTP).这样的好处是通讯服务器不用再处理业务了,所有的业务处理都通过数据通道交由web管理服务器处理.通讯服务器不需要再发生改变.

  再就是后来我们想到是不是通讯服务器也可以去掉,这样可以节省掉c++模块的维护,只使用web服务器进行通讯,并且也方便以后的调试.但是使用http协议进行通讯有个最大的缺陷就是只能客户端通过web服务器去拉取数据,而web服务器无法向客户端主动下发数据.为了克服这个缺点,研究了使用http协议轮询数据,或者建立http长连接,但在时效性,性能,兼容性各方面考虑最后还是没有使用.后来研究xmpp的时候,发现webIM的很多实现用了一种叫Bidirectional-streams Over Synchronous HTTP (BOSH)的技术,可以模拟双向通讯.于是下面我就是实验了一下.

  根据bosh的说法就是客户端向服务器发起请求之后,服务器如果当前没有数据的话,就hold住这个请求,不立即返回,当有数据的时候,再返回此次请求.怎样hold住就是问题的关键了,由于之前没用过asp.net但可以预见到,直接把请求的当前线程挂起是不行的,如果1000个请求就挂住一千个线程,服务器是受不了的,猜测asp.net应该有一种异步处理机制的,网上搜了一下,果然米有问题,添加"一般处理程序"修改为继承异步接口就可以了,如下代码.

    public class _long : IHttpAsyncHandler
{
public bool IsReusable
{
get
{
return false;
}
}
public System.IAsyncResult BeginProcessRequest(System.Web.HttpContext context, System.AsyncCallback cb, object extraData)
{
LongAsyncResult result = new LongAsyncResult(cb, context);
try
{
//do something
}
catch (System.Exception ex)
{
result.SetSyncComplete();
}
return result;
}
public void EndProcessRequest(System.IAsyncResult result)
{
//do something
}
public void ProcessRequest(System.Web.HttpContext context)
{
//throw new Exception("The method or operation is not implemented.");
}
}

  后来我们公司根据实际情况还是用http建立了两个通道,一般业务请求处理,使用普通的http短连接请求,而服务器的数据下发则使用的bosh建立的双向通道.经过测试修改iis部分配置之后,连接数是没有限制的,关键就是看业务执行的效率了.如果对性能没有什么特殊的要求的话,这种实现方式的开发效率还是很高的.

总结一下使用这种方式的好处:

  可以利用IIS稳定高效的底层通讯框架。
  可以使用.NET框架迅速开发出稳定程序,并可以方便对业务的快速修改。
  可以跨平台部署通讯服务器。
  可以利用IIS或者Apache现成的负载均衡解决方案。
  在外网部署,http协议防火墙穿透性比较强。
  可以利用一些现成的http代理服务器进行通讯跳转。

Print2flash在.NET(C#)中的使用,即文档在线预览

office文档(word,excel,ppt)在线预览查看,有很多种方式,比如可以

1、调用weboffice组件,进行word预览,要求客户端安装word,仅适用IE, word2013, IE11会提示word停止响应;

2、将word转为html文档;

3、使用flexpaper,感觉不是很美观,不过还是可以用;

4、使用flashpaper,效果比较好看,不过只支持32位操作系统,不支持64位;

5、使用print2flash,效果跟flashpaper差不多;

这里主要讲一下print2flash的使用,先上一个效果图:

print2flash的大体实现是这样的,通过把从客户端上传的word/Excel/ppt文件,调用print2flash官方提供的dll,转化成swf格式文件,最后浏览swf文件,就是上图中的效果。

具体使用 如下:

1、下载print2flash,这里是64位的,可以到官方http://print2flash.com/download.php下载最新的,其中的Print2Flash SDK 3.5,是java php .net asp的代码示例

2、配置服务信息,这一步很关键,不然会提示 COM 类工厂中 CLSID 为 {466FAC17-24D2-4B37-A2C4-E2CFA0D3E1E7} 的组件失败,原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))(不安装print2flash也会这样提示)

配置步骤:打开print2flash安装目录,64位操作系统默认在C:\Program Files (x86)\Print2Flash3下,右键管理员方式运行print2flash.exe,点击option—>Print2Flash Service Configuration,如下图:

3、在程序里引用Interop.Print2Flash3.dll,并调用如下代码,进行转换。

            String fs_filename = Server.MapPath("UploadedFiles/") + FileUpload1.FileName;
String fs_convertedfilename = Server.MapPath("ConvertedFiles/") + FileUpload1.FileName + ".swf";
Print2Flash3.Server2 p2fServer = new Print2Flash3.Server2();
p2fServer.ConvertFile(fs_filename, fs_convertedfilename, null, null, null);

这里其美中不足的地方是,试用版会在预览的时候,有一串英语,意思是让你到官方去瞅瞅。网上有3.1版本的注册码,这个是3.5的,注册码没法用。

另外官方也提供了相关sdk,这里的源码即是官方提供的。但核心代码就是上面那几句。 
源码下载

另外这里是官方flexpaper在c#中实现的源码,其实现原理是process调用pdf2swf.exe,将pdf文件转为swf文件,点击下载源码,安装需要swftool0.9.1.exe支持,点击下载swftoolvs运行起来后,页面登陆用户名admin 密码123456 效果图如下

WCF MSMQ的更多相关文章

  1. 基于WCF MSMQ 的企业应用解决方案

    最近研究了一下基于MSMQ的WCF应用,从书上.网上查了很多资料,但始终没能彻底理解WCF-MSMQ的工作原理,也没能得到一个合理的应用解决方案.索性还是自己做个实验,探索一下吧.经过反复试验,颇有收 ...

  2. WCF MSMQ消息队列与离线操作

    消息队列类型 公共队列:整个网络中的节点都可以访问到 专用队列:本地计算机,知道路径者可以访问 管理队列:包含确认在给定“消息队列”网络中的发送的消息回执的消息 相应队列:返回给发送程序的相应信息

  3. WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ

    之前曾经写过一个关于MSMQ消息队列的文章:WCF分布式开发必备知识(1):MSMQ消息队列 ,当时的目的也是用它来作为学习WCF 消息队列MSMQ编程的基础文章.在那篇文章里,我们详细介绍了MSMQ ...

  4. 跟我一起学WCF(11)——WCF中队列服务详解

    一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务队列的方法来支持客户端 ...

  5. WCF中队列服务详解

    WCF中队列服务详解 一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务 ...

  6. 重启IIS报错:IIS 服务或万维网发布服务,或者依赖这 服务可能在启动期间发生错误或者已禁用

    参考文章: http://www.cnblogs.com/zengen/archive/2010/10/29/1864569.html 开启如下服务: Net.Msmq Listener Adapte ...

  7. IIS 服务或万维网公布服务,或者依赖这 服务可能在启动期间错误发生或者已禁用

    作者:jiankunking 出处:http://blog.csdn.net/jiankunking 详细错误信息例如以下: 解决方式: 在服务中禁用下面3个服务自己主动启动: Net.Msmq Li ...

  8. 跟我一起学WCF(1)——MSMQ消息队列

    一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能 ...

  9. 基于MSMQ绑定的WCF服务实现总结

    一. 创建消息队列    1 1) 创建一个非事物性的私有队列    1 2)设置消息队列访问权限    2 二.创建WCF服务并绑定消息队列    4 1)创建HelloService服务    4 ...

随机推荐

  1. 第14章 命令模式(Command Pattern)

    原文 第14章 命令模式(Command Pattern) 命令模式(Command Pattern) 概述   在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”.但在某些场合,比如 ...

  2. NYoj 685 查找字符串

    描述 小明得到了一张写有奇怪字符串的纸,他想知道一些字符串出现了多少次,但这些字符串太多了,他想找你帮忙,你能帮他吗?输入字符包括所有小写字母.‘@’.‘+’.   输入 第一行包含一个整数T(T&l ...

  3. jsp页面onsubmit=&quot;return checklogin();&quot;该解决方案给

    选择Window->Preferences->MyEclipse->Validation 去掉方框里的对号,然后Apply 然后点击Yes->然后再点击ok->Yes,足 ...

  4. Objective-C马路成魔【12-分类和协议】

    郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助.欢迎给作者捐赠,支持郝萌主.捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 分类与协议 ...

  5. CSDN博客频道维护公告

    各位亲爱的用户:        为了给大家提供更稳定的使用环境,2014年4月23日23点至04月24日1点(本周四凌晨)博客频道server将进行维护,维护期间不能正常訪问.给大家带来不便,敬请广大 ...

  6. TDD

    初识TDD 首先说一下名词解释,TDD,英文名称Test-Driven Development,中文名称测试驱动开发,简单的断下句“测试/驱动/开发”,简单的理解一下,就是测试驱动着开发,大白话就是说 ...

  7. Touch Punch在移动设备上面增加jQuery UI的触摸支持|Jquery UI 支持移动端 触摸滑动等

    jQuery UI是我们前台开发常用的UI前端类库,但是目前的jQuery UI用户界面类库在互动和widget上并不支持touch事件.这意味着你在桌面上设计的优雅的UI可能在触摸设备,例如,ipa ...

  8. .NET开源项目 TOP 25

    .NET开源项目 TOP 25 如果知道.NET项目在开源中国的git上所占的比重只有5%的话,为什么这个<2014年国人开发的最热门的开源软件TOP 100>榜中.NET项目那么少就是情 ...

  9. MonkeyRunner源码分析之工作原理图-attach

    花了点时间整理了下MonkeyRunner的工作原理图: Item Description Warning Author 天地会珠海分舵 转载请注明出处! Blog Address http://bl ...

  10. 使用Dropbox+Justwriting+Markdown建立个人博客

    使用Dropbox+Justwriting+Markdown建立个人博客,让您真正体会到什么是"简化". 您的博客所有日志存储在您的PC上.即使有一天你的server主机挂了,你的 ...