2012-09-25 43 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