SOA應用中WebService層的離線對接C#實現

來源:互聯網
上載者:User

宿主應用程式部分:

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);
  }
 }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.