一直都在用Msmqbinding,也一直忽视了message里面的内容格式是什么样的,这也是微软给我们高层封装带给我们的开发效率,但同时一旦中间出了什么问题,

就不知道从何查起了。有个需求是这样的,服务端和客户端采用离线连接,也就是消息队列模式,server接收端在处理消息的时候,要根据一定的逻辑,如果该消息不

满足规则,就把消息原样的丢回消息队列中,问题就出现在这里。。。消息丢进去了,然后,然后就tmd的飞走了!!!先快速的看下代码。

一:示例代码

1.server端

         public void Run(Test test)
{
if (test.str.Length % == )
{
//重新丢回消息队列
MessageQueue mq = new MessageQueue(@".\private$\myqueue");
Message msg = new Message();
msg.Body = test;
msg.Formatter = new XmlMessageFormatter(new Type[] { test.GetType() }); mq.Send(msg);
//Environment.Exit(0); System.Console.WriteLine("已经成功丢回! ,当前线程:" + Thread.CurrentThread.ManagedThreadId);
}
else
{
System.Console.WriteLine("已经消费客户端消息!");
}
}

2.服务代码

         public void Run(Test test)
{
if (test.str.Length % == )
{
//重新丢回消息队列
MessageQueue mq = new MessageQueue(@".\private$\myqueue");
Message msg = new Message();
msg.Body = test;
msg.Formatter = new XmlMessageFormatter(new Type[] { test.GetType() }); mq.Send(msg);
//Environment.Exit(0); System.Console.WriteLine("已经成功丢回! ,当前线程:" + Thread.CurrentThread.ManagedThreadId);
}
else
{
System.Console.WriteLine("已经消费客户端消息!");
}
}

3.client端

         static void Main(string[] args)
{
var msmq = new NetMsmqBinding(NetMsmqSecurityMode.None); msmq.ExactlyOnce = false; ChannelFactory<IHomeService> factory = new ChannelFactory<IHomeService>(msmq,
"net.msmq://localhost/private/myqueue"); var client = factory.CreateChannel(); for (int i = ; i < int.MaxValue; i++)
{
var t = new Test() { str = "" }; client.Run(t);
Console.WriteLine("调用第 " + i + " 次");
} var s = ;
}

当时写的急,也没关注能不能用MessageQueue将消息丢回消息队列中,然后让WCF的MsmqBinding去读取,结果上面的奇葩问题就来了,反正队列中的数据

一直在减少,但是server端就是没进来,tmd的wcf却一个错误都不抛出来,麻蛋。。。为了展示出效果,我特意做成了flash。

从上面的flash中,你可以看到console控制台已经不在接受消息了,但是奇怪的是消息队列中的数据还是一直在减少。。。。

二:怀疑

  从开始在server端将message丢回消息队列的时候,我就有一点怀疑,或许这两种message的内容格式不一样,wcf在接受的时候应该会报错,但是tmd的

就是没有给小爷报错,现在既然问题来了,我就去比较一下,到底两种message的格式是什么样的,然后我就写了两份丢消息队列的方法。

         static void Main(string[] args)
{
//第一种方式:
var msmq = new NetMsmqBinding(NetMsmqSecurityMode.None);
msmq.ExactlyOnce = false; ChannelFactory<IHomeService> factory = new ChannelFactory<IHomeService>(msmq,
"net.msmq://localhost/private/myqueue");
var client = factory.CreateChannel(); var t = new Test() { str = "" }; client.Run(t); //第二种方式:
MessageQueue mq = new MessageQueue(@".\private$\myqueue");
Message msg = new Message();
msg.Body = t;
msg.Formatter = new XmlMessageFormatter(new Type[] { t.GetType() }); mq.Send(msg);
}

然后我跑去MMC控制台看一下,果然消息的大小都不一样,内容也不一样。。。真相大白,左边也不知道是什么格式,右边很清楚的看到是xml格式。

如果文章到这里的话,说明我也就只能看表面现象,因为刚才我已经提出了一个问题,左边到底是什么格式???

三:进一步探索

  现在我们知道Msmqbinding使用的是自己独有格式的消息body,现在是不是有耐心看看wcf这个底层怎么写的呢???我通过一系列的调试跟踪,

发现MsmqBinding是先创建一个Msmq的信道栈,可以看到这个channel要传递的消息是soap12协议的,不管是什么样的,可以确认的是,消息传递

采用的soap消息的模式。对吧,如下图:

接下来,这个channel会调用wcf自己封装的消息队列MsmqQueue,并且会调用其中的send方法,将消息推送到消息队列中,不过要记住,wcf中那

些高层的msmq操作,在底层都是这个类来达到效果的。

好了,探索就到这里为止了,到现在我们起码知道以下二点消息了。

第一: MessageQueue类投送的消息一般可以指定xml或者binaray,而WCF中的Msmq中的消息采用的是soap格式。。。这也是为什么一个内容小,一个大。

第二: WCF中所有的高层消息操作,都是建立在自己独有个MsmqQueue之上,包括send,received方法,只是微软给我们封装了而已。

