SOA应用中WebService层的离线对接C#实现

宿主应用程序部分:

class Client
 {
  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [STAThread]
  static void Main(string[] args)
  {
   /*服务请求及离线托管请求,已测试完毕*/
   IServiceProvider context = ClientContextManager.Singleton().CreateServiceContext();
   IDelegate service = ClientContextManager.Singleton().CreateDelegate();    
   System.Collections.Specialized.StringDictionary attributes = new System.Collections.Specialized.StringDictionary();;
   InsXMLMessage reqMsg = new InsXMLMessage();
   reqMsg.Code = string.Empty;
   reqMsg.Command = new InsXMLCommand();
   reqMsg.Command.Name = "设备台帐同步服务";
   reqMsg.Command.Version = InsMessage.PrepareVersion(System.DateTime.Now);
   reqMsg.Command.Data = string.Empty;
   reqMsg.Sender = "INS_APP_0001";
   reqMsg.Time = System.DateTime.Now; 
   string debug = reqMsg.ToString();
   object result = service.Invoke("设备台帐同步服务代理",reqMsg.ToString());
   if(result != null)
   {
    InsXMLMessage retMsg = new InsXMLMessage((string)result);
    //调试输出
    Console.WriteLine(Enum.GetName(typeof(InsMessageState),retMsg.State));
    Console.WriteLine(Enum.GetName(typeof(InsMessageType),retMsg.Type));
    Console.WriteLine(retMsg.Code);
    Console.WriteLine(retMsg.Sender);
    Console.WriteLine(retMsg.Time.ToString());
    Console.WriteLine(retMsg.Command.Name);
    Console.WriteLine(retMsg.Command.Version);
    Console.WriteLine(retMsg.Command.Data);     
    if(retMsg.State == InsMessageState.Succeed)
    {
     //将返回的消息委派到对应操作
     retMsg.Type = InsMessageType.Synchronize;
     ContinueAt(retMsg);
    }
    else if(retMsg.State == InsMessageState.NetworkError)
    {
     //将发生网络故障的请求分派给请求管理器接管
     ServiceRequestManager.Singleton().TakeOver("设备台帐同步服务代理",retMsg,new ServiceRequestContinueAt(ContinueAt));
    }
   }    
   Console.Read();  
   /*
    * 服务初始化及运行实例代码,已测试完毕
   ServiceRequestManager.Singleton().Initialize();
   ServiceRequestManager.Singleton().SubmitAllSuspend();
   Console.Read();  
   */
  }
  /// <summary>
  /// 服务请求返回后续操作
  /// </summary>
  /// <param name="retMsg"></param>
  public static void ContinueAt(InsXMLMessage retMsg)
  {
   Console.WriteLine("ContinueAt called.");
   IOperation operation = OperationContextManager.Singleton().CreateOperation();
   //operation.Invoke("设备台帐同步本地操作",retMsg);
  }

离线请求管理器部分:

/// <summary>
 /// 服务请求恢复后的入口委托
 /// </summary>
 public delegate void ServiceRequestContinueAt(InsXMLMessage retMsg);
 /// <summary>
 /// 服务请求管理器
 /// </summary>
 public class ServiceRequestManager
 {
  /// <summary>
  /// 服务容器
  /// </summary>
  protected IServiceProvider _context;
  /// <summary>
  /// 本地代理
  /// </summary>
  protected IDelegate _service; 
  /// <summary>
  /// 持久服务
  /// </summary>
  protected IPersistenceService _persistence;
  /// <summary>
  /// 等待间隔
  /// </summary>
  protected long _ticks;
  private ServiceRequestManager()
  {
   _cache = Hashtable.Synchronized(new Hashtable());
   _context = ClientContextManager.Singleton().CreateServiceContext();
   _service = ClientContextManager.Singleton().CreateDelegate(); 
   _persistence = (IPersistenceService)_context.GetService(typeof(IPersistenceService)); 
   _ticks = 60 * 10000000;
  }
  protected static ServiceRequestManager _instance;
  /// <summary>
  /// 缓存
  /// </summary>
  protected static Hashtable _cache;
  /// <summary>
  /// 单件
  /// </summary>
  /// <returns></returns>
  public static ServiceRequestManager Singleton()
  {
   if(_instance == null)_instance = new ServiceRequestManager();
   return _instance;
  }  
  /// <summary>
  /// 加入缓存
  /// </summary>
  /// <param name="guid"></param>
  /// <param name="request"></param>
  protected void Add(System.Guid guid,ServiceRequest request)
  {
   _cache[guid] = request;
  }  
  /// <summary>
  /// 从缓存中获取
  /// </summary>
  /// <param name="guid"></param>
  /// <returns></returns>
  protected ServiceRequest Get(System.Guid guid)
  {
   object request = _cache[guid];   
   return request == null?null:request as ServiceRequest;
  } 
  /// <summary>
  /// 从缓存中移除
  /// </summary>
  /// <param name="guid"></param>
  protected void Remove(System.Guid guid)
  {   
   //从内存移除
   _cache.Remove(guid);
   //从存储移除
   IServiceProvider context = ClientContextManager.Singleton().CreateServiceContext();
   IPersistenceService persistence = (IPersistenceService)context.GetService(typeof(IPersistenceService)); 
   persistence.Remove(guid);  
  }
  /// <summary>
  /// 接管失败的请求
  /// </summary>
  /// <param name="target"></param>
  /// <param name="msg"></param>
  /// <param name="continueAt"></param>
  public void TakeOver(string target,InsXMLMessage msg,ServiceRequestContinueAt continueAt)
  {
   //委托可见性校验
   if(!continueAt.Method.IsPublic)throw new ArgumentException("委托指向的方法访问范围必须是public");
   //立即序列化,并加入缓存副本
   IServiceProvider context = ClientContextManager.Singleton().CreateServiceContext();
   IPersistenceService persistence = (IPersistenceService)context.GetService(typeof(IPersistenceService));  
   ServiceRequest request = new ServiceRequest(target,msg,continueAt);
   string xml = SerializeRequest(request); 
   System.Guid instance = persistence.Passivate(xml);
   Add(instance,request);
  }
  /// <summary>
  /// 提交所有接管的请求,由定时时钟触发
  /// </summary>
  public void SubmitAllSuspend()
  {
   IServiceProvider context = ClientContextManager.Singleton().CreateServiceContext();
   IDelegate service = ClientContextManager.Singleton().CreateDelegate(); 
   //创建副本,在遍历过程中移除缓存中请求成功的项目
   Hashtable copy = new Hashtable(_cache);
   foreach(object key in copy.Keys)
   {
    ServiceRequest request = Get(new Guid(key.ToString())) as ServiceRequest;
    InsXMLMessage reqMsg = request.Message;
    object result = service.Invoke(request.Service,reqMsg.ToString());
    if(result != null)
    {
     InsXMLMessage retMsg = new InsXMLMessage((string)result);
     if(retMsg.State == InsMessageState.Succeed)
     {
      //将返回的消息转嫁到注册的委托
      if(request.ContinueAtMethod.IsStatic)
      {
       request.ContinueAtMethod.Invoke(null,new object[]{retMsg});
      }
      else
      {
       object instance = request.ContinueAtMethod.DeclaringType.Assembly.CreateInstance(request.ContinueAtMethod.DeclaringType.FullName);
       request.ContinueAtMethod.Invoke(instance,new object[]{retMsg});
      }
      //移除接管
      Remove(new Guid(key.ToString()));
     }     
    }   
    //挂起1分钟以等待上一操作完成
    System.Threading.Thread.CurrentThread.Join(new TimeSpan(_ticks));   
   }
  }
  /// <summary>
  /// 初始化,在应用程序启动时调用
  /// </summary>
  public void Initialize()
  {
   //将所有序列化的请求载入内存
   IServiceProvider context = ClientContextManager.Singleton().CreateServiceContext();
   IPersistenceService persistence = (IPersistenceService)context.GetService(typeof(IPersistenceService)); 
   System.Guid[] requests = persistence.Possess();
   foreach(Guid guid in requests)
   {
    ServiceRequest request = RetrieveRequest(persistence.Activating(guid));
    Add(guid,request);
   }
  }
  /// <summary>
  /// 序列化
  /// </summary>
  /// <param name="request"></param>
  /// <returns></returns>
  protected string SerializeRequest(ServiceRequest request)
  {
   System.Xml.XmlDataDocument doc = new XmlDataDocument();
   XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0","utf-8",string.Empty);
   doc.AppendChild(declaration);
   XmlNode serviceRequest = doc.CreateNode(XmlNodeType.Element,"ServiceRequest",string.Empty);
   XmlAttribute service = doc.CreateAttribute("service");  
   service.Value = request.Service;
   XmlAttribute date = doc.CreateAttribute("date");  
   date.Value = System.DateTime.Now.ToLongDateString();
   XmlAttribute time = doc.CreateAttribute("time");  
   time.Value = System.DateTime.Now.ToLongTimeString();
   serviceRequest.Attributes.Append(service);
   serviceRequest.Attributes.Append(date);
   serviceRequest.Attributes.Append(time);

   XmlNode insMsg = doc.CreateNode(XmlNodeType.CDATA,"InsMessage",string.Empty);
   insMsg.Value = request.Message.ToString();
   serviceRequest.AppendChild(insMsg); 
   
   XmlNode continueAt = doc.CreateNode(XmlNodeType.Element,"ContinueAt",string.Empty);
   XmlAttribute type = doc.CreateAttribute("type");    
   type.Value = request.ContinueAt.Method.DeclaringType.AssemblyQualifiedName;
   continueAt.Attributes.Append(type);
   XmlAttribute method = doc.CreateAttribute("method");
   method.Value = request.ContinueAt.Method.Name;
   continueAt.Attributes.Append(method);
   serviceRequest.AppendChild(continueAt); 

   doc.AppendChild(serviceRequest);   
   return doc.InnerXml;
  } 
  /// <summary>
  /// 反序列化
  /// </summary>
  /// <param name="xml"></param>
  /// <returns></returns>
  protected ServiceRequest RetrieveRequest(string xml)
  {
   System.Xml.XmlDataDocument doc = new System.Xml.XmlDataDocument();
   doc.LoadXml(xml);
   string service = doc.DocumentElement.Attributes["service"].Value;
   string msg = doc.DocumentElement.InnerText;
   string continueAtType = doc.DocumentElement.SelectSingleNode("ContinueAt").Attributes["type"].Value;
   string continueAtMethod = doc.DocumentElement.SelectSingleNode("ContinueAt").Attributes["method"].Value;
   MethodInfo methodInfo = Type.GetType(continueAtType).GetMethod(continueAtMethod);
   return new ServiceRequest(service,new InsXMLMessage(msg),methodInfo);
  }
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值