2012-09-25 118 views
1

我正在爲我的僱主構建一個小工具,並試圖使用Akka 2 + Scala來實現它。使用Akka處理SOAP消息

一個我與接口的系統都有AA SOAP API,它有一個有趣的實現:

----請求-------

客戶----請求---->服務器

客戶< ---請求確認-----服務器

---- ------響應

客戶< ---響應----服務器

客戶---- RESP確認---->服務器

請求保持跟蹤通過由REQ-ACK發送任務ID來完成。

我的問題是給SO社會,誰擁有與阿卡如下:

  • 什麼是用阿卡對於這種特殊情況來處理HTTP消息的理想方式?我看過一些Akka-Mist的例子,看起來它已經停止使用了play-mini,然後還有akka-camel,我似乎無法找到該庫作爲akka 2.0.3的一部分。發佈,所以我有點困惑,應該採取什麼方法。有沒有推薦的方法來封裝akka actor中的servlet行爲?

謝謝大家提前。

+0

您沒有指定應用程序是客戶端還是服務器。 –

+0

該應用程序是一個客戶端,但也必須有一個uri端點來接收響應。 – cudiaco

回答

2

你提的問題是非常開放式的,所以我也會對你要求一些假設。

請求假設:有很多在一些事件產生的請求。

創建具有路由器行爲者包裹異步-HTTP客戶端(https://github.com/sonatype/async-http-client)。一旦async-http-client完成一個請求,它就會發送一個消息,其中包含在Req Ack中的ID給一個協調角色。協調者會聚合ID。

以下是主要的僞代碼,但它足夠接近真正的API,你應該能夠找出遺漏的部分。

case class Request(url:String) 
case class IDReceived(id:String) 

case class RequestingActor extends Actor { 

    override def receive = { 
     case Request(url) => { 
      //set up the async client and run the request 
      //since it's async the client will not block and this actor can continue making generating more requests 
     } 
    } 
} 


class AsyncHttpClientResponseHandler(aggregationActor:ActorRef) extends SomeAsyncClientHandler { 

    //Override the necessary Handler methods. 

    override def onComplete = { 
     aggregationActor ! IDReceived(//get the id from the response) 
    } 
} 

class SomeEventHandlerClass { 

    val requestRouter = actorSystem.actorOf(Props[RequestingActor].withRouter(FromConfig(//maybe you've configured a round-robin router)), requestRouterName) 

    def onEvent(url:String) { 
     requestRouter ! Request(url) 
    } 

} 

case class AggregationActor extends Actor { 

    val idStorage = //some form of storage, maybe a Map if other information about the task ID needs to be stored as well. Map(id -> other information) 

    override def receive = { 
     case IDReceived(id) => //add the ID to idStorage 
    } 
} 

響應假設:你需要做的與包含在響應中的數據的東西,然後標記ID爲完成。 HTTP前端只需處理這一組消息。

,而不是試圖找到阿卡集成框架只用一個簡單的HTTP前端,將消息發送到你所創建的阿卡網絡。我無法想象通過使用play-mini獲得的任何優勢,我認爲它會掩蓋一些劃分工作分離和控制的界限。情況並非總是如此,但考慮到您的問題缺乏要求,我無法根據我的意見做出任何決定。

case class ResponseHandlingActor extends Actor { 

    val aggregationActor = actorSystem.actorFor(//the name of the aggregation router within the Actor System) 

    override def receive = { 
     case Response(data) => { 
      //do something with the data. If the data manipulation is blocking or long running it may warrant its own network of actors. 
      aggregationActor ! ResponseReceived(//get the id from the response) 
     } 
    } 
} 

class ScalatraFrontEnd() extends ScalatraServlet { 

    val responseRouter = actorSystem.actorOf(Props[RequestingActor].withRouter(FromConfig(//maybe you've configured a round-robin router)), requestRouterName) 

    post("/response") { 
     responseRouter ! Response(//data from the response) 
    } 

} 

創建一個類似的系統使您的關注漂亮的分離,使得它可以很容易推理哪裏處理髮生和足夠的空間用於縮放系統或擴展它。

+0

這實際上正是我正在尋找的。謝謝! – cudiaco