技术篇(4)--基于QPG容器的服务扩展

不好意思,这个月单位的事情实在太多。昨天又加班到23:00。

技术篇(2)--QPG容器的高级用法中我们讲到,使用QPG平台后,您就可以把对象间的耦合和依赖降到最小。以前的做法如下:
原始法: 
  TypeA o1=new TypeA();//可能是算法策略
  TypeB o2=new TypeB(o1);
   o2.getResults(x,y);// may be call o1.getResults(x,y)
改进法:
     TypeB o2=new TypeB("math1");//call 工厂建立TypeA实例
    这种做法作后还是形成了对TypeA的间接依赖。

而使用SimpleContainer简单的方法:
DTO handle(string ServiceName,DTO data);
您就不用关心是哪个对象来完成您的服务要求,可能服务对象有很多个,有很多种类型,还可能分布在千里之外的另一台机器上。

那么,如何将一些常用的服务通过QPG平台集成起来呢?下面以email sender作为例子讲一下。为了简洁。我去掉了实际发送邮件的具体代码。

首先,为了让容器可以自动启动服务,我们需要实现IService和IStartable(Castle提供)接口:
using Castle.Model;
    
using QPG.Interface;
    
using QPG.Utility;
    
using QPG;
    
    
public class EmailSender : IService,IStartable{
}

IService 只要实现ServiceName属性和handle方法
IStartable只要实现Start和Stop方法,平台容器会自动调用它们,不用您老操心的了:-)
运作原理如下:
1) 服务者要从容器里获得消息队列实例;
2) 设置一个定时器定时从队列里取回自己要处理的请求并进行处理;
3) 为了及时响应,应该在启动时成为队列收到请求的处理监听者,这样才能收到消息。
具体代码如下:
public class EmailSender : IService,IStartable {
        
private bool _Started = false;
        
private bool _Stopped = false;


        
private System.Collections.Queue _queue =  System.Collections.Queue.Synchronized(new Queue());
        
        
private string _serviceName="qpg.email_sender";
        
private BroadCastEventWrapper wrapper=null;
        
private System.Timers.Timer _timer;
        
private IMessageQueue _mq;
        
        
public EmailSender() {
            _mq
=SimpleContainer.MessageQueue;
            
            _timer
=new System.Timers.Timer(1000);
            _timer.Elapsed
+=new System.Timers.ElapsedEventHandler(timer_Elapsed);

        }

        
        
public void attach(BroadCastEventHandler func) {
            
if(wrapper==null){
                wrapper
=new BroadCastEventWrapper();
                wrapper.OnLocalBroadCast 
+= new BroadCastEventHandler(func);
                _mq.OnBroadCast
+=new BroadCastEventHandler(wrapper.BroadCasting);
            }

        }


        
        
public void detach() {
            _mq.OnBroadCast
-=new BroadCastEventHandler(wrapper.BroadCasting);
            
        }

        
        
        
public string ServiceName {
            
get{return _serviceName;}
        }


        
public virtual void Start() {
            
if(_Started==truereturn;
            SimpleContainer.SysLogger.DEBUG(
"email_sender Started");
            _timer.Enabled
=true;
            _Started
=true;
            attach(
new QPG.Interface.BroadCastEventHandler(handle));
        }


        
public virtual void Stop() {
            SimpleContainer.SysLogger.DEBUG(
"email_sender Stopped");
            _Stopped 
=  true;
            _timer.Enabled
=false;
            detach();
        }

        
public virtual DTO handle(DTO data) {
            _queue.Enqueue(data);
            DTO rt
=new DTO(data);
            rt.setOutputData(
new Parameter[]{new Parameter("Msg","Put msg to queue-->"+data.RequestArgs[0].Value.ToString())},null);
            
return rt;
        }

        
protected virtual bool send(ParametersHelper ph) {
            
bool rt=true;
            
try{
                
// real sent by SMTP
            }

            
catch{rt=false;}
            
return rt;
        }


        
private void getRequest() {
            DTO d
=_mq.receieveRequestFromQueue(ServiceName);
            
if(d!=null{
                d
=handle(d);// 在这里没有多大意义,不用处理什么,只是返回一个通知,不让客户端等待
                _mq.sendResultToQueue(d.TransactionID,d);
            }

        }


        
protected  void run() {
            getRequest();    
            
if(_queue.Count<1return;
            DTO data
=(DTO)_queue.Dequeue();
            
            ParametersHelper ph
=new ParametersHelper(data.RequestArgs);
            SimpleContainer.SysLogger.DEBUG(ph.ToString());
            
if(send(ph)) SimpleContainer.SysLogger.DEBUG("OK!");
            
else SimpleContainer.SysLogger.DEBUG("FAIL!");
            
        }


        
        
public virtual void handle(QPG.Utility.NotifyArgs arg) {
            
if(arg.RequestServiceName!=ServiceName) return;
            run();
            }
    
        
    

        
public virtual bool Started {
            
get return _Started; }
        }


        
public virtual bool Stopped {
            
get {
                
                
return _Stopped; 
            }

        }


        
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
            run();

        }

    }

今后您要做的是不断稳定现有的服务,增加新的服务。您会发现开发将会是一种享受了。。。。

posted @ 2005-10-09 11:59  成为-行动-拥有(BeDoHave)  阅读(1452)  评论(0编辑  收藏  举报