使用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订阅替换轮训的更多相关文章

  1. 使用WCF订阅替换轮训

    之前因为某些特定岗位的人不知道是不方便还是什么的原因,所以随便做了个独立于所有系统之外的邮件审批服务,功能是那些人在邮件里给待审批单据发个“同意”就自动审批通过,大致分为3部分:第一部分每隔固定时间去 ...

  2. js 替换 当前URL 特定参数

    js 替换 当前URL 特定参数 2012-12-24 20:45:53|  分类: JS&JQuery |举报 |字号 订阅   //替换指定传入参数的值,paramName为参数,repl ...

  3. [ZigBee] 4、ZigBee基础实验——中断

    前言 上一篇介绍了CC2530的IO的基础知识,并用LED的控制来展示如何配置并控制GPIO的输出,用KEY状态的读取实验来展示如何读取GPIO的状态.从上一节的KEY状态读取的代码看出是采用轮训方式 ...

  4. MQTT v5.0------SUBSCRIBE 报文

    SUBSCRIBE 报文 固定报头: 剩余长度字段 表示可变报头的长度加上有效载荷的长度,被编码为变长字节整数. 可变报头 SUBSCRIBE报文可变报头按顺序包含以下字段:报文标识符(Packet ...

  5. ActiveMQ配置文档

    本文介绍一对一.一对多.持久化.非持久化消息配置方式 一.创建项目 导入jar 二.创建MQ.xml <!-- 配置JMS连接工厂 --> <bean id="connec ...

  6. VB.net Wcf事件广播(订阅、发布)

    这篇东西原写在csdn.net上,最近新开通了博客想把零散在各处的都转移到一处.   一.源起 学WCF有一段时间了,可是无论是微软的WebCast还是其他网上的教程,亦或我购买的几本书中,都没有怎么 ...

  7. 替换 wcf 消息传输中的 命名空间

    替换 wcf 消息传输中的 命名空间,http://vanacosmin.ro/Articles/Read/WCFEnvelopeNamespacePrefix

  8. WCF Publisher/Subscriber 订阅-发布模式

    本博后续将陆续整理这些年做的一些预研demo,及一些前沿技术的研究,与大家共研技术,共同进步. 关于发布订阅有很多种实现方式,下面主要介绍WCF中的发布订阅,主要参考书籍<Programming ...

  9. 项目中使用WCF替换asmx Web service总结

    以前项目解决方案中,用http协议的asmx Web service作服务器数据访问入口,在SoapHeader中写入用户名和加盐密码进行身份认证. http asmx服务是明文传输,传输过程中数据很 ...

随机推荐

  1. mongodb迁移

    A机器上有mongodb服务,A机器要废,于是迁至B. 简单起见,依旧是在A上ps auxwww|grep mongo找到正在执行的进程: /home/admin/mongodb/mongodb-li ...

  2. 排序(4)---------希尔(shell)排序(C语言实现)

    由于考试耽搁了几天,不好意思~~~ 前面的介绍的三种排序算法,都属于简单排序,大家能够看下详细算法,时间复杂度基本都在0(n^2),这样呢,非常多计算机界.数学界的牛人就非常不爽了,他们在家里想啊想, ...

  3. C语言优化实例:为了消除嵌套switch-case聪明的做法

    我们有可能会写出或者遇到类似这种代码: C/C++ switch (expr1) { case label11: switch (expr2) { case label21: // do someth ...

  4. 划分数 (DP)

    输入: n=4 m=3 M=10000 输出: 4 (1+1+2=1+3=2+2=4) 复杂度(nm) int n,m; int a[MAX]; int dp[MAX][MAX]; //数组 void ...

  5. 基于Js实现的UrlEncode和UrlDecode函数代码

    <script language="javascript">//UrlEncode函数function UrlEncode(str){  var ret="& ...

  6. 利用缓存、Timer间隔时间发送微信的实例,很有用的例子

    //Class WechatOfferExcutor 此类为微信触发类,属于上层调用类,其中有用到用静态变量缓存offer信息,Task异步执行发送方法等 using Newtonsoft.Json. ...

  7. HDU 4303 Hourai Jeweled 树dp 所有权利和航点 dfs2次要

    意甲冠军: long long ans = 0; for(int i = 1; i <= n; i++) for(int j = i+1; j <= n; j++) ans += F(i, ...

  8. 转载使用Flurl制作可复用的分页组件

    使用Flurl制作可复用的分页组件 使用ASP.NET MVC查询时,一直使用MvcPaging组件,虽然需要自定义MvcPaging.Pager才能达到我想要的效果,但在没有较好的URL库时,还是这 ...

  9. 管理员控制Windows Service

    C# 以管理员方式启动Winform,进而使用管理员控制Windows Service   问题起因: 1,) 问题自动分析Windows服务在正常运行时,确实会存在程序及人为原因导致该服务停止.为了 ...

  10. Java设计模式偷跑系列(21)建模和实现享受metapatterns

    转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/40021651 享元模式(Flyweight):运用共享的技术有效地支持大量细粒度的对象. ...