2016-01-12 31 views
1

我对Scala,Play框架和Akka都很陌生。在我目前正在开发的项目中,Web应用程序的用户应该能够以异步的方式向服务器请求几件事情(如开始特定的计算)。如果服务器完成,它应该通知用户也是异步的。我解决了其上建立的WebSocket连接这方面的需求,当用户第一次使用应用程序连接和WebSocket的由UserActor,其连接到用户会话处理:玩家框架用户演员与用户会话

def ws = WebSocket.tryAcceptWithActor[JsValue, JsValue] { implicit request => 

    Future.successful(request.session.get(UID) match { 
     case None => Left(Forbidden) 
     case Some(uid) => Logger.info("WebSocket has accepted the request with uid " + uid) 
          Right(UserActor.props(uid)) 
    }) 
} 

目前,唯一的事情UserActor确实接收来自WebSocket的消息,如JsValue

def index = Action { implicit request => { 
    val uid = request.session.get(UID).getOrElse { 
     counter += 1 
     counter.toString 
    } 
    Ok(views.html.index(uid)).withSession { 
     Logger.debug("create uid " + uid) 
     request.session + (UID -> uid) 
    }} 
} 

UserActor所述应该表示在服务器上的实际用户,从而包括所有的动作的用户可以在服务器上执行的逻辑:请求索引时生成会话的UID。只要我通过WebSocket发送所有用户交互,此工作正常。

现在情况如何与其他用户输入,如表单提交?该应用程序包含一个表单,其数据不应超过WebSocket,而应提交POST请求(可能带有AJAX)并将其绑定到控制器中,如文档中所述。

def saveContact = Action { implicit request => 
    contactForm.bindFromRequest.fold(
    formWithErrors => { 
     BadRequest(views.html.contact.form(formWithErrors)) 
    }, 
    contact => { 
     val contactId = Contact.save(contact) 
     Redirect(routes.Application.showContact(contactId)).flashing("success" -> "Contact saved!") 
    } 
) 
} 

本示例摘自Playframework documentation

现在,我如何链接表单提交处理程序与UserActor?假设我想告诉用户演员表格已经提交。一个简单的例子是,UserActor只要收到一个表格,就会通过WebSocket向客户端发送一个表单值。所以基本上这个问题归结为我想发送来自ControllerUserActor消息的问题。

我可能想出了通过WebSocket发送所有表单数据的想法,但我也希望在将来实现大数据的上传,我想要像解释in this blog post所述那样处理。然后,我可以想象的一个场景是UserActor应该收到它接收的每个块的消息。

我想一个问题是,UserActorWebSocketActor是相同的,我宁愿要拆他们的逻辑,使得UserActor只与会议相关的,但我不知道如何做到这一点。也许我需要另一个演员,说一个UserManager,跟踪目前UserActors,并允许访问UserActors

您是否有任何建议,建议或示例应用程序也处理这种情况?非常感谢你提前。

问候

回答

0

不要使用您传递给tryAcceptWithActorUser的代表演员。它应该代表与该用户的特定会话。可能地,用户可能在特定时间打开的许多并发会话(多个浏览器或标签)之一。

创建一个单独的actor来表示用户及其可以执行的所有操作。现在会话演员应该将他们的消息转发给用户演员。传统的控制器方法也可以将请求转发给相应的用户参与者。