用MsmqBinding投送message出现的一个灵异事件 【第二篇】的更多相关文章

  1. mybatis缓存,从一个“灵异”事件说起

    刚准备下班走人,被一开发同事叫住,让帮看一个比较奇怪的问题:Mybatis同一个Mapper接口的查询方法,第一次返回与第二次返回结果不一样,百思不得其解! 问题 Talk is cheap. Sho ...

  2. SWUST OJ 东6宿舍灵异事件(0322)

    东6宿舍灵异事件(0322) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 88 Accepted: 31   Descriptio ...

  3. [Swust OJ 322]--东6宿舍灵异事件(中缀表达式转化为后缀表达式的简单运用)

    题目链接:http://acm.swust.edu.cn/problem/322/ Time limit(ms): 1000 Memory limit(kb): 65535     Descripti ...

  4. 记录一起k8s的service服务名解析灵异事件

    故障现象: 基于alpine 3.7的镜像,构建的spring boot服务及eureka服务器. 在使用deployment和service文件部署到k8s集群之后, 在不同的pod内部,访问ser ...

  5. android中listview点击事件失效的灵异事件

    首先说明一下我想实现的功能: 点击某个item之后,让其颜色发生变化.如果变化网上有很多例子,我就不班门弄斧了.Listview之所以点击没有反应是因为上图中绿色部分(自己定义的一个继承BaseAda ...

  6. redis系列-14点的灵异事件

    概述 项目组每天14点都会遭遇惊魂时刻.一条条告警短信把工程师从午后小憩中拉回现实.之后问题又神秘消失.是PM喊你上工了?还是服务器给你开玩笑?下面请看工程师如何一步一步揪出真凶,解决问题. 如果不想 ...

  7. MySQL 灵异事件一则 -- desc报语法错误

    今天有一开发同学找到我,说查询SQL中倒序报错,不明原因,于是奔赴工位现场研究情况. 果然,只要SQL中带有desc 就会报错,而ASC没问题. 哪怕desc放在句首用作explain也会报错. 报错 ...

  8. AngularJS进阶(十四)AngularJS灵异代码事件

    AngularJS灵异代码事件 注:请点击此处进行充电! 事情原委 router_sys.js源代码如下: 自己在html路由跳转的代码如下: 但是在实际路由过程中,却路由到了下面的状态,相应的页面中 ...

  9. 高效开发之SASS篇 灵异留白事件——图片下方无故留白 你会用::before、::after吗 link 与 @import之对比 学习前端前必知的——HTTP协议详解 深入了解——CSS3新增属性 菜鸟进阶——grunt $(#form :input)与$(#form input)的区别

    高效开发之SASS篇   作为通往前端大神之路的普通的一只学鸟,最近接触了一样稍微高逼格一点的神器,特与大家分享~ 他是谁? 作为前端开发人员,你肯定对css很熟悉,但是你知道css可以自定义吗?大家 ...

随机推荐

  1. 损失函数(Loss Function) -1

    http://www.ics.uci.edu/~dramanan/teaching/ics273a_winter08/lectures/lecture14.pdf Loss Function 损失函数 ...

  2. MVC之前的那点事儿系列(9):MVC如何在Pipeline中接管请求的?

    文章内容 上个章节我们讲到了,可以在HttpModules初始化之前动态添加Route的方式来自定义自己的HttpHandler,最终接管请求的,那MVC是这么实现的么?本章节我们就来分析一下相关的M ...

  3. 使用MySQL WorkBench导入数据库

    1. 在MySQL WorkBench的Server Administrator中双击要连接的数据库: 2. 点击左边的Data Import/Restore; 3. Import from Dump ...

  4. Android获取系统时间方法的总结

    Android获取系统时间方法的方法有很多种,常用的有Calendar.Date.currentTimeMills等方法. (1)Calendar Calendar获取系统时间首先要用Calendar ...

  5. 框架Maven笔记系列 一 基础

    主题:SpringMVC 学习资料参考网址: 1.http://www.icoolxue.com 2.http://maven.apache.org/ 1.Maven解决了什么问题? Maven基于项 ...

  6. Python的sorted函数应用

    sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序 L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88) ...

  7. [翻译] Autofac 入门文档

    原文链接:http://docs.autofac.org/en/latest/getting-started/index.html 在程序中使用Autofac的基本模式是: 用控制反转(IoC)的思想 ...

  8. 七个结构模式之适配器模式(Adapter Pattern)

    定义: 将一个接口转换为客户需要的另外一个接口,使接口不兼容的类型可以一起工作,也被称为包装器模式(Wrapper Patern). 结构图: Target:目标抽象类,客户所需要的接口. Adapt ...

  9. Redis-复制

    Redis 的复制 (replication) 是一种使用和配置起来非常简单的主从(master-slave)复制,允许 Redis 从服务器成为主服务器的精确副本.以下是关于 Redis 复制的一些 ...

  10. Java基础学习-- 继承 的简单总结

    代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...