使用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服务是明文传输,传输过程中数据很 ...
随机推荐
- Web API之消息处理管道
Web API之消息处理管道 前言 MVC有一套请求处理的机制,当然Web API也有自己的一套消息处理管道,该消息处理管道贯穿始终都是通过HttpMessageHandler来完成.我们知道请求信息 ...
- 表与表的关系把RD搞乱了,记一个Procedure中的bug
就是6张表的关联查询,写了一个存储过程,使用4层for来处理 bug:最后一个for中,两张表的关联条件少了一个,结果数据多查了. 排查办法:使用dbms_output.printline('');每 ...
- 每天收获一点点------Hadoop Eclipse插件的使用
本文所用软件版本:myeclipe2014 hadoop1.2.1 1.安装Hadoop开发插件 下载hadoop-eclipse-plugin-1.2.1.jar,拷贝到myeclipse根目 ...
- JavaEE(6) - JMS消息选择和查看
1. JMS消息的类型.消息头和消息属性 消息类型: StreamMessage MapMessage TextMessage ObjectMessage BytesMessage JMS消息中的消息 ...
- OCP读书笔记(26) - 题库(ExamF)
501.Note the output of the following query;SQL> SELECT flashback_archieve_name, status FROM dba_f ...
- DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能
DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能 一.引言 在当前的电子商务平台中,用户下完订单之后,然后店家会在后台看到客户下的订单,然后店家可以对客户的订单进行发货操作.此时客户会在自己 ...
- Struts2流程
Struts2流程 1.client浏览器初始化时发出HTTP请求 2.依据web.xml配置,上述请求被FilterDispatcher接收 3.依据struts.xml配置,找到须要调用的Acti ...
- Merge into的使用详解-你Merge了没有
Merge是一个非常有用的功能,类似于Mysql里的insert into on duplicate key. Oracle在9i引入了merge命令, 通过这个merge你能够在一个SQL语句中对一 ...
- 房间计费系统改造E-R图纸设计
简单的学习过程: 这几天忙得太混乱了,用了近一个星期才设计好.我在这段时间遇到的困难,就积极找师哥师姐指点迷津,如今多少总算是有些拿得出手的成果. 学习成果: Entity Relations ...
- JavaScript语言基础知识点图示
原文:JavaScript语言基础知识点图示 一位牛人归纳的JavaScript 语言基础知识点图示. 1.JavaScript 数据类型 2.JavaScript 变量 3.Javascript 运 ...