使用WCF订阅替换轮训
之前因为某些特定岗位的人不知道是不方便还是什么的原因,所以随便做了个独立于所有系统之外的邮件审批服务,功能是那些人在邮件里给待审批单据发个“同意”就自动审批通过,大致分为3部分:第一部分每隔固定时间去邮件服务器抓一批邮件下来;第二部分分析邮件格式,如果符合就提取必须的邮件内容;第三部分提交审批流驱动进行审批。
我一直想做个移动端APP然后废掉它算了,不过似乎领导觉得这个东西还能撑下去,总之就一时半会是不可能干掉了。
所以,游戏之做还是得优化一下,这里就说说第一部分:
每隔固定时间抓取然后执行存在的问题,比如说现在是每隔十分钟抓一次,处理不怎么及时,而且即使没有新邮件也会去抓一次,另外还有一个隐藏的问题,就是为什么设置10分钟,主要是邮件服务器那边还有其他的处理,需要一个回执,但是这是个单线程的服务(因为用的人很少)所以担心设置的时间短了这一批抓取的还没处理完,这里有一些无关的事都耦合上了。
解决办法:不再去抓邮件,而是如果邮件审批服务空闲了,就去邮件服务器上注册一下,如果有了新邮件,就由邮件服务器发布任务,这样以后用的人多了还可以做分布式处理(当然,我还是倾向于不用这种方式了,因为各种客户端发出来的邮件千奇百怪,解析难保正确)。
这里就使用WCF的订阅发布来做了,其实我觉得在没什么压力的情况下,有些消息队列也可以用这种方法简化
下面是测试代码:
首先是配置文件
<service name="HotelService.PublishService">
<endpoint address="" binding="wsDualHttpBinding" contract="HotelService.IPublishService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
服务和回调契约:
[ServiceContract(CallbackContract = typeof(ISubscribeCallback), Namespace = "http://www.justonlyatest.com")]
public interface IPublishService
{
[OperationContract(IsOneWay = true)]
void DoWork(); [OperationContract(IsOneWay = true)]
void Subscribe(string id); [OperationContract(IsOneWay = true)]
void UnSubscribe(string id);
} public interface ISubscribeCallback
{
[OperationContract]//(IsOneWay = true)
void CallbackWork(string workState);
}
服务实现,注释里简单交代了下实例模型下的效果
// InstanceContextMode.Single 同步通知所有订阅的客户端,可将服务作为版本服务器的客户端,同步分布式服务的版本信息
// InstanceContextMode.PerSession 同步同一Session下的所有订阅,本例中单个客户端实例的所有订阅
// InstanceContextMode.PerCall 由于所有请求都是独立服务实例,所以无法实现订阅
// ConcurrencyMode.Single 回调必须是IsOneWay
// 回调是IsOneWay时可同步通知所有订阅方,否则只能顺序通知
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class PublishService : IPublishService
{
Subscribers subscribers = new Subscribers();
public void DoWork()
{
string workState = "完成";
//ISubscribeCallback callback = OperationContext.Current.GetCallbackChannel<ISubscribeCallback>();
//callback.CallbackWork(workState); Dictionary<string, ISubscribeCallback> subscribes = subscribers.Subscribes;
foreach (var key in subscribes.Keys)
{
subscribes[key].CallbackWork(key + ":" + workState);
}
} public void Subscribe(string id)
{
ISubscribeCallback callback = OperationContext.Current.GetCallbackChannel<ISubscribeCallback>();
subscribers.AddSubscriber(id, callback);
} public void UnSubscribe(string id)
{
ISubscribeCallback callback = OperationContext.Current.GetCallbackChannel<ISubscribeCallback>();
subscribers.RemoveSubscriber(id, callback);
}
}
public class Subscribers
{
public Dictionary<string, ISubscribeCallback> Subscribes { get; set; } public Subscribers()
{
Subscribes = new Dictionary<string, ISubscribeCallback>();
} public void AddSubscriber(string id,ISubscribeCallback callback)
{
if (!Subscribes.Keys.Contains(id))
{
Subscribes.Add(id, callback);
}
} public void RemoveSubscriber(string id, ISubscribeCallback callback)
{
if (Subscribes.Keys.Contains(id))
{
Subscribes.Remove(id);
}
}
}
客户端测试
PublishService.PublishServiceClient client;
string clientID; public TestSubscribe()
{
InstanceContext context = new InstanceContext(new CallbackSubscribe());
client = new PublishService.PublishServiceClient(context); clientID = Guid.NewGuid().ToString();
} private void btnTest_Click(object sender, EventArgs e)
{
client.DoWork();
} private void btnRegist_Click(object sender, EventArgs e)
{
client.Subscribe(clientID);
} private void btnCancellation_Click(object sender, EventArgs e)
{
client.UnSubscribe(clientID);
}
使用WCF订阅替换轮训的更多相关文章
- WCF订阅替换轮训
使用WCF订阅替换轮训 之前因为某些特定岗位的人不知道是不方便还是什么的原因,所以随便做了个独立于所有系统之外的邮件审批服务,功能是那些人在邮件里给待审批单据发个“同意”就自动审批通过,大致分为3部分 ...
- js 替换 当前URL 特定参数
js 替换 当前URL 特定参数 2012-12-24 20:45:53| 分类: JS&JQuery |举报 |字号 订阅 //替换指定传入参数的值,paramName为参数,repl ...
- [ZigBee] 4、ZigBee基础实验——中断
前言 上一篇介绍了CC2530的IO的基础知识,并用LED的控制来展示如何配置并控制GPIO的输出,用KEY状态的读取实验来展示如何读取GPIO的状态.从上一节的KEY状态读取的代码看出是采用轮训方式 ...
- MQTT v5.0------SUBSCRIBE 报文
SUBSCRIBE 报文 固定报头: 剩余长度字段 表示可变报头的长度加上有效载荷的长度,被编码为变长字节整数. 可变报头 SUBSCRIBE报文可变报头按顺序包含以下字段:报文标识符(Packet ...
- ActiveMQ配置文档
本文介绍一对一.一对多.持久化.非持久化消息配置方式 一.创建项目 导入jar 二.创建MQ.xml <!-- 配置JMS连接工厂 --> <bean id="connec ...
- VB.net Wcf事件广播(订阅、发布)
这篇东西原写在csdn.net上,最近新开通了博客想把零散在各处的都转移到一处. 一.源起 学WCF有一段时间了,可是无论是微软的WebCast还是其他网上的教程,亦或我购买的几本书中,都没有怎么 ...
- 替换 wcf 消息传输中的 命名空间
替换 wcf 消息传输中的 命名空间,http://vanacosmin.ro/Articles/Read/WCFEnvelopeNamespacePrefix
- WCF Publisher/Subscriber 订阅-发布模式
本博后续将陆续整理这些年做的一些预研demo,及一些前沿技术的研究,与大家共研技术,共同进步. 关于发布订阅有很多种实现方式,下面主要介绍WCF中的发布订阅,主要参考书籍<Programming ...
- 项目中使用WCF替换asmx Web service总结
以前项目解决方案中,用http协议的asmx Web service作服务器数据访问入口,在SoapHeader中写入用户名和加盐密码进行身份认证. http asmx服务是明文传输,传输过程中数据很 ...
随机推荐
- HDOJ 1753 明朝A+B
http://acm.hdu.edu.cn/showproblem.php? pid=1753 大明A+B Time Limit: 3000/1000 MS (Java/Others) M ...
- 用CSS3制作很特别的波浪形菜单
原文:用CSS3制作很特别的波浪形菜单 网页菜单我们见过很多,各种炫酷的.实用的菜单比比皆是.昨天我看到一款很特别的CSS3菜单,它的外形是波浪形的,弯弯曲曲,结合背景,看上去还挺不错的,下面看下一效 ...
- Eclipse 发布到网站的附加产品的形式 Update Site
Eclipse 发布到网站的附加产品的形式 Update Site 通过Update Site Project项目将自己做的插件产品公布到公网上,给客户或其它測试人员下载和应用,这样自己的插件就以网站 ...
- shell脚本操作数据库
#!/bin/bash HOST_NAME="localhost" PORT=3306 USERNAME="root" PASSWORD="root& ...
- HDU 5052 Yaoge’s maximum profit 光秃秃的树链拆分 2014 ACM/ICPC Asia Regional Shanghai Online
意甲冠军: 特定n小点的树权. 以下n每一行给出了正确的一点点来表达一个销售点每只鸡价格的格 以下n-1行给出了树的侧 以下Q操作 Q行 u, v, val 从u走v,程中能够买一个鸡腿,然后到后面卖 ...
- OCP读书笔记(25) - 题库(ExamE)
401.Which of the following are correct about block media recovery? (Choose all that apply.)A. Physic ...
- 创建自定义的Middleware中间件
创建自定义的Middleware中间件 阅读目录 何为Middleware中间件 使用Inline方式注册Middleware 使用Inline+ AppFunc方式注册Middleware 定义原生 ...
- VB.NET与C# 语法show差异
学习VB.NET后发现,VB.NET与C#的语法基本的不同在两个部分,这两部分搞通了,那就游刃有余,迎刃而解了. 现将其对照总结例如以下: 一.实体部分 (与VB相比.在C#和VB.NET中,实体的使 ...
- 计蒜客 作弊揭发者(string的应用)
鉴于我市拥堵的交通状况,市政交管部门经过听证决定在道路两侧安置自动停车收费系统.当车辆驶入车位,系统会通过配有的摄像头拍摄车辆画面,通过识别车牌上的数字.字母序列识别车牌,通过连接车管所车辆信息数据库 ...
- [置顶] Spring中DI设置器注入
Java的反射机制可以说是在Spring中发挥的淋漓尽致,下面要看的代码就是通过反射机制来实现向一个类注入其实际依赖的类型,这个过程的实现会交由Spring容器来帮我们完成. JavaBean中针对属 ...