之前因为某些特定岗位的人不知道是不方便还是什么的原因,所以随便做了个独立于所有系统之外的邮件审批服务,功能是那些人在邮件里给待审批单据发个“同意”就自动审批通过,大致分为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订阅替换轮训

    使用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. (插播)unity的 异常捕捉和 ios Android 崩溃信息的捕捉。

    近期 做些准备性得工作和有意思的事情.所以近期做了一个适合ios和android 错误信息捕捉的unity插件. 两个功能,app崩溃也就是闪退 是开发人员 非常头疼的一件事,还有就是一些莫名得错误 ...

  2. c# 硬件开源神器netduino的开发中慎用Cpu.Pin

    最近为了测试netduino开发板的各个端口是否正常使用,让同事写了一些测试程序,结果出了问题,他的测试程序导致开发板无法发布程序进去,按他的结论是开发板有问题,针对这个情况,我们经过仔细分析代码,认 ...

  3. 更多RANK37

    By LTL 经过对BDG长期的观察得出的这套理论,希望能对大家学习OI有所帮助. 入门篇 首先在掌握一门语言时(P,C都无所谓的),假设不习惯指针能够直接无视.语言之中对于入门选手来说最重要的递归. ...

  4. boxfilter 实现

    A implementation of boxfilter boxfilter 是均值滤波的一种改进.在以下这篇blog里面有介绍. http://www.cnblogs.com/easymind22 ...

  5. NGUI Example5 演示示例评论– lights and Refraction

     NGUI Example5 – lights and Refraction        NUI这个系统是在是牛.比unity3D里面自带的gui要好用得多.还能够为GUI加入法线贴图! 哈哈. ...

  6. about greenplum collection tool

    three collection tool for greenplum:pstack.strace.gcore.                                            ...

  7. Spring MVC异常处理详解(转)

    下图中,我画出了Spring MVC中,跟异常处理相关的主要类和接口. 在Spring MVC中,所有用于处理在请求映射和请求处理过程中抛出的异常的类,都要实现HandlerExceptionReso ...

  8. .net程序调用检测和性能分析工具——DotTrace

    DotTrace可以对.net程序进行性能监测,对正在运行的程序和网站监控,主要界面如下: 需要将该工具安装在程序运行的服务器上. 主要用到这个视图,显示了每个方法的时间,下面是反编译出来的代码. P ...

  9. 使用Maven管理Spring[转]

    原文链接: Spring with Maven 原文日期: 2013年04月17日 翻译日期: 2014年06月29日 翻译人员: 铁锚 翻译原文连接:http://blog.csdn.net/ren ...

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

